日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

自适应中值滤波及实现

發布時間:2025/3/21 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 自适应中值滤波及实现 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前言

無意中看到了一篇比較老的論文,Adaptive median filters: new algorithms and results。感興趣的可以下載下來看看。主要就是提出了一種自適應中值濾波算法,這個算法是很經典的中值濾波算法的改進版本,自動選擇濾波器的大小,以追求更好的效果。原理十分簡單,后面都盡量簡短地進行說明。

中值濾波器(Median Filter)

中值濾波的思想就是比較一定領域內的像素值的大小,取出其中值作為這個領域的中心像素新的值。假設對一定領域內的所有像素從小到大進行排序,如果存在孤立的噪聲點,比如椒鹽噪聲(椒噪聲——較小的灰度值,呈現的效果是小黑點;鹽噪聲——較大的灰度值,呈現的效果是小白點),那么從小到大排序的這個數組中,那些孤立的噪聲一定會分布在兩邊(要么很小,要么很大),這樣子取出的中值點可以很好地保留像素信息,而濾除了噪聲點的影響。
中值濾波器受濾波窗口大小影響較大,用于消除噪聲和保護圖像細節,兩者會存在沖突。如果窗口較小,則能較好地保護圖像中的一些細節信息,但對噪聲的過濾效果就會打折扣;反之,如果窗口尺寸較大則會有較好的噪聲過濾效果,但也會對圖像造成一定的模糊效果,從而丟失一部分細節信息。另外,如果在濾波窗口內的噪聲點的個數大于整個窗口內像素的個數,則中值濾波就不能很好的過濾掉噪聲。

自適應中值濾波器(Adaptive Median Filter)

在噪聲密度不是很大的情況下(根據經驗,噪聲的出現的概率小于0.2),使用中值濾波的效果不錯。但是當噪聲出現的概率比較高時,原來的中值濾波算法就不是很有效了。只有增大濾波器窗口尺寸,盡管會使圖像變得模糊。
使用自適應中值濾波器的目的就是,根據預設好的條件,動態地改變中值濾波器的窗口尺寸,以同時兼顧去噪聲作用和保護細節的效果。
下面是自適應中值濾波器算法的詳細描述:
預先定義好以下符號:

  • SxySxy:濾波器的作用區域,濾波器窗口所覆蓋的區域,該區域中心點為圖像中第y行第x列個像素點;
  • ZminZminSxySxy中最小的灰度值;
  • ZmaxZmaxSxySxy中最大的灰度值;
  • ZmedZmedSxySxy中所有灰度值的中值;
  • ZxyZxy:表示圖像中第y行第x列個像素點的灰度值;
  • SmaxSmaxSxySxy所允許的最大窗口尺寸;

自適應中值濾波器分為以下兩個過程,AB
A:
1. A1 = ZmedZmed - ZminZmin
2. A2 = ZmedZmed - ZmaxZmax
3. 如果A1>0A1>0A2<0A2<0,則跳轉到B
4. 否則,增大窗口的尺寸
5. 如果增大后的尺寸SmaxSmax,則重復A
6. 否則,直接輸出ZmedZmed
B
1. B1 = ZxyZxy - ZminZmin
2. B2 = ZxyZxy - ZmaxZmax
3. 如果B1>0B1>0B2<0B2<0,則輸出ZxyZxy
4. 否則輸出ZmedZmed

直觀解釋

在自適應中值濾波算法中,A步驟里面會先判斷是否滿足Zmin<Zmed<ZmaxZmin<Zmed<Zmax。這一步驟實質是判斷當前區域的中值點是否是噪聲點,通常來說是滿足Zmin<Zmed<ZmaxZmin<Zmed<Zmax這個條件的,此時中值點不是噪聲點,跳轉到B;考慮一些特殊情況,如果Zmed=ZminZmed=Zmin或者Zmed=ZmaxZmed=Zmax,則認為是噪聲點,應該擴大窗口尺寸,在一個更大的范圍內尋找一個合適的非噪聲點,隨后再跳轉到B,否則輸出的中值點是噪聲點;
接下來考慮跳轉到B之后的情況:判斷中心點的像素值是否是噪聲點,判斷條件為Zmin<Zxy<ZmaxZmin<Zxy<Zmax,原理同上,因為如果Zxy=ZminZxy=Zmin或者Zxy=ZmaxZxy=Zmax,則認為是噪聲點。如果不是噪聲點,我們可以保留當前像素點的灰度值;如果是噪聲點,則使用中值替代原始灰度值,濾去噪聲。

程序實現

程序中定義了產生椒噪聲和鹽噪聲函數,以及中值濾波和自適應中值濾波的函數。
程序很基礎,不做贅述。

#include <stdio.h> #include <opencv2/opencv.hpp> #include <opencv2/highgui/highgui.hpp> #include <opencv2/imgproc/imgproc.hpp>//鹽噪聲 void saltNoise(cv::Mat img, int n) {int x, y;for (int i = 0;i < n / 2;i++){x = std::rand() % img.cols;y = std::rand() % img.rows;if (img.type() == CV_8UC1){img.at<uchar>(y, x) = 255;}else if (img.type() == CV_8UC3){img.at<cv::Vec3b>(y, x)[0] = 255;img.at<cv::Vec3b>(y, x)[1] = 255;img.at<cv::Vec3b>(y, x)[2] = 255;}} }//椒噪聲 void pepperNoise(cv::Mat img, int n) {int x, y;for (int i = 0;i < n / 2;i++){x = std::rand() % img.cols;y = std::rand() % img.rows;if (img.type() == CV_8UC1){img.at<uchar>(y, x) = 0;}else if (img.type() == CV_8UC3){img.at<cv::Vec3b>(y, x)[0] = 0;img.at<cv::Vec3b>(y, x)[1] = 0;img.at<cv::Vec3b>(y, x)[2] = 0;}} }// 中值濾波器 uchar medianFilter(cv::Mat img, int row, int col, int kernelSize) {std::vector<uchar> pixels;for (int y = -kernelSize / 2;y <= kernelSize / 2;y++){for (int x = -kernelSize / 2;x <= kernelSize / 2;x++){pixels.push_back(img.at<uchar>(row + y, col + x));}}sort(pixels.begin(), pixels.end());auto med = pixels[kernelSize*kernelSize / 2];return med; }// 自適應中值濾波器 uchar adaptiveMedianFilter(cv::Mat &img, int row, int col, int kernelSize, int maxSize) {std::vector<uchar> pixels;for (int y = -kernelSize / 2;y <= kernelSize / 2;y++){for (int x = -kernelSize / 2;x <= kernelSize / 2;x++){pixels.push_back(img.at<uchar>(row + y, col + x));}}sort(pixels.begin(), pixels.end());auto min = pixels[0];auto max = pixels[kernelSize*kernelSize - 1];auto med = pixels[kernelSize*kernelSize / 2];auto zxy = img.at<uchar>(row, col);if (med > min && med < max){// to Bif (zxy > min && zxy < max)return zxy;elsereturn med;}else{kernelSize += 2;if (kernelSize <= maxSize)return adaptiveMedianFilter(img, row, col, kernelSize, maxSize);// 增大窗口尺寸,繼續A過程。elsereturn med;} }int main() {int minSize = 3;int maxSize = 7;cv::Mat img;img = cv::imread("lena.bmp");cv::cvtColor(img, img, cv::COLOR_BGR2GRAY);cv::imshow("src", img);saltNoise(img, 40000);pepperNoise(img, 40000);cv::imshow("noise", img);cv::Mat temp = img.clone();// 自適應中值濾波cv::Mat img1;// 擴展圖像的邊界cv::copyMakeBorder(img, img1, maxSize / 2, maxSize / 2, maxSize / 2, maxSize / 2, cv::BorderTypes::BORDER_REFLECT);// 圖像循環for (int j = maxSize / 2;j < img1.rows - maxSize / 2;j++){for (int i = maxSize / 2;i < img1.cols - maxSize / 2;i++){img1.at<uchar>(j, i) = adaptiveMedianFilter(img1, j, i, minSize, maxSize);}}cv::imshow("adaptiveMedianFilter", img1);// 中值濾波cv::Mat img2;int kernelSize = 3;cv::copyMakeBorder(temp, img2, kernelSize / 2, kernelSize / 2, kernelSize / 2, kernelSize / 2, cv::BorderTypes::BORDER_REFLECT);for (int j = kernelSize / 2;j < img2.rows - kernelSize / 2;j++){for (int i = kernelSize / 2;i < img2.cols - kernelSize / 2;i++){img2.at<uchar>(j, i) = medianFilter(img2, j, i, kernelSize);}}cv::imshow("medianFilter", img2);cv::waitKey();cv::destroyAllWindows();return 0; }

結果截圖

原始圖像和添加椒鹽噪聲后的圖像。

其實截圖中看不出很明顯的區別,在自己電腦上運行后看結果會清楚點。可以看到使用普通中值濾波的結果相比另一個會模糊一些,且局部仍然會有一小的噪聲點。圖像邊緣多出來的區域不好做中值濾波處理保留了原始圖像,所以邊緣那一圈仍然有噪聲。

總結

以上是生活随笔為你收集整理的自适应中值滤波及实现的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。