1. 程式人生 > >中值濾波器c++實現

中值濾波器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)。

原理其實不難,主要是如何將其變為現實。看似簡單的一個問題實際上也踩了不少坑,因此加油吧,少年!