OpenCV學習筆記3:圖像模糊作用和方法
一、意義和作用:
圖像的模糊處理就是將圖片處理的更加模糊,如下圖,左側是原圖,右側是經過處理之後的圖片。
從主觀意願上說,我們希望看到清晰的圖像,而不是模糊的圖像。所以很多時候我們聽說還有一種專門進行模糊圖像的操作時,感覺不可思議,這有什麽用呢。要知道模糊圖像只是處理噪聲帶來的副作用,並不是我們的目的。圖像沒有噪聲的時候,我們用平滑濾波器去模糊圖像幹什麽呢?還真有一個重要的應用。把上面的圖像使用變得更加模糊之後。效果如下:
我們可以看到,相對於原始圖像,一些較小的物體已經融入背景,看不到了,有些物體即使能看到,亮度也明顯降低。這樣,我們用圖像模糊將圖像中較大的較亮的物體保留了下來,而其它的物體則消除了。我們進一步通過閾值處理對模糊後的圖像進行操作,將最高亮度的25%作為閾值,低於此閾值的賦為0,高於此閾值的賦為255。
經過處理後圖片為這樣:
像這樣利用閾值函數處理並基於物體亮度來消除某些物體的操作時很典型的。當我們只想得到感興趣的物體時,通過圖像模糊,可以將那些尺寸和亮度較小的物體過濾掉,較大的物體則易於檢測。除了降低噪聲,這就是圖像平滑(模糊)的另一個重要應用:目標提取。
二、模糊方法
模糊操作時圖像處理中最簡單和常用的操作之一,使用該操作的原因之一就為了給圖像預處理時減低噪聲。
使用模糊操作的背後是數學的卷積計算:
其中權重核h(k,l)h(k,l)為“濾波系數”。上面的式子可以簡記為:
通常這些卷積算子計算都是線性操作,所以又叫線性濾波。
均值濾波(歸一化濾波)
均值濾波是典型的線性濾波算法,它是指在圖像上對目標像素給一個模板,該模板包括了其周圍的臨近像素(以目標像素為中心的周圍8個像素,構成一個濾波模板,即去掉目標像素本身),再用模板中的全體像素的平均值來代替原來像素值。
用 3×3 大小模板進行均值濾波。
由於圖像邊框上的像素無法被模板覆蓋,所以不做處理。
這當然造成了圖像邊緣的缺失
以(2,2)像素點為例。
則濾波後的結果為:
濾波後(2,2)像素點的值由 10 變為 3
最終結果:
OpenCV提供均值濾波API:
void blur(Mat src,Mat dst, Size(xradius,yradius), Point(-1, -1))
代碼:
#include <opencv.hpp>
using namespace cv;
int main()
{
Mat srcImage;
srcImage = imread(" d://1.png");
imshow("均值濾波【原圖】", srcImage);
Mat dst; // 構造目標類
blur(srcImage, dst, Size(5, 5)); // 進行均值濾波操作
imshow("均值濾波【處理後】", dst);
waitKey();
return 0;
}
效果圖:
對於椒鹽噪聲:
對於高斯噪聲:
中值濾波
中值,中間值,將數據從小到大排序後的中間值
用 3×3 大小模板進行中值濾波。
以(2,2)像素點為例。
對模板中的 9 個數進行從小到大排序:1,1,1,2,2,5,6,6,10。中間值為 2.所有,中值濾波後(2,2)位置的值變為 2. 同理對其他像素點。
處理結果:
OpenCV提供中值濾波API:
void medianBlur(InputArray src, OutputArray dst, int ksize)
代碼:
#include <opencv.hpp> using namespace cv; int main() { Mat srcImage; srcImage = imread("d://1.png"); imshow("均值濾波【原圖】", srcImage); Mat dst; // 構造目標類 medianBlur(srcImage, dst, 3); //blur(srcImage, dst, Size(5, 5)); // 進行均值濾波操作 imshow("高斯濾波【處理後】", dst); waitKey(); return 0; }
處理結果:
雙邊濾波
- 均值模糊無法克服邊緣像素信息丟失缺陷。原因是均值模糊是基於平均權重。
- 高斯模糊部分克服了該缺陷,但是無法完全避免,因為沒考慮到像素值的不同。
- 雙邊濾波是保留邊緣的濾波方法,避免了邊緣信息的丟失,保留了圖像輪廓不變。
OpenCV提供的API:
void bilateralFilter(InputArray src, OutputArray dst, int d, double sigmaColor, double sigmaSpace, int borderType=BORDER_DEFAULT )
代碼:
#include <opencv.hpp> using namespace cv; int main() { /* d:計算的半徑 sigmaColor:多少差值之內的像素會被計算 sigmaSpace:如果d>0,那麽聲明無效,否則根據它來計算d值 */ Mat srcImage; srcImage = imread("d://1.png"); imshow("雙邊濾波【原圖】", srcImage); Mat dst; // 構造目標類 bilateralFilter(srcImage, dst, 15, 150, 3); //medianBlur(srcImage, dst, 3); //blur(srcImage, dst, Size(5, 5)); // 進行均值濾波操作 imshow("雙邊濾波【處理後】", dst); waitKey(); return 0; }
最終結果:
OpenCV學習筆記3:圖像模糊作用和方法