这是图像处理的第一章,简单地说一下OpenCv
的基础功能
这一节,我将会介绍一下各种噪声的类型,并且添加两三种常见的噪声
将图像读入到Mat
后,有三种方式访问Mat
中的数据:
相信大家已经对这些基础中的基础了解的很不错了,所以我就直接开始介绍主题,噪声
(以下的介绍为其他博客找到的)
图像噪声是图像在获取或传输的过程中受到随机信号的干扰,在图像上出现的一些随机的、离散的、孤立的像素点,这些点会干扰人眼对图像信息的分析。图像的噪声通常是比较复杂的,很多时候将其看成是多维随机过程,因而可以借助于随即过程描述噪声,即使用概率分布函数和概率密度函数。
图像的噪声很多,性质也千差万别, 可以通过不同的方法给噪声分类。
按照产生的原因:
内部噪声
这种分类方法,有助于理解噪声产生的源头,但对于降噪算法只能起到原理上的帮组。
噪声和图像信号的关系,可以分为:
按照概率密度函数(PDF)分类:
按照指定的噪声类型,生成一个随机数,然后将这个随机数加到源像素值上,并将得到的值所放到[0,255]
区间即可。
我在噪声的加成上用的是C++11
新标准下的随机数生成方法
新的随机数生成器被抽象成了两个部分:随机数生成引擎和要生成的随机数符合的分布。
随机数引擎有三种:
linear_congruential_engine
线性同余算法 mersenne_twister_engine
梅森旋转算法subtract_with_carry_engine
带进位的线性同余算法第一种最常用,而且速度比较快;第二种号称最好的伪随机数生成器
std::random_device rd; // 随机数种子
std::mt19937 mt(rd()); // 随机数引擎
std::normal_distribution<> d(5,20); // 高斯分布
std::map<int,int> hist;
for(int n = 0; n < 10000; n ++)
++hist[std::round(d(mt))]; // 生成符合高斯分布的随机数
以上为生成符合高斯分布的随机数
使用C++的随机数发生器为图像添加两种噪声:椒盐噪声和高斯噪声。
对了,记得要用这个随机数产生的话,请#include
,用法请自行百度
椒盐噪声是图像中离散分布的白点或者黑点,测试代码如下:
void addSaltNoise(Mat &m, int num)
{ // 随机数产生器
std::random_device rd; //种子
std::mt19937 gen(rd()); // 随机数引擎
auto cols = m.cols * m.channels();
for (int i = 0; i < num; i++)
{
auto row = static_cast<int>(gen() % m.rows);
auto col = static_cast<int>(gen() % cols);
auto p = m.ptr(row);
p[col++] = 255;
p[col++] = 255;
p[col] = 255;
}
}
高斯噪声是一种加性噪声,为图像添加高斯噪声的代码如下:
//添加高斯噪声
//用指针进行像素点的访问
void addGaussianNoise(Mat & img, const int& mu,const int & sigma)
{
auto cols = img.cols*img.channels();
auto rows = img.rows;
// 产生Gauss分布随机数发生器
std::random_device rd;
std::mt19937 gen(rd());
std::normal_distribution<> gaussR(mu, sigma);
for (int i = 0; i < rows; i++)
{
auto p = img.ptr(i);
for (int j = 0; j < cols; j++)
{
auto tmp = p[j] + gaussR(gen);
tmp = tmp > 255 ? 255 : tmp;
tmp = tmp < 0 ? 0 : tmp;
p[j] = tmp;
}
}
}
以下为运行结果:
左边是原始图片,中间是椒盐噪声模糊之后的图像,最后是高斯模糊之后的图像
根据噪声类型的不同,选择不同的滤波器过滤掉噪声。通常,对于椒盐噪声,选择中值滤波器(Median Filter),在去掉噪声的同时,不会模糊图像;对于高斯噪声,选择均值滤波器(Mean Filter),能够去掉噪声,但会对图像造成一定的模糊。
在OpenCV中,对应于均值滤波器的函数是blur,该函数需要5个参数,通常只设置前3个后两个使用默认值即可。
blur(m, m2, Size(5, 5));
第一个参数是输入的图像,第二个参数是输出的图像,第三个参数是滤波器的大小,这里使用的是5×5
的矩形。
对应于中值滤波器的函数是medianBlur(m1, m3, 5);
前两个参数是输入输出的图像,第三个参数是滤波器的大小,由于是选取的是中值,滤波器的大小通常是一个奇数。
下图是对有噪声图像使用滤波器后的结果,中间的是原始图像,左边的是使用均值滤波器过滤高斯噪声后的结果;右边的是使用中值滤波器过滤椒盐噪声后的结果。可以明显的看出,这两种滤波器都能够很好的去掉图像的噪声,但会对图像造成一定的模糊,尤其是均值滤波器造成的模糊比较明显。
PS:好了,差不多如此,借鉴了很多别人博客的东西,希望这一周能够多总结一下opencv的东西。