自定义中值滤波

#include<opencv2\imgproc\imgproc.hpp>
#include<opencv2\highgui\highgui.hpp>

using namespace std;
using namespace cv;

uchar sort(uchar n1, uchar n2, uchar n3, uchar n4, uchar n5, uchar n6, uchar n7, uchar n8, uchar n9)
{
	uchar arr[9];
	arr[0] = n1;
	arr[1] = n2;
	arr[2] = n3;
	arr[3] = n4;
	arr[4] = n5;
	arr[5] = n6;
	arr[6] = n7;
	arr[7] = n8;
	arr[8] = n9;
	//希尔排序,缩减增量
	for (int div = 9 / 2; div >= 1; div = div / 2)//定增量div,并不断减小
	{
		for (int i = 0; i<div; ++i)//分组成div组
		{
			for (int j = i; j<9 - div; j += div)//对每组进行插入排序
				for (int k = j; k<9; k += div)
					if (arr[j]>arr[k])
						swap(arr[j], arr[k]);//交换两个数的值
		}
	}
	return arr[4];
			
}
void salt(Mat &src, int n)
{
	if (!src.data) return;
	for (int k = 0; k < n; k++)
	{
		int i = rand() % src.rows;
		int j = rand() % src.cols;
		if (src.channels() == 1)
		{
			src.at<uchar>(i, j) = 255;
		}
		else if (src.channels() == 3)
		{
			src.at<Vec3b>(i, j) = 255;
		}
	}
}

void myMedian(const Mat src, Mat &dst)
{
	if (!src.data) return;
	Mat _dst(src.size(), src.type());
	for(int i=0;i<src.rows;++i)
		for (int j = 0; j < src.cols; ++j)
		{
			if ((i - 1) >= 0 && (j - 1) >= 0 && (i + 1)<src.rows && (j + 1) < src.cols)
			{
				_dst.at<Vec3b>(i, j)[0] = sort(src.at<Vec3b>(i, j)[0], src.at<Vec3b>(i + 1, j + 1)[0],
					src.at<Vec3b>(i + 1, j)[0], src.at<Vec3b>(i, j + 1)[0], src.at<Vec3b>(i + 1, j - 1)[0],
					src.at<Vec3b>(i - 1, j + 1)[0], src.at<Vec3b>(i - 1, j)[0], src.at<Vec3b>(i, j - 1)[0],
					src.at<Vec3b>(i - 1, j - 1)[0]);
				_dst.at<Vec3b>(i, j)[1] = sort(src.at<Vec3b>(i, j)[1], src.at<Vec3b>(i + 1, j + 1)[1],
					src.at<Vec3b>(i + 1, j)[1], src.at<Vec3b>(i, j + 1)[1], src.at<Vec3b>(i + 1, j - 1)[1],
					src.at<Vec3b>(i - 1, j + 1)[1], src.at<Vec3b>(i - 1, j)[1], src.at<Vec3b>(i, j - 1)[1],
					src.at<Vec3b>(i - 1, j - 1)[1]);
				_dst.at<Vec3b>(i, j)[2] = sort(src.at<Vec3b>(i, j)[2], src.at<Vec3b>(i + 1, j + 1)[2],
					src.at<Vec3b>(i + 1, j)[2], src.at<Vec3b>(i, j + 1)[2], src.at<Vec3b>(i + 1, j - 1)[2],
					src.at<Vec3b>(i - 1, j + 1)[2], src.at<Vec3b>(i - 1, j)[2], src.at<Vec3b>(i, j - 1)[2],
					src.at<Vec3b>(i - 1, j - 1)[2]);

			}
		}
	_dst.copyTo(dst);
}
void main()
{
	Mat image = imread("D:/2015project/medianlvbo/1.jpg");
	Mat salt_image;
	image.copyTo(salt_image);
	salt(salt_image, 3000);

	Mat image1, image2;
	myMedian(salt_image, image1);
	medianBlur(salt_image, image2, 3);
	imshow("原图", image);
	imshow("椒盐化", salt_image);
	imshow("自定义中值滤波", image1);
	imshow("opencv自带中值滤波", image2);
	waitKey(0);

}

 

 

 中值滤波能有效抑制椒盐噪声

猜你喜欢

转载自blog.csdn.net/sinat_38998284/article/details/82291177