按老规矩,先给简要说明,然后上MATLAB,c++和Python的代码。
不管是模拟信号还是数字信号,都难免会产生噪声,尤其是模拟信号,噪声处理一直是比较重要的环节,数字信号相对来说噪声会少一点。
图像噪声的产生原因很复杂,可能是成像设备或者环境本身导致成像质量不稳定,也可能是数字信号传输过程中发生丢失或者受到干扰,可以将噪声看成是一种无规律不可预测的随机误差。
噪声主要形式有:椒盐噪声(可能是黑白噪声的看着像椒盐,然后叫这名字吧);高斯噪声(服从高斯分布的噪声,一般在数码相机图像采集阶段会产生);泊松噪声(服从泊松分布的噪声)。
噪声的产生会严重影响图像质量,必须给予纠正。
MATLAB: imnoise(src,noise_name,size),通过设置不同噪声名字,可以添加高斯,椒盐,泊松噪声。OpenCV: 没有专门添加噪声的函数,但是可以人为添加,见下文gaussian_noise()
滤波也称为平滑模糊,是一种可以有效去除图像噪声的方法。下面简单分析一下几种常见滤波器的工作原理。图像卷积核一般推荐3x3, 5x5,通常不会超过15,卷积核越大图像越模糊
图像的卷积很多文章都有讲过,就是设置一个卷积核,对图像通过卷积核进行逐个的元素相乘,再求和求平均值,从而达到图像平滑的效果。
在MATLAB中,卷积操作为: conv2(src, size); src表示输入图像,size表示设定的卷积核在OpenCV中,卷积操作为:blue(src, dst, size);
均值滤波核卷积滤波原理一致,区别是均值滤波卷积核为 n*n 的元素为1的矩阵,求出来的像素值为采样点的平均数,而卷积滤波的卷积核可以自行设置,比方我可以设置为[1 2 3; 3 2 1; 1 1 1]。
在MATLAB中,均值滤波为: imfilte(src, size); 在OpenCV中,均值滤波就是把blue的卷积核元素设置为1
中值滤波原理也很简单,就是设置一个奇数的卷积核,找出像素采样范围内的中值,用中值代替原像素,从而可以消除孤立的像素点,达到图像平滑的目的,对椒盐噪声有较好的效果。
在MATLAB中,中值滤波为: medfilt2(src, size); 在OpenCV中,中值滤波为:medianBlur(src, dst, size);
高斯模糊考虑了中心像素距离的影响,通过像素距离中心的距离,使用高斯分布公式生成不同的权重系数,自动生成卷积核参数,然后进行图像卷积操作。
在MATLAB中,高斯滤波为: fspecial(‘gaussian’, size, sigma); 这是滤波函数,若把‘gaussian’换成中值,均值,也能实现其他滤波方式在OpenCV中,高斯滤波为:GaussianBlur(src, dst, size);
和高斯滤波相比,还考虑了像素值分布对卷积输出的影响,对图像空间分布差异较大的值进行保留,因此高斯双边滤波是一种能保留边缘信息的滤波方式。运算量大,但是效果不错,看起来就跟美颜磨皮一样。
MATLAB好像没找到这个滤波方式,OpenCV调用api为: bilateralFilter()
MATLAB滤波方法有很多中,空域滤波有:卷积滤波,均值滤波,中值滤波,排序滤波,自适应滤波,逆滤波,维纳滤波等;频域滤波有低通滤波,高通滤波等多种滤波器。
并且大部分的滤波器都只能进行单通道滤波,需要各颜色通道分开滤波。
不过本次只演示空域的常用滤波方式
close all;img = imread('data/face2.jpeg');dst = imnoise(img, 'gaussian', 0, 0.02); % 添加高斯噪声subplot(1,2,1); imshow(img);title('原图像');subplot(1,2,2); imshow(dst);title('高斯噪声');result1 = imfilter(dst, 5, 5);figure;imshow(result1); title('均值滤波');% 进行中值滤波, 一次只能进行一个通道;result2(:,:,1) = medfilt2(dst(:,:,1), [5, 5]);result2(:,:,2) = medfilt2(dst(:,:,2), [5, 5]);result2(:,:,3) = medfilt2(dst(:,:,3), [5, 5]);figure;imshow(result2); title('中值滤波');% 进行二维排序滤波, 一次只能进行一个通道;result3(:,:,1) = ordfilt2(dst(:,:,1),15,true(5));result3(:,:,2) = ordfilt2(dst(:,:,2),15,true(5));result3(:,:,3) = ordfilt2(dst(:,:,3),15,true(5));figure;imshow(result3); title('二维排序滤波');% 进行自适应滤波, 一次只能进行一个通道;result4(:,:,1) = wiener2(dst(:,:,1), [5,5]);result4(:,:,2) = wiener2(dst(:,:,2), [5,5]);result4(:,:,3) = wiener2(dst(:,:,3), [5,5]);figure;imshow(result4); title('自适应滤波');
opencv在滤波器方面做得不错,可以直接放彩色图像,不用像MATLAB一样还需要设置通道。在滤波器上,OpenCV和MATLAB各自有一些独占滤波器,比如OpenCV有双边滤波,非局部均值滤波等,MATLAB就没有。
#include #include using namespace cv;using namespace std;void gaussian_noise(Mat &image);Mat dst;int main(int argc, char** argv) { Mat img = imread("data/images/face1.jpg"); namedWindow("原图像