中值濾波器c++實現
阿新 • • 發佈:2018-12-12
中值濾波器呢,我就不用過多介紹了,其實是很簡單的,就是對像選取窗口裡的畫素值排序後取中值,可有效的抑制椒鹽噪音。之前一直都是呼叫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)。
原理其實不難,主要是如何將其變為現實。看似簡單的一個問題實際上也踩了不少坑,因此加油吧,少年!