影像平滑(medianBlur、bilateralFilter)
平滑濾波主要分兩種,線性濾波和非線性濾波:
- 線性濾波:有一個有固定參數的核心,常見的有平均平滑和高斯平滑。
- 非線性濾波:沒有一個有固定的核心,常見的有中值濾波和雙邊濾波。
這邊我們介紹中值濾波和雙邊濾波。
中值濾波作法為統計排序的濾波器,對於影像某個像素,中值濾波會將濾波範圍內的所有像素排序,並用中值替換當前的像素值,在椒鹽噪音這種類型的雜訊,中值濾波能夠有效的去除雜訊,且模糊的現象比平均平滑和高斯平滑都來的輕微。
OpenCV中值濾波
void medianBlur(const Mat &src, Mat &dst, int ksize)
- src:當ksize為3或5時,輸入可以為多通道的CV_8U、CV_16U或CV_32F,在更大的模板時,只能操作CV_8U的型態。
- dst:輸出圖會和輸入圖尺寸、型態相同。
- ksize:模板大小,必須為大於1的正奇數,像3、5、7……。
雙邊濾波器和傳統的平滑化不同,雙邊濾波器除了使用像素之間幾何上的靠近程度之外,還多考慮了像素之間的光度/色彩差異,使得雙邊濾波器能夠有效的將影像上的雜訊去除,同時保存影像上的邊緣資訊,不過需要的處理時間相對較多。
OpenCV雙邊濾波
void bilateralFilter(const Mat &src, Mat &dst, int d, double sigmaColor, double sigmaSpace)
- src:只能處理CV_8UC1、CV_8UC3、CV_32FC1、CV_32FC3這三種。
- dst:輸出圖會和輸入圖尺寸、型態相同。
- d:過程中各像素會使用到的鄰域直徑大小
- 為了簡化,我們讓sigmaColor和sigmaSpace的值相同,如果值很小(小於10),雙邊濾波的效果不明顯,如果值很大(大於150),雙邊濾波效果明顯,這時影像會很像卡通,大的濾波處理速度會很慢,所以在即時的情況下,建議令d=5,在靜態且有大量的雜訊需要去除時,可以令d=9。
以下程式碼示範這兩種濾波的用法,中值濾波對椒鹽雜訊的去除效果不錯,雙邊濾波會做保留邊緣的動作,也就是若顏色差異幅度太大,就會判定是邊緣而不模糊,若顏色差異幅度較小,就會進行模糊,會造成卡通化的現象:
#include <cstdio>
#include <opencv2/opencv.hpp>
using namespace cv;
int main(){
Mat src1 = imread("lena_noise.jpg",CV_LOAD_IMAGE_GRAYSCALE);
Mat src2 = imread("lena.jpg");
Mat dst1;
Mat dst2;
medianBlur(src1, dst1, 5);
bilateralFilter(src2, dst2, 5 ,30 ,30);
imshow("origin1", src1);
imshow("medianBlur", dst1);
imshow("origin2", src2);
imshow("bilateralBlur", dst2);
waitKey(0);
return 0;
}
source: http://monkeycoding.com/?p=575