计算机视觉学习笔记8 噪声与滤波

//双边滤波imshow;waitKey{Matnoise=Mat:zeros,image.type,);//高斯噪声函数,噪声均值15,方差3

按老规矩,先给简要说明,然后上MATLAB,c++和Python的代码。

图像的噪声

不管是模拟信号还是数字信号,都难免会产生噪声,尤其是模拟信号,噪声处理一直是比较重要的环节,数字信号相对来说噪声会少一点。

图像噪声的产生原因很复杂,可能是成像设备或者环境本身导致成像质量不稳定,也可能是数字信号传输过程中发生丢失或者受到干扰,可以将噪声看成是一种无规律不可预测的随机误差。

噪声主要形式有:椒盐噪声(可能是黑白噪声的看着像椒盐,然后叫这名字吧);高斯噪声(服从高斯分布的噪声,一般在数码相机图像采集阶段会产生);泊松噪声(服从泊松分布的噪声)。

噪声的产生会严重影响图像质量,必须给予纠正。

MATLAB: imnoise(src,noise_name,size),通过设置不同噪声名字,可以添加高斯,椒盐,泊松噪声。
OpenCV: 没有专门添加噪声的函数,但是可以人为添加,见下文gaussian_noise()

常见的滤波方法

滤波也称为平滑模糊,是一种可以有效去除图像噪声的方法。下面简单分析一下几种常见滤波器的工作原理。图像卷积核一般推荐3×3, 5×5,通常不会超过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);
计算机视觉学习笔记8 噪声与滤波

3×3的滤波核,9个像素中值为23

  • 高斯滤波

高斯模糊考虑了中心像素距离的影响,通过像素距离中心的距离,使用高斯分布公式生成不同的权重系数,自动生成卷积核参数,然后进行图像卷积操作。

在MATLAB中,高斯滤波为: fspecial(‘gaussian’, size, sigma); 这是滤波函数,若把‘gaussian’换成中值,均值,也能实现其他滤波方式
在OpenCV中,高斯滤波为:GaussianBlur(src, dst, size);
  • 高斯双边滤波

和高斯滤波相比,还考虑了像素值分布对卷积输出的影响,对图像空间分布差异较大的值进行保留,因此高斯双边滤波是一种能保留边缘信息的滤波方式。运算量大,但是效果不错,看起来就跟美颜磨皮一样。

MATLAB好像没找到这个滤波方式,OpenCV调用api为: bilateralFilter()

MATLAB常见滤波方法

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('自适应滤波');
计算机视觉学习笔记8 噪声与滤波

原图像和噪声图像

计算机视觉学习笔记8 噪声与滤波

均值滤波好像只行了一个通道,效果有点差啊

计算机视觉学习笔记8 噪声与滤波

滤波效果都还行

c++常见滤波方法

opencv在滤波器方面做得不错,可以直接放彩色图像,不用像MATLAB一样还需要设置通道。在滤波器上,OpenCV和MATLAB各自有一些独占滤波器,比如OpenCV有双边滤波,非局部均值滤波等,MATLAB就没有。

#include <opencv2/opencv.hpp>
#include <iostream>
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("原图像", WINDOW_AUTOSIZE);
 imshow("原图像", img);
 gaussian_noise(img); // 添加高斯噪声
 imshow("添加高斯噪声", dst);

 Mat result1, result2, result3, result4, result5;
 blur(dst, result1, Size(5, 5)); // 均值滤波去噪声
 imshow("均值滤波", result1);

 GaussianBlur(dst, result2, Size(5, 5), 0); // 高斯滤波去噪声
 imshow("高斯滤波", result2);

 medianBlur(dst, result3, 5); // 中值滤波
 imshow("中值滤波", result3);

 fastNlMeansDenoisingColored(dst, result4, 10, 10, 7, 21); // 非局部均值去噪
 imshow("非局部均值滤波", result4); // 10 搜索窗口大小,30 模板窗口大小,一般设置为1:3比例

 bilateralFilter(dst, result5, 0, 100, 10, 4); // 双边滤波
 imshow("双边滤波", result5);

 waitKey(0);
 return 0;
}

void gaussian_noise(Mat &image) {
 Mat noise = Mat::zeros(image.size(), image.type());
 randn(noise, (15, 15, 15), (30, 30, 30)); // 高斯噪声函数,噪声均值15,方差30.
 add(image, noise, dst);
}
计算机视觉学习笔记8 噪声与滤波

添加了高数噪声

计算机视觉学习笔记8 噪声与滤波

手机端图像太小可能看不清效果

计算机视觉学习笔记8 噪声与滤波

非局部均值滤波磨皮效果不错吧

计算机视觉学习笔记8 噪声与滤波

双边滤波磨皮效果

后两种滤波方式据说在美颜上有不少应用,看起来美颜效果还是不错的。

Python常见滤波方法

Python和c++代码基本一样,也都有注释,总的来说还是比较简单

import cv2 as cv
import numpy as np

def gaussian_noise(image):
 noise = np.zeros(image.shape, image.dtype)
 m = (15, 15, 15)
 s = (30, 30, 30)
 cv.randn(noise, m, s)
 dst = cv.add(image, noise)
 cv.imshow("gaussian noise", dst)
 return dst

img = cv.imread("data/images/face1.jpg")
cv.imshow("input", img)
dst = gaussian_noise(img) # 添加高斯噪声

result1 = cv.blur(dst, (3, 3)) # 均值滤波去噪声
cv.imshow("blur", result1)

result2 = cv.GaussianBlur(dst, (3, 3), 0) # 高斯滤波去噪声
cv.imshow("GaussianBlur", result2)

result3 = cv.medianBlur(dst, 3) # 中值滤波
cv.imshow("medianBlur", result3)

result4 = cv.fastNlMeansDenoisingColored(dst, None, 10, 10, 7, 21) # 非局部均值去噪
cv.imshow("fastNlMeansDenoisingColored", result4)

result5 = cv.bilateralFilter(dst, 0, 100, 10) # 双边滤波
cv.imshow("bilateralFilter", result5)

cv.waitKey(0)
cv.destroyAllWindows()

因为都是调用OpenCV,所以效果图和c++一样

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/81619.html

(0)

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注

关注微信