噪音、过滤器与边缘检测(我的「计算机视觉」学习)

图像处理中有一个很重要的任务就是降低图像的噪音,噪音有很多种类型,一种常见的是斑点噪音(speckling),专业名称叫做:Additive white Gaussian noise (AWGN)。

speckling

上图左边即所谓的高斯噪音,减少噪音可以对相同的景象拍很多张照片,比如1000张,然后将对应的像素点累加之后取平均值,因为高斯分布(正态分布)的均值为0,累加的照片越多噪音越小,这种方法常用在天文学。

average-images-to-reduce-noise

我个人理解:拍一张不清楚,我们就多拍几张,可能第1张眼睛那有噪点,没关系,其他的或许眼睛清楚,鼻子有噪点,以此类推,各取所长后平均一下就会比拍一张清楚。

这正好也说明这种高斯噪音是随机的,通过大量的照片来减少随机带来的噪音。

更常规的,我们往往只有一张图,就需要对每个像素点处理,针对单个像素点,它和周围的像素点总会有点相似关系,毕竟图片放大看像素点的颜色是慢慢渐变的:

gradual-change

如上,灰到黑是有个渐变的过程,专业点叫空间连贯性,所以常规操作就是累加周围的像素点后取平均作为新的像素点:

average-neighbouring-pixels

另一种方式是引入另外一个窗口?,将这个窗口与原始输入相乘取平均,

multiply-window

上面的过程就称为卷积

convolution convolution-1

过滤器

新的像素都是通过一些线性组合的方式生成,就叫线性过滤。上面提到的窗口也可以叫模版过滤器,具体的可以随便定义,会产生不一样的效果,比如:

没有变化 左移一个像素

过滤器分盒子过滤器(Box filter)高斯过滤器(Gaussian filter),盒子过滤器就是一些简单的数组成的矩阵,大概这样:

box-filter box-filter-graph

从图像上看,盒子过滤器是一个柱体,和周围比比较突兀。

而高斯过滤器就是经过高斯函数设计出来的一个矩阵(我也不是很懂呀),

gaussian-filter

从图像看是一个平滑的曲面,看起来就比较舒服。

我自己瞎写的 😂

两者在卷积效果上的对比如下:

box-filter-vs-gaussian-filter

虽然两者都很模糊,但盒子过滤器有明显的颗粒感,就像一张放大的图片,高斯就很平滑了,就像没戴眼镜的近视。

边缘检测

什么是边缘呢?就是图像中像素的强度的不连续导致边缘出现,夸张点可以看下面这张图:

edge

如果对图像信号求一个偏导,就能明显知道边缘:

partial-derivative

图像可以看作是一个信号函数,通过求导可以知道图像灰度的变化,这里求导即为梯度,因为图像是二维离散函数,分别对x和y求偏导就能知道在水平方向和垂直方向的灰度变化。

垂直、水平、对角线梯度

上图分别是垂直梯度,水平梯度和对角线梯度。

上图例子中,如果如果X方向上像素灰度值有变化,就能计算出梯度,如果灰度没有变化,梯度就是0,将梯度值与原像素相加,可以看到新的像素在X方向差距变大,由原来的10变成20,说明对比度明显增加,就更能区分物体的轮廓与背景。还可以用坐标轴来解释:

gradient-and-axis

不同的梯度变化可以体现在点到原点的距离,距离越远,梯度越大,灰度变化越明显,反之越不明显,距离用幅度(magnitude)来表示,公式为:

magnitude-formula

梯度的方向:

gradient-direction

一些经典的图像梯度算法是考虑图像的每个像素的某个邻域内的灰度变化,利用边缘临近的一阶或二阶导数变化规律,对原始图像中像素某个邻域设置梯度算子,通常我们用小区域模板进行卷积来计算,有Sobel算子、Robinson算子、Laplace算子等。

(copy来的)算子也可以叫过滤器吧?

索贝尔算子(Sobel Operator)

在图像处理中Sobel用的很多,它有个好处是能在检测边缘之前稍微地平滑图像,具体的矩阵如下:

sobel-operator

怎么处理图片呢?我这里写了一个例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
function [img, imgGradX, imgGradY, imgGrad] = sobel(imgPath)
Gx=[1 2 1;
0 0 0;
-1 -2 -1];

Gy=[-1 0 1;
-2 0 2;
-1 0 1];

set(gcf,'Position',[300 300 800 800])

imgOrg = imread(imgPath);
img = rgb2gray(imgOrg);
subplot(2,2,1);
imshow(img);
title('原图');

imgGradX = conv2(Gx, img, 'full');
imgGradX = abs(imgGradX);
subplot(2,2,2);
imshow(imgGradX,[]);
title('sobel垂直梯度');

imgGradY = conv2(Gy, img, 'full');
imgGradY = abs(imgGradY);
subplot(2,2,3);
imshow(imgGradY,[]);
title('sobel水平梯度');

imgGrad = imgGradX + imgGradY;
subplot(2,2,4);
imshow(imgGrad,[]);
title('sobel梯度');
end
sobel-demo-1 sobel-demo-2

以上是我个人的学习笔记,部分截图来自于老师PPT,如有错误欢迎指正,如果有兴趣欢迎联系我一起学习,共同进步。

参考


欢迎阅读本篇文章,如有兴趣可以关注博主公众号哦: