OpenCV 筆記(28):圖像降噪算法——中值濾波、高斯濾波

1. 圖像噪聲

圖像降噪(Image Denoising)是指從圖像中去除噪聲的過程,目的是提高圖像質(zhì)量,增強(qiáng)圖像的視覺效果。

圖像噪聲是指圖像中不希望出現(xiàn)的隨機(jī)亮度或顏色變化,通常會降低圖像的清晰度和可辨識度,以及會降低圖像的質(zhì)量并使圖像分析和理解更加困難。

圖像噪聲主要有以下幾個(gè)原因來產(chǎn)生的:

  • 光線不足:光線不足會導(dǎo)致光子噪聲增加,從而降低圖像的信噪比。
  • 電子元器件的熱噪聲:電子元器件在工作時(shí)會產(chǎn)生熱噪聲,這種噪聲會影響圖像的質(zhì)量。
  • 電路噪聲:電路中的電磁干擾也會導(dǎo)致圖像噪聲的產(chǎn)生。
  • 圖像傳輸過程中的錯(cuò)誤:圖像在傳輸過程中可能會受到各種干擾,從而導(dǎo)致圖像噪聲的產(chǎn)生。

根據(jù)噪聲的統(tǒng)計(jì)特性來分類,可以將圖像噪聲分為以下幾類:

  • 椒鹽噪聲:圖像中隨機(jī)出現(xiàn)黑白像素的噪聲。
  • 高斯噪聲:最常見的噪聲類型,其概率密度函數(shù)服從高斯分布。
  • 泊松噪聲:光子噪聲的一種類型,其概率密度函數(shù)服從泊松分布。
  • 斑點(diǎn)噪聲:由圖像傳感器壞點(diǎn)或污點(diǎn)引起的噪聲。

下面的例子,分別展示了在圖像中添加椒鹽噪聲、高斯噪聲、泊松噪聲和斑點(diǎn)噪聲。

#include <opencv2/opencv.hpp>
#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>
#include <random>

using namespace std;
using namespace cv;

void addSaltNoise(Mat &src, int num, Mat &dst)
{
    dst = src.clone();

    // 隨機(jī)數(shù)產(chǎn)生器
    std::random_device rd; //種子
    std::mt19937 gen(rd()); // 隨機(jī)數(shù)引擎

    auto rows = src.rows; // 行數(shù)
    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;
    }
}

void addGaussianNoise(Mat &src, int mu, int sigma, Mat &dst)
{
    dst = src.clone();

    // 產(chǎn)生高斯分布的隨機(jī)數(shù)發(fā)生器
    std::random_device rd;
    std::mt19937 gen(rd());

    std::normal_distribution<> d(mu, sigma);

    auto rows = src.rows; // 行數(shù)
    auto cols = src.cols * src.channels(); // 列數(shù)

    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;

void addPoissonNoise(const Mat& src, double lambda, Mat& dst) {
    dst = src.clone();

    // 產(chǎn)生泊松分布的隨機(jī)數(shù)生成器
    std::random_device rd;
    std::mt19937 gen(rd());
    std::poisson_distribution<int> distribution(lambda);

    dst.forEach<Pixel>([&](Pixel &p, const int * 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);
    });
}

void addSpeckleNoise(Mat& image, double scale, Mat &dst) {
    dst = image.clone();
    RNG rng;

    dst.forEach<Pixel>([&](Pixel &p, const int * position) -> void {
        int row = position[0];
        int col = position[1];

        double random_value = rng.uniform(0.0, 1.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);
    });
}

int main() {
    Mat src = imread(".../girl.jpg");

    imshow("src", src);

    Mat dst1;
    addSaltNoise(src,100000,dst1);
    imshow("addSaltNoise", dst1);

    Mat dst2;
    addGaussianNoise(src, 0, 50,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);
    return 0;
}
原圖和椒鹽噪聲.png
原圖和高斯噪聲.png
原圖和泊松噪聲.png
原圖和斑點(diǎn)噪聲.png

2. 圖像降噪方法

傳統(tǒng)的圖像處理是基于濾波器的方式進(jìn)行降噪,比如使用空域?yàn)V波、頻域?yàn)V波、非局部均值濾波等等,還有使用形態(tài)學(xué)降噪,當(dāng)然也可以深度學(xué)習(xí)的方式進(jìn)行降噪。

本文介紹兩種空域?yàn)V波的方式進(jìn)行降噪。

2.1 中值濾波

中值濾波是一種非線性濾波器,它通過對圖像中的像素值進(jìn)行排序并取中間值來進(jìn)行濾波處理。

中值濾波.png

中值濾波的特性:

  • 對于圖像中的每個(gè)像素,選取其周圍一定區(qū)域內(nèi)的所有像素值,并對其進(jìn)行排序。
  • 將排序后的像素值的中位數(shù)賦予該像素。

中值濾波的優(yōu)點(diǎn):

  • 能夠有效去除椒鹽噪聲和脈沖噪聲,對圖像中的孤立噪聲點(diǎn)具有較強(qiáng)的抑制能力。
  • 能夠較好地保留圖像的邊緣和細(xì)節(jié)信息,不會造成圖像模糊。

中值濾波的缺點(diǎn):

  • 對高斯噪聲的去除效果不佳。
  • 計(jì)算量相對較大,特別是對于大尺寸圖像而言。

2.2 高斯濾波

高斯濾波是一種線性平滑濾波器,它利用高斯函數(shù)對圖像進(jìn)行加權(quán)平均,可以有效地去除高斯噪聲,同時(shí)平滑圖像。

高斯濾波的優(yōu)點(diǎn):

  • 高斯濾波具有良好的平滑效果,能夠有效地抑制圖像中的噪聲。
  • 高斯濾波是一種線性濾波器,具有可分離性,可以提高計(jì)算效率。
  • 高斯濾波在頻域上具有低通濾波器的特性,能夠去除圖像中的高頻噪聲。

高斯濾波的缺點(diǎn):

  • 高斯濾波會造成圖像細(xì)節(jié)丟失,降低圖像銳度。
  • 高斯濾波對椒鹽噪聲等非平滑噪聲的去除效果不佳。

高斯濾波以使用兩種方法實(shí)現(xiàn):一種是離散化窗口滑窗卷積,另一種方法是通過傅里葉變化。最常見的就是滑窗卷積實(shí)現(xiàn)。

先來回顧一下一維高斯函數(shù):

G(x) = \frac{1}{ \sqrt{2\pi}\delta}e^{-\frac{(x-\mu)^2}{2\delta^2}}

一維高斯函數(shù).png

其中,\mu是 x 的均值,\delta是 x 的方差。x 是卷積核內(nèi)任意一點(diǎn)的坐標(biāo),\mu是卷積核中心的坐標(biāo)。當(dāng) \mu= 0 時(shí),

G(x) = \frac{1}{ \sqrt{2\pi}\delta}e^{-\frac{x^2}{2\delta^2}}

由于圖像是二維的,二維的高斯函數(shù)則是對 x、y 兩個(gè)方向的一維高斯函數(shù)的乘積:

G(x,y) = G(x)*G(y) = \frac{1}{ \sqrt{2\pi}\delta_x}e^{-\frac{(x-\mu_x)^2}{2\delta_x^2}}*\frac{1}{ \sqrt{2\pi}\delta_y}e^{-\frac{(y-\mu_y)^2}{2\delta_y^2}}

當(dāng)\mu_x = \mu_y = 0時(shí),就是我們比較熟悉的二維高斯函數(shù)公式:

G(x,y) = \frac{1}{2\pi\delta^2}e^{-\frac{x^2+y^2}{2\delta^2}}

二維高斯函數(shù).png

常用的高斯模板有如下幾種形式,它們是基于高斯函數(shù)計(jì)算出來的。

高斯模版.png

高斯濾波具有以下性質(zhì):

  • 線性: 高斯濾波器是線性的,這意味著它可以與其他濾波器組合使用。例如,可以先使用高斯濾波器去除噪聲,然后再使用邊緣檢測濾波器檢測邊緣。
  • 可分離性: 高斯濾波器可以分離為兩個(gè)一維濾波器,即水平方向和垂直方向的濾波器。這使得高斯濾波器的計(jì)算效率更高。
  • 傅里葉變換: 高斯濾波器的傅里葉變換是一個(gè)低通濾波器,這意味著它可以抑制圖像中的高頻成分,而保留低頻成分。
  • 旋轉(zhuǎn)不變性: 高斯濾波器在各個(gè)方向上具有相同的平滑效果,這意味著它不會改變圖像的旋轉(zhuǎn)方向。
  • 尺度不變性: 高斯濾波器的尺度可以通過調(diào)整高斯函數(shù)的標(biāo)準(zhǔn)差來控制。標(biāo)準(zhǔn)差越大,濾波器的平滑效果越強(qiáng)。

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

int main() {
    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, 0, 50,dst2);
    imshow("addGaussianNoise", dst2);

    GaussianBlur(dst2, result, Size(15, 15), 0, 0);
    imshow("removeGaussianNoise", result);

    waitKey(0);
    return 0;
}
椒鹽噪聲和中值濾波后的效果.jpeg
高斯噪聲和高斯濾波后的效果.png

3. 總結(jié)

圖像降噪可以提高圖像質(zhì)量、提高圖像分析和處理的準(zhǔn)確性、提高圖像壓縮效率以及擴(kuò)展圖像應(yīng)用范圍。

本文介紹了兩種簡單的降噪算法。中值濾波適用于去除椒鹽噪聲和脈沖噪聲,常用于圖像修復(fù)和增強(qiáng)。高斯濾波適用于去除高斯噪聲、平滑圖像,常用于圖像預(yù)處理和模糊處理。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,527評論 6 544
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,687評論 3 429
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,640評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,957評論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 72,682評論 6 413
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 56,011評論 1 329
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,009評論 3 449
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 43,183評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,714評論 1 336
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 41,435評論 3 359
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 43,665評論 1 374
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,148評論 5 365
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,838評論 3 350
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,251評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,588評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 52,379評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 48,627評論 2 380

推薦閱讀更多精彩內(nèi)容