中值滤波器c++实现

中值滤波器呢,我就不用过多介绍了,其实是很简单的,就是对像选取窗口里的像素值排序后取中值,可有效的抑制椒盐噪音。之前一直都是调用OpenCV的 库函数,今天想着练一下c++代码的基本功就尝试了下,按照自己的思路,最终也是实现了,效果还可以。不废话了,直接贴代码:

#include<iostream>
#include<opencv2/opencv.hpp>
#include <vector>
#include<functional>
using namespace std;
using  namespace cv;

/* 中值滤波器实现 */
void MedianFlitering(Mat &src, Mat &dst, int k)
{
	Mat im,m1, m2, m3, m4, m5, m6, B, G, R;
	vector <Mat> channels;
	split(src, channels);
	B = channels.at(0);
	G = channels.at(1);
	R = channels.at(2);//通道分离
	int a = src.rows;
	int b = src.cols; //获得行和列
	for (int i = k/2; i < a - k/2; i++)//遍历图像,注意要把边框部分去除了
	{
		for (int j = k/2; j < b - k/2; j++)
		{
			m1 = B(Rect(j - k/2, i - k/2, k, k)).clone();//选取k*k窗口中的B通道
			m2 = G(Rect(j - k / 2, i - k / 2, k, k)).clone();//选取k*k窗口G通道
			m3 = R(Rect(j - k / 2, i - k / 2, k, k)).clone();//选取k*k窗口R通道
			m1 = m1.reshape(1, 1);
			m2 = m2.reshape(1, 1);
			m3 = m3.reshape(1, 1); //像素值将其变为一行
			cv::sort(m1, m4, 0);
			cv::sort(m2, m5, 0);
			cv::sort(m3, m6, 0);//对其排序
			int p0 = m4.at<uchar>(0, k*k/2+1);
			int p1 = m5.at<uchar>(0, k*k / 2 + 1);
			int p2 = m6.at<uchar>(0, k*k / 2 + 1);//选取各通道的像素中值点
			dst.at<Vec3b>(i - k/2, j - k/2)[0] = p0;
			dst.at<Vec3b>(i - k/2, j - k/2) [1]= p1;
			dst.at<Vec3b>(i - k/2, j - k/2) [2]= p2;//对其进行重赋值
		}
	}
	imshow("Annie", dst);
	waitKey(0);
}
int main()
{
	Mat img, im1,im2;
	img = imread("c:\\users\\xa\\desktop\\img.jpg");
	//cvtColor(img, gray, COLOR_RGB2GRAY);//转为灰度图
	imshow("原始图像", img);
	waitKey(0);
	medianBlur(img, im1, 5);
	imshow("opencv中值滤波", im1);
	waitKey(0);
	im2 = img.clone();
	MedianFlitering(img, im2,5);
}

加了噪音的原始图像:

opencv滤波后的图像(5*5):

自己实现的中值滤波后效果图(5*5)。

原理其实不难,主要是如何将其变为现实。看似简单的一个问题实际上也踩了不少坑,因此加油吧,少年!

猜你喜欢

转载自blog.csdn.net/zzzzjh/article/details/82870435
今日推荐