1. 图画噪声

图画降噪(Image Denoising)是指从图画中去除噪声的过程,目的是进步图画质量,增强图画的视觉作用。

图画噪声是指图画中不期望呈现的随机亮度或色彩变化,通常会下降图画的清晰度和可辨识度,以及会下降图画的质量并使图画剖析和了解愈加困难。

图画噪声主要有以下几个原因来发生的:

  • 光线不足:光线不足会导致光子噪声增加,然后下降图画的信噪比。
  • 电子元器件的热噪声:电子元器件在工作时会发生热噪声,这种噪声会影响图画的质量。
  • 电路噪声:电路中的电磁干扰也会导致图画噪声的发生。
  • 图画传输过程中的过错:图画在传输过程中可能会受到各种干扰,然后导致图画噪声的发生。

根据噪声的计算特性来分类,能够将图画噪声分为以下几类:

  • 椒盐噪声:图画中随机呈现黑白像素的噪声。
  • 高斯噪声:最常见的噪声类型,其概率密度函数服从高斯散布。
  • 泊松噪声:光子噪声的一种类型,其概率密度函数服从泊松散布。
  • 斑驳噪声:由图画传感器坏点或污点引起的噪声。

下面的比如,分别展示了在图画中添加椒盐噪声、高斯噪声、泊松噪声和斑驳噪声。

#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();
    // 随机数发生器
    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;
    }
}
void addGaussianNoise(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;
void addPoissonNoise(const Mat& src, double lambda, Mat& dst) {
    dst = src.clone();
    // 发生泊松散布的随机数生成器
    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;
}

OpenCV 笔记(28):图画降噪算法——中值滤波、高斯滤波

OpenCV 笔记(28):图画降噪算法——中值滤波、高斯滤波

OpenCV 笔记(28):图画降噪算法——中值滤波、高斯滤波

OpenCV 笔记(28):图画降噪算法——中值滤波、高斯滤波

2. 图画降噪办法

传统的图画处理是根据滤波器的方法进行降噪,比如运用空域滤波、频域滤波、非局部均值滤波等等,还有运用形态学降噪,当然也能够深度学习的方法进行降噪。

本文介绍两种空域滤波的方法进行降噪。

2.1 中值滤波

中值滤波是一种非线性滤波器,它经过对图画中的像素值进行排序并取中间值来进行滤波处理。

OpenCV 笔记(28):图画降噪算法——中值滤波、高斯滤波

中值滤波的特性:

  • 对于图画中的每个像素,选取其周围一定区域内的一切像素值,并对其进行排序。
  • 将排序后的像素值的中位数赋予该像素。

中值滤波的优点:

  • 能够有效去除椒盐噪声和脉冲噪声,对图画中的孤立噪声点具有较强的按捺才能。
  • 能够较好地保留图画的边际和细节信息,不会形成图画模糊。

中值滤波的缺点:

  • 对高斯噪声的去除作用欠安。
  • 计算量相对较大,特别是对于大尺寸图画而言。

2.2 高斯滤波

高斯滤波是一种线性滑润滤波器,它运用高斯函数对图画进行加权平均,能够有效地去除高斯噪声,一起滑润图画。

高斯滤波的优点:

  • 高斯滤波具有杰出的滑润作用,能够有效地按捺图画中的噪声。
  • 高斯滤波是一种线性滤波器,具有可别离性,能够进步计算功率。
  • 高斯滤波在频域上具有低通滤波器的特性,能够去除图画中的高频噪声。

高斯滤波的缺点:

  • 高斯滤波会形成图画细节丢掉,下降图画锐度。
  • 高斯滤波对椒盐噪声等非滑润噪声的去除作用欠安。

高斯滤波以运用两种办法完成:一种是离散化窗口滑窗卷积,另一种办法是经过傅里叶变化。最常见的便是滑窗卷积完成。

先来回顾一下一维高斯函数:

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

OpenCV 笔记(28):图画降噪算法——中值滤波、高斯滤波

其中,mu是 x 的均值,delta是 x 的方差。x 是卷积核内任意一点的坐标,mu是卷积核中心的坐标。当 mu= 0 时,

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

由于图画是二维的,二维的高斯函数则是对 x、y 两个方向的一维高斯函数的乘积:

G(x,y)=G(x)∗G(y)=12xe−(x−x)22×2∗12ye−(y−y)22y2G(x,y)=G(x)*G(y) = frac{1}{ sqrt{2pi}delta_x}e^{-frac{(x-mu_x)^2}{2delta_x^2}}*frac{1}{ sqrt{2pi}delta_y}e^{-frac{(y-mu_y)^2}{2delta_y^2}}

x=y=0mu_x = mu_y = 0 时,便是我们比较熟悉的二维高斯函数公式:

G(x,y)=122e−x2+y222G(x,y)=frac{1}{2pidelta^2}e^{-frac{x^2+y^2}{2delta^2}}

OpenCV 笔记(28):图画降噪算法——中值滤波、高斯滤波

常用的高斯模板有如下几种方式,它们是根据高斯函数计算出来的。

OpenCV 笔记(28):图画降噪算法——中值滤波、高斯滤波

高斯滤波具有以下性质:

  • 线性: 高斯滤波器是线性的,这意味着它能够与其他滤波器组合运用。例如,能够先运用高斯滤波器去除噪声,然后再运用边际检测滤波器检测边际。
  • 可别离性: 高斯滤波器能够别离为两个一维滤波器,即水平方向和垂直方向的滤波器。这使得高斯滤波器的计算功率更高。
  • 傅里叶变换: 高斯滤波器的傅里叶变换是一个低通滤波器,这意味着它能够按捺图画中的高频成分,而保留低频成分。
  • 旋转不变性: 高斯滤波器在各个方向上具有相同的滑润作用,这意味着它不会改变图画的旋转方向。
  • 标准不变性: 高斯滤波器的标准能够经过调整高斯函数的标准差来操控。标准差越大,滤波器的滑润作用越强。

下面的比如,分别运用中值滤波和高斯滤波消除椒盐噪声和高斯噪声。

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;
}

OpenCV 笔记(28):图画降噪算法——中值滤波、高斯滤波

OpenCV 笔记(28):图画降噪算法——中值滤波、高斯滤波

3. 总结

图画降噪能够进步图画质量、进步图画剖析和处理的准确性、进步图画压缩功率以及扩展图画应用规模。

本文介绍了两种简略的降噪算法。中值滤波适用于去除椒盐噪声和脉冲噪声,常用于图画修复和增强。高斯滤波适用于去除高斯噪声、滑润图画,常用于图画预处理和模糊处理。