影像平滑(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;
}

blur

blur

blur

blur

回到首頁

回到OpenCV教學


參考資料:

OpenCV 教程