1. 程式人生 > >OpenCV基礎(六)---圖像濾波

OpenCV基礎(六)---圖像濾波

bim height 空間 int 空域濾波 edwin 思路 idt med

圖像濾波

對圖像進行單個像素操作,主要是進行對比度和閾值處理

而圖像濾波在像素鄰域間進行,一來達到我們希望的效果,二來進一步進行圖像特征提取

濾波分為空間域和頻域濾波,空間域濾波又分線性、非線性濾波

常用的線性濾波有,均值濾波,高斯濾波;非線性濾波有中值濾波,雙邊濾波

線性濾波

均值模糊:blur()

void blur( InputArray src, OutputArray dst,
                        Size ksize, Point anchor = Point(-1,-1),
                        int
borderType = BORDER_DEFAULT );
  • src 源圖像
  • dst 輸出圖像
  • ksize 卷積核
  • anchor 錨點在核中心
  • borderType 圖像邊界處理方式

卷積核如下圖所示

技術分享圖片

高斯模糊:GaussianBlur()

void GaussianBlur( InputArray src, OutputArray dst, Size ksize,
                                double sigmaX, double sigmaY = 0,
                                
int borderType = BORDER_DEFAULT );
  • src 源圖像
  • dst 目的圖像
  • ksize 高斯核,ksize.width與ksize.height可以不同,但必須為正的奇數.可以為0,通過simga計算得到
  • sigmaX 高斯核在x方向的標準差
  • sigmaY 高斯核在y方向的標準差
  • borderType 邊界像素處理方式

均值與高斯模糊代碼:

 1 #include <opencv2/opencv.hpp>
 2 #include <iostream>
 3 
 4 using namespace std;
5 using namespace cv; 6 7 int main() { 8 9 Mat srcImage = imread("D:/lena.png"); 10 if (!srcImage.data) { 11 cout << "could not load image" << endl; 12 return -1; 13 } 14 imshow("src Image", srcImage); 15 16 Mat bImage, gImage; 17 blur(srcImage, bImage, Size(3, 3)); 18 GaussianBlur(srcImage, gImage, Size(3, 3), 11, 11); 19 20 imshow("blur", bImage); 21 imshow("Gaussblur", bImage); 22 waitKey(0); 23 return 0; 24 }

效果圖:

技術分享圖片技術分享圖片技術分享圖片

非線性濾波

統計排序濾波器是一種非線性濾波器,最知名的便是中值濾波。它將濾波器所包含的圖像區域進行排序,選取中間值代替該點像素值,

其對椒鹽噪聲處理十分有效

中值濾波

void medianBlur( InputArray src, OutputArray dst, int ksize );
  • src 源圖像
  • dst 目的圖像
  • ksize 孔徑尺寸,必須為大於1的奇數
 1 #include <opencv2/opencv.hpp>
 2 #include <iostream>
 3 
 4 using namespace std;
 5 using namespace cv;
 6 
 7 
 8 //加入椒鹽噪聲
 9 void salt(Mat image, int n)
10 {
11     int i, j;
12     for (int k = 0; k<n; k++)
13     {
14         // rand()是隨機數生成器
15         i = rand() % image.cols;
16         j = rand() % image.rows;
17         if (image.type() == CV_8UC1)
18         { // 灰度圖像
19             if(rand()% 2 == 0)
20             image.at<uchar>(j, i) = 255;
21             else
22                 image.at<uchar>(j, i) = 0;
23         }
24         else if (image.type() == CV_8UC3)
25         { // 彩色圖像
26             if (rand()%2==0) {
27                 image.at<cv::Vec3b>(j, i)[0] = 255;
28                 image.at<cv::Vec3b>(j, i)[1] = 255;
29                 image.at<cv::Vec3b>(j, i)[2] = 255;
30             }
31             else{
32                 image.at<cv::Vec3b>(j, i)[0] = 0;
33                 image.at<cv::Vec3b>(j, i)[1] = 0;
34                 image.at<cv::Vec3b>(j, i)[2] = 0;
35             }
36         }
37     }
38 }
39 
40 int main() {
41 
42     Mat srcImage = imread("D:/lena.png");
43     if (!srcImage.data) {
44         cout << "could not load image" << endl;
45         return -1;
46     }
47     salt(srcImage, 1500);   //加入椒鹽噪聲
48     imshow("src Image", srcImage);   
49     
50     Mat mImage;
51     medianBlur(srcImage, mImage, 3); //中值濾波
52     imshow("medianblur", mImage);
53  
54     waitKey(0);
55     return 0;
56 

效果圖:

技術分享圖片技術分享圖片

雙邊濾波

1.介紹 雙邊濾波(Bilateral Filtering)是一種簡單,非叠代的保邊去噪算法。

在最廣泛的意義上“濾波”這一詞,濾波圖像在給定位置的值是輸入圖像在相同位置小鄰域中的函數。

例如,高斯低通濾波(Gaussian low-pass fitering)計算像素鄰域中得加權平均值,權重隨著遠離鄰域中心減少。

雖然可以給出這種權重下降的正式和定量解釋,但直覺是圖像通常在空間上緩慢變化,

因此鄰近像素可能具有相似的值,因此將它們平均在一起是合適的。

破壞這些鄰近像素的噪聲值與信號值相互關聯較少,因此,當信號被保留時,噪聲平均消失。

然而在邊緣處,假設的緩慢空間變化失效了,因此會被線性低通濾波器模糊。

如何在平滑圖像的同時,防止邊緣被平均呢?下面介紹雙邊濾波的基本思路。

2.思路

雙邊濾波的基本思想是在傳統空域濾波中引入值域濾波。兩個像素可以彼此接近,即占據附近的空間位置,或者它們可以彼此相似,即具有鄰近的值。

考慮應用於圖像的平移不變低通域濾波器:

技術分享圖片

歸一化常數

技術分享圖片

類似的定義值濾波器:

技術分享圖片

在這種情況下歸一化常數:

技術分享圖片

解決方案是結合空域和值濾波,組合濾波可以描述如下:

技術分享圖片

歸一化常數是,

技術分享圖片

結合空域與值域濾波被定義為雙邊濾波。在光滑的區域,鄰域中像素的值差異不大,雙邊濾波的效果與標準空間濾波等同,

平均的消除噪聲引起的像素值之間的小的、弱相關的差異。

在邊緣處,濾波器用其附近的明亮像素的平均值代替中心處的明亮像素,並且基本上忽略了暗像素,

反之,當濾波器以暗像素為中心時,則忽略了明亮像素。

至此,由於濾波器的空域成分,邊界得以保存;由於濾波器的值域成分,清晰的邊緣也得以保存

 void bilateralFilter( InputArray src, OutputArray dst, int d,
                                   double sigmaColor, double sigmaSpace,
                                   int borderType = BORDER_DEFAULT );
  • src 單通道,浮點類型,源圖像
  • dst 輸出圖像,與src類型一致
  • d 用於濾波的每個像素鄰域的直徑。如果它是非正的,

    它是從sigmaSpace計算出來的

  • sigmaColor 較大的參數值意味著像素鄰域內的較遠顏色(參見sigmaSpace)將混合在一起
  • sigmaSpace 坐標空間中的sigmaSpace濾波器。參數值越大意味著越遠處的像素(若像素足夠接近)會影響該點像素
 1 #include <opencv2/opencv.hpp>
 2 #include <iostream>
 3 
 4 using namespace std;
 5 using namespace cv;
 6 
 7 int main() {
 8     Mat src, dst;
 9     src = imread("D:/kitten-orig.png");
10     if (src.empty()) {
11         cout << "could not load image..." << endl;
12         return -1;
13     }
14     bilateralFilter(src, dst, 9, 75, 75); 
15     namedWindow("input", CV_WINDOW_AUTOSIZE);
16     imshow("input", src);
17     namedWindow("output", CV_WINDOW_AUTOSIZE);
18     imshow("output", dst);
19     imwrite("kitten-outp.png", dst); 
20     waitKey(0);
21 }

效果對比:

技術分享圖片技術分享圖片

OpenCV基礎(六)---圖像濾波