當前位置: 妍妍網 > 碼農

OpenCV影像降噪演算法之中值濾波與高斯濾波

2024-04-02碼農

1. 影像雜訊

影像降噪(Image Denoising)是指從影像中去除 雜訊 的過程,目的是提高影像品質,增強影像的視覺效果。

影像雜訊是指影像中不希望出現的隨機亮度或顏色變化,通常會降低影像的解析度和可辨識度,以及會降低影像的品質並使影像分析和理解更加困難。

影像雜訊主要有以下幾個原因來產生的:

  • 光線不足 :光線不足會導致光子雜訊增加,從而降低影像的訊雜比。

  • 電子元器件的熱雜訊 :電子元器件在工作時會產生熱雜訊,這種雜訊會影響影像的品質。

  • 電路雜訊 :電路中的電磁幹擾也會導致影像雜訊的產生。

  • 影像傳輸過程中的錯誤 :影像在傳輸過程中可能會受到各種幹擾,從而導致影像雜訊的產生。

  • 根據雜訊的統計特性來分類,可以將影像雜訊分為以下幾類:

  • 椒鹽雜訊 :影像中隨機出現黑白像素的雜訊。

  • 高斯雜訊 :最常見的雜訊型別,其機率密度函式服從高斯分布。

  • 帕松雜訊 :光子雜訊的一種型別,其機率密度函式服從卜瓦松分布。

  • 斑點雜訊 :由影像傳感器壞點或汙點引起的雜訊。

  • 下面的例子,分別展示了在影像中添加椒鹽雜訊、高斯雜訊、帕松雜訊和斑點雜訊。

    #include<opencv2/opencv.hpp>
    #include<opencv2/core.hpp>
    #include<opencv2/highgui.hpp>
    #include<random>
    usingnamespacestd;
    usingnamespace cv;
    voidaddSaltNoise(Mat &src, int num, Mat &dst)
    {
    dst = src.clone();
    // 隨機數產生器
    std::random_device rd; //種子
    std::mt19937 gen(rd())// 隨機數引擎
    auto rows = src.rows; // 行數
    auto cols = src.cols * src.channels();
    for (int i = 0; i < num; i++)
    {
    auto row = static_cast<int>(gen() % rows);
    auto col = static_cast<int>(gen() % cols);
    auto p = dst.ptr<uchar>(row);
    p[col++] = 255;
    p[col++] = 255;
    p[col] = 255;
    }
    }
    voidaddGaussianNoise(Mat &src, int mu, int sigma, Mat &dst)
    {
    dst = src.clone();
    // 產生高斯分布的隨機數發生器
    std::random_device rd;
    std::mt19937 gen(rd());
    std::normal_distribution<> d(mu, sigma);
    auto rows = src.rows; // 行數
    auto cols = src.cols * src.channels(); // 列數
    for (int i = 0; i < rows; i++)
    {
    auto p = dst.ptr<uchar>(i); // 取得行首指標
    for (int j = 0; j < cols; j++)
    {
    auto tmp = p[j] + d(gen);
    tmp = tmp > 255 ? 255 : tmp;
    tmp = tmp < 0 ? 0 : tmp;
    p[j] = tmp;
    }
    }
    }
    typedef cv::Point3_<uint8_t> Pixel;
    voidaddPoissonNoise(const Mat& src, double lambda, Mat& dst){
    dst = src.clone();
    // 產生卜瓦松分布的隨機數生成器
    std::random_device rd;
    std::mt19937 gen(rd());
    std::poisson_distribution<intdistribution(lambda);
    dst.forEach<Pixel>([&](Pixel &p, constint * position) -> void {
    int row = position[0];
    int col = position[1];
    int count = distribution(gen);
    dst.at<Vec3b>(row, col) = dst.at<Vec3b>(row, col) + Vec3b(count, count, count);
    });
    }
    voidaddSpeckleNoise(Mat& image, double scale, Mat &dst){
    dst = image.clone();
    RNG rng;
    dst.forEach<Pixel>([&](Pixel &p, constint * position) -> void {
    int row = position[0];
    int col = position[1];
    double random_value = rng.uniform(0.01.0);
    double noise_intensity = random_value * scale;
    dst.at<Vec3b>(row, col) = dst.at<Vec3b>(row, col) + Vec3b(noise_intensity * 255, noise_intensity * 255, noise_intensity * 255);
    });
    }
    intmain(){
    Mat src = imread(".../girl.jpg");
    imshow("src", src);
    Mat dst1;
    addSaltNoise(src,100000,dst1);
    imshow("addSaltNoise", dst1);
    Mat dst2;
    addGaussianNoise(src, 050,dst2);
    imshow("addGaussianNoise", dst2);
    Mat dst3;
    addPoissonNoise(src, 60, dst3);
    imshow("addPoissonNoise", dst3);
    Mat dst4;
    addSpeckleNoise(src,0.5,dst4);
    imshow("addSpeckleNoise", dst4);
    waitKey(0);
    return0;
    }
























    原圖和椒鹽雜訊.png

    原圖和高斯雜訊.png

    原圖和帕松雜訊.png

    原圖和斑點雜訊.png

    2. 影像降噪方法

    傳統的影像處理是基於濾波器的方式進行降噪,比如使用空域濾波、頻域濾波、非局部均值濾波等等,還有使用形態學降噪,當然也可以深度學習的方式進行降噪。

    本文介紹兩種空域濾波的方式進行降噪。

    2.1 中值濾波

    中值濾波是一種 非線性 濾波器,它透過對影像中的像素值進行排序並取中間值來進行濾波處理。

    中值濾波.png

    中值濾波的特性:

  • 對於影像中的每個像素,選取其周圍一定區域內的所有像素值,並對其進行排序。

  • 將排序後的像素值的中位數賦予該像素。

  • 中值濾波的優點:

  • 能夠有效去除椒鹽雜訊和脈沖雜訊,對影像中的孤立雜訊點具有較強的抑制能力。

  • 能夠較好地保留影像的邊緣和細節資訊,不會造成影像模糊。

  • 中值濾波的缺點:

  • 對高斯雜訊的去除效果不佳。

  • 計算量相對較大,特別是對於大尺寸影像而言。

  • 2.2 高斯濾波

    高斯濾波是一種 線性 平滑濾波器,它利用高斯函式對影像進行加權平均,可以有效地去除高斯雜訊,同時平滑影像。

    高斯濾波的優點:

  • 高斯濾波具有良好的平滑效果,能夠有效地抑制影像中的雜訊。

  • 高斯濾波是一種線性濾波器,具有可分離性,可以提高計算效率。

  • 高斯濾波在頻域上具有低通濾波器的特性,能夠去除影像中的高頻雜訊。

  • 高斯濾波的缺點:

  • 高斯濾波會造成影像細節遺失,降低影像銳度。

  • 高斯濾波對椒鹽雜訊等非平滑雜訊的去除效果不佳。

  • 高斯濾波以使用兩種方法實作:一種是離散化視窗滑窗摺積,另一種方法是透過傅立葉變化。最常見的就是滑窗摺積實作。

    先來回顧一下一維高斯函式:

    一維高斯函式.png

    其中,是 x 的均值,是 x 的變異數。x 是摺積核內任意一點的座標,是摺積核中心的座標。當 = 0 時,

    由於影像是二維的,二維的高斯函式則是對 x、y 兩個方向的一維高斯函式的乘積:

    當時,就是我們比較熟悉的二維高斯函式公式:

    二維高斯函式.png

    常用的高斯樣版有如下幾種形式,它們是基於高斯函式計算出來的。

    高斯模版.png

    高斯濾波具有以下性質:

  • 線性: 高斯濾波器是線性的,這意味著它可以與其他濾波器組合使用。例如,可以先使用高斯濾波器去除雜訊,然後再使用邊緣檢測濾波器檢測邊緣。

  • 可分離性: 高斯濾波器可以分離為兩個一維濾波器,即水平方向和垂直方向的濾波器。這使得高斯濾波器的計算效率更高。

  • 傅立葉變換: 高斯濾波器的傅立葉變換是一個低通濾波器,這意味著它可以抑制影像中的高頻成分,而保留低頻成分。

  • 旋轉不變性: 高斯濾波器在各個方向上具有相同的平滑效果,這意味著它不會改變影像的旋轉方向。

  • 尺度不變性: 高斯濾波器的尺度可以透過調整高斯函式的標準差來控制。標準差越大,濾波器的平滑效果越強。

  • 下面的例子,分別使用中值濾波和高斯濾波消除椒鹽雜訊和高斯雜訊。

    intmain(){
    Mat src = imread(".../girl.jpg");
    imshow("src", src);
    Mat result;
    Mat dst1;
    addSaltNoise(src,100000,dst1);
    imshow("addSaltNoise", dst1);
    int a = 7;
    medianBlur(dst1, result,a);
    imshow("removeSaltNoise", result);
    Mat dst2;
    addGaussianNoise(src, 050,dst2);
    imshow("addGaussianNoise", dst2);
    GaussianBlur(dst2, result, Size(1515), 00);
    imshow("removeGaussianNoise", result);
    waitKey(0);
    return0;
    }





    椒鹽雜訊和中值濾波後的效果.jpeg

    高斯雜訊和高斯濾波後的效果.png

    3. 總結

    影像降噪可以提高影像品質、提高影像分析和處理的準確性、提高影像壓縮效率以及擴充套件影像套用範圍。

    本文介紹了兩種簡單的降噪演算法。中值濾波適用於去除椒鹽雜訊和脈沖雜訊,常用於影像修復和增強。高斯濾波適用於去除高斯雜訊、平滑影像,常用於影像預處理和模糊處理。

    系統化學習直接掃碼檢視

    推薦閱讀