图像处理代码编写二:基于C++的中值滤波代码编写

中值滤波原理及应用

中值滤波器是统计排序滤波器的一种,是一种非线性空间滤波器。中值滤波器是通过其像素邻域内像素排序为基础,然后用这些像素排序后的中值作为该像素点新的像素值,若邻域中有一些像素值相同时,所有相等的值都可作为中值。假如3×3邻域有一系列像素值(12,54,66,5,10,20,70,20,18),排序后为(5,10,12,18,20,20,54,66,70),那么中值就是20。
中值滤波器最有效的就是处理椒盐噪声的能力,但是不适合处理点和线太多的图像。

代码如下:

#include <opencv2/opencv.hpp>
#include<iostream>
using namespace cv;
using namespace std;
void select_sort(vector<uchar>&arr)//选择排序
{
	
	for (int i = 0; i < arr.size(); i++)
	{
		int k = i;
		for (int j = i + 1; j < arr.size(); j++)
		{
			if (arr[k] > arr[j])
			{
				k = j;
			}
		}
		if (k != i)
		{
			swap(arr[k], arr[i]);
		}
	}
}
void mymedianblur(const Mat&src, Mat&dst, Size ksize)//中值滤波
{
	//若模板不是奇数模板,则报错退出
	if (ksize.width % 2 == 0 || ksize.height % 2 == 0)
	{
		cout << "please input odd ksize!" << endl;
		exit(-1);
	}
	//根据ksize大小扩充模板边界
	int awidth = (ksize.width - 1) / 2;
	int aheight = (ksize.height - 1) / 2;
	Mat asrc;
	copyMakeBorder(src, asrc, aheight, aheight, awidth, awidth, BORDER_DEFAULT);
	//根据图像通道数遍历图像求均值
	//通道数为1
	if (src.channels() == 1)
	{
		for (int i = aheight; i < src.rows + aheight; i++)
		{
			for (int j = awidth; j < src.cols + awidth; j++)
			{
				vector<uchar> arr;
				for (int k = i - aheight; k <= i + aheight; k++)
				{
					for (int l = j - awidth; l <= j + awidth; l++)
					{
						arr.push_back(asrc.at<uchar>(k, l));
					}
				}
				select_sort(arr);//选择排序
				dst.at<uchar>(i - aheight, j - awidth)= arr[(ksize.area() - 1) / 2];//将中值映射到输出图像
			}
		}
	}
	//通道数为3	

	if (src.channels() == 3)
	{
		for (int i = aheight; i < src.rows + aheight; i++)
		{
			for (int j = awidth; j < src.cols + awidth; j++)
			{
				vector<vector<uchar>> arr(3);
				for (int k = i - aheight; k <= i + aheight; k++)
				{
					for (int l = j - awidth; l <= j + awidth; l++)
					{
						arr[0].push_back(asrc.at<Vec3b>(k, l)[0]);
						arr[1].push_back(asrc.at<Vec3b>(k, l)[1]);
						arr[2].push_back(asrc.at<Vec3b>(k, l)[2]);
					}
				}
				for (int m = 0; m < 3; m++)
				{
					select_sort(arr[m]);//选择排序
					dst.at<Vec3b>(i - aheight, j - awidth)[m] = arr[m][(ksize.area() - 1) / 2];//将中值映射到输出图像
				}
			}
		}
	}
}
int main()
{
	Mat src = imread("C:/Users/msi-/Desktop/picture/20190130005650499.png",0);
	Mat dst;
	dst = Mat::zeros(src.size(), src.type());
	imshow("椒盐图片", src);
	mymedianblur(src, dst, Size(5, 5));
	imshow("滤波处理后的椒盐图片", dst);
	waitKey(0);
	return 0;
}

初始图片:
在这里插入图片描述
滤波后图片:
在这里插入图片描述

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
我很抱歉,作为一名语言模型,我无法为您编写代码。但是,我可以提供一些关于彩色图像中值滤波的常见方法,希望对您有所帮助。 彩色图像中值滤波通常用于去除噪点和平滑图像。它基于对图像像素进行排序并将中间(即中值)像素替换为每个像素的现有值。 具体而言,可以按以下方式执行彩色图像中值滤波: 1. 将输入彩色图像转换为三个分量(例如RGB),并对每个分量分别执行中值滤波。 2. 针对每个分量,可以使用各种排序算法(例如插入排序或快速排序),并将中值像素替换为每个像素的现有值。 下面是一些非常基本的C语言代码,可能需要根据您的具体需求进行修改: ```C #include <stdio.h> #include <stdlib.h> #define WINDOWS_SIZE 3 void swapPixel(unsigned char* a, unsigned char* b) { unsigned char temp[3]; temp[0] = *a; temp[1] = *(a + 1); temp[2] = *(a + 2); *a = *b; *(a + 1) = *(b + 1); *(a + 2) = *(b + 2); *b = temp[0]; *(b + 1) = temp[1]; *(b + 2) = temp[2]; } void sortPixels(unsigned char* pixels[], int pixelsCount) { int sorted; do { sorted = 1; for (int i = 0; i < pixelsCount - 1; ++i) { int pixel1 = pixels[i][0] + pixels[i][1] + pixels[i][2]; int pixel2 = pixels[i + 1][0] + pixels[i + 1][1] + pixels[i + 1][2]; if (pixel1 > pixel2) { sorted = 0; swapPixel(&pixels[i][0], &pixels[i + 1][0]); } } } while (!sorted); } void medianFilter(unsigned char* image, unsigned char* result, int width, int height) { for (int i = 1; i < height - 1; ++i) { for (int j = 1; j < width - 1; ++j) { unsigned char* pixels[WINDOWS_SIZE]; int pixelsCount = 0; for (int k = -1; k < 2; ++k) { for (int l = -1; l < 2; ++l) { pixels[pixelsCount++] = &image[((i + k) * width + j + l) * 3]; } } sortPixels(pixels, pixelsCount); result[(i * width + j) * 3] = pixels[4][0]; result[(i * width + j) * 3 + 1] = pixels[4][1]; result[(i * width + j) * 3 + 2] = pixels[4][2]; } } } int main(int argc, char* argv[]) { if (argc < 2) { printf("Usage: %s input_file\n", argv[0]); return 1; } FILE* input = fopen(argv[1], "rb"); if (!input) { printf("Unable to open %s for reading\n", argv[1]); return 2; } fseek(input, 0, SEEK_END); long fileSize = ftell(input); fseek(input, 0, SEEK_SET); unsigned char* imageData = (unsigned char*)malloc(fileSize); fread(imageData, fileSize, 1, input); fclose(input); int width = *(int*)&imageData[18]; int height = *(int*)&imageData[22]; unsigned char* result = (unsigned char*)malloc(fileSize); memcpy(result, imageData, fileSize); medianFilter(imageData, result, width, height); FILE* output = fopen("result.bmp", "wb"); fwrite(result, fileSize, 1, output); fclose(output); free(imageData); free(result); return 0; } ``` 这段代码读取输入文件中的彩色图像(以BMP格式为例),并将其复制到输出文件中进行中值滤波处理。请注意,它只对Windows大小为3的中心像素进行排序,然后将中值像素用于替换中心像素。 如果您需要更大或更小的窗口,请相应地更改辅助像素列表的大小。此外,您可能还需要根据您的需要来调整内存分配和指针操作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值