前言

本系列文章为学校课程《数字图像处理》布置的一些小project作业

除了给出每个问题的解答和代码,我也会附上相关知识点,以方便后续复习

前置概念

信号频率与噪声

一个信号通常是由低频和高频部分组成

低频组成部分:平滑或逐段平滑的区域,邻近像素亮度值相似。

高频组成部分:震荡性强的区域,邻近像素亮度值不同,通常在边缘或噪声点处。

下面是一个明显的例子

image-20231112142919890

那么我们已经知道高频信号经常是图片中的噪声,也就顺理成章地能想到一种去噪方法

那就是将图像中噪声集中的频率过滤掉

image-20231112145659608

深入研究去噪方法前,我们先来了解有哪些常见的噪声

  1. 盐和胡椒噪声(Salt-and-Pepper Noise)
    • 特点:这种噪声呈现为图像中随机分布的黑白像素点。
    • 产生原因:通常由图像传感器、传输错误或由于数据损坏等原因引起。
    • 表现:图像中出现的黑点(”胡椒”)和白点(”盐”)。
  2. 脉冲噪声(Impulse Noise)
    • 特点:类似于盐和胡椒噪声,但通常只包括单一色彩的像素点(通常是白色)。
    • 产生原因:可能由图像传感器的故障、传输过程中的错误或其他技术问题导致。
    • 表现:图像中随机分布的明亮像素点。
  3. 高斯噪声(Gaussian Noise)
    • 特点:这种噪声的幅度遵循高斯分布(正态分布),即噪声值的分布呈钟形曲线。
    • 产生原因:可以由多种原因产生,包括传感器噪声、电子电路噪声、热噪声等。
    • 表现:在整个图像中平均分布,通常看起来像是图像的粒状或轻微模糊。

空域滤波

数字图像处理中的滤波是一种用于增强、恢复、平滑或检测图像中的特定特征的技术。

它的思想是利用四周的像素点信息,即将像素点的值替换为该像素及其领域的函数值

主要用途有以下几个方面:

  1. 去噪声:图像通常会因为各种原因(如传感器缺陷、传输错误等)含有噪声。滤波器可以帮助去除或减少这些噪声。
  2. 锐化和边缘增强:滤波可以用来增强图像中的边缘,从而使图像看起来更清晰。
  3. 平滑和模糊:通过滤波可以对图像进行平滑处理,这在去除噪声或降低图像细节方面非常有用。
  4. 特征提取:特定类型的滤波器能够帮助识别图像中的某些特征,如直线、圆形等。
  5. 检测图像:例如模板匹配

滤波器可以是线性的,也可以是非线性的。线性滤波器包括高通滤波器、低通滤波器、带通滤波器等,常见的如高斯滤波器、均值滤波器。非线性滤波器则包括中值滤波器、双边滤波器等。不同的滤波器有着不同的用途和效果。

线性滤波

滤波值是相邻像素值的线性组合,具有线性和移位不变性的特点

线性:$filter(f+g)=filter(f)+filter(g)$

移位不变性:滤波器对输入的移位保持不变,$filter(shift(f)) = shift(filter(f))$

我们可以从一个最简单的滤波入手,即均值滤波

在均值滤波中,每个样本(即四周的像素点)都有相同的权重

那么事实上,我们可以把卷积看作一个移动加权均值滤波

其中权值序列$a[j]$也可以叫做滤波器

当然在运算时,线性滤波还有一些属性

  • 交换律(Commutative):$a b = b a$,这表示线性滤波器可以与信号以任意顺序结合,而不会影响最终结果。在图像处理中,这意味着不管是先对图像进行滤波还是先考虑图像中的某个特定区域,其结果是相同的。
  • 结合律(Associative):$a (b + c) = (a b) + (a * c)$,这表明多个线性滤波器可以串联使用,它们的组合效果与应用单个综合滤波器的效果是等同的。例如,如果有三个不同的滤波器要应用于图像,你可以先计算这三个滤波器的组合,然后将其应用于图像,这与依次应用每个滤波器的结果相同。
  • 分配律(Distributive over addition):$a (b + c) = (a b) + (a * c)$,这意味着如果你有两个图像或信号需要合并,你可以先对每个图像独立进行滤波,然后再将它们相加,这与将这两个图像首先相加,然后对结果图像进行滤波,得到的结果是一样的。
  • 标量因子(Scalars factor out):$k \cdot (a b) = (k \cdot a) b = a * (k \cdot b)$,在滤波操作中,可以提前将标量(即常数因子)与滤波器或信号相乘,或者在滤波操作后再乘以标量,最终结果不会改变。
  • 恒等元素(Identity):$a * e = a \quad \text{where} \quad e = [\ldots, 0, 0, 1, 0, 0, \ldots]$,在线性滤波的上下文中,单位脉冲(一个中心为1,其他地方为0的滤波器)不会改变图像,这意味着图像经过这样的滤波器后保持不变

常见滤波器

  1. 方框滤波器:简单且便宜的低通滤波器。

    image-20231112164537351

  2. 帐篷滤波器:线性插值。

    image-20231112164551705

  3. 高斯滤波器:非常平滑的抗锯齿低通滤波器。

    image-20231112164601168

相关滤波

以上描述都是基于一维空间上的滤波,而对于图像处理,我们需要用到二维空间的滤波

在相关滤波中,滤波器也被称为模板(template)或核(kernel)

  1. 如果滤波器对称,即h(u,v)=h(-u,-v), 则卷积滤波和相关滤波等价
  2. 将相关滤波器h(u,v)按中心逆时针旋 转180度再作卷积,和相关滤波具有等价效果
  3. 使用卷积是为了应用有关频域处理卷积定理

相关滤波和卷积的公式区别如下

image-20231113110005836

在相关匹配时,一定要归一化,否则可能出现错误结果

模板匹配

相关滤波的一种应用是模板匹配

模板匹配是一种在整个图像中寻找与给定子图像(称为“模板”或“目标”)匹配的区域的技术。这个过程涉及在目标图像上滑动模板图像,并在每个位置计算模板图像和它覆盖的目标图像区域之间的相似度。模板匹配广泛应用于机器视觉和图像处理领域,用于定位和识别对象、追踪移动物体、场景重建以及许多其他任务。

模板匹配通过将模板图像在大图像上滑动,并在每个位置计算两者之间的相关性,相似度最高的区域被认为是模板的匹配位置。

相关的计算是通过将图像元素和⼦模式图像元素联系起来获得的,将相关元素相乘后累加。我们完全可以将⼦图像w视为⼀个按⾏或按列存储的向量 ,将计算过程中被w覆盖的图像区域视为另⼀个按照同样的⽅式存储的向量 。这样一来,相关计算就成了向量之间的点积运算

两个向量的点积为:

其中,θ为向量$ \vec{a} $ 、 $ \vec{b} $ 之间的夹⻆。显然,当 $ \vec{a} $ 和 $ \vec{b} $ 具有完全相同的⽅向(平⾏)时,cosθ=1,从⽽式子取得其最⼤值 ,这就意味着当图像的局部区域类似于⼦图像模式时,相关运算产⽣最⼤的响应。然⽽,公式最终的取值还与向量 $\vec{a} $ 、 $ \vec{b} $ ⾃⾝的模有关,这将导致按照公式计算的相关响应存在着对f和w的灰度幅值⽐较敏感的缺陷。这样⼀来,在f的⾼灰度区域,可能尽管其内容与⼦图像w的内容并不相近,但由于 $ \left| {\vec{a}} \right| $⾃⾝较⼤⽽同样产⽣⼀个很⾼的响应。可通过对向量以其模值来归⼀化从⽽解决这⼀问题,即通过$\frac{\vec{a} \cdot \vec{b}}{|\vec{a}| |\vec{b}|}$来计算相关。

高斯低通滤波

高斯滤波的思想是让相邻像素点对函数值有更大的影响

image-20231113103406936

高斯函数是一个非常重要的平滑函数,它在二维空间中的形式是:

这里的 $x$ 和 $y$代表了离中心像素的距离,$σ$ 是控制“钟形”曲线宽度的标准差。

其效果是让图片变得更加平滑

高斯低通滤波器的一个关键参数是标准差 $σ$。当 $σ$较小时,高斯核的宽度较小,滤波效果较弱,保留了更多的高频信息(即细节)。相反,当 $σ$较大时,高斯核的宽度较大,滤波效果较强,从而产生更强的模糊效果。

下面是不同标准差下产生的效果

image-20231113103832776

锐化

锐化的滤波器核为一个冲激I 减去一个平滑滤波器g

image-20231113110353224

效果如下

image-20231113110427951

非线性滤波

中值滤波

中值滤波会选取滑动窗口中的中间值作为函数结果

相比于高斯低通滤波,中值滤波有对异常值的稳健性,同时也具有边缘保护功能

image-20231113110755683

当然,它还有一个特点,即非线性

一个通用定义为在领域p中选取中间值

image-20231113111108890

当我们想要对彩色图像进行中值滤波时,可以考虑向量中值滤波

向量中值滤波算法:

设$X_1,X_2,\ldots,X_N \in \mathbb{R}^k$是对应滤波器窗口的输入向量,计算每个向量$x_i$到其他向量的距离和:

其中$| \cdot |_L$为 1-或者 2-范数,寻找 $s(X_i)$的最小值,并作为向量中值滤波的输出

HW1 模板匹配

作业要求:

给定图像car.png和模版图像wheel.png,利用相关检测实现对car图像中的wheel检测,具有最大相关值的位置可以解释为所检测到的wheel位置。程序的输入是图像和模版,要求:

(i)显示图像的相关值结果;

(ii)列出在图像中检测到的所有目标的(x,y)坐标。

在模板匹配的算法上,我们选用互相关匹配(Normalized Cross Correlation,NCC)

它的一个特点是在光照方面受的影响比较小,所以当检测图像亮度和形状变化很大时还是能够匹配得到。

回顾PPT

image-20231112195938795

该公式为

事实上,我们可以将每个点的计算过程看作两个向量相乘

模板视为⼀个按⾏或按列存储的向量 $\vec{a}$,而计算过程中被w覆盖的图像区域视为另⼀个按照同样的⽅式存储的向量 $\vec{b}$

此时我们想要找到最大相关性,即计算$cos\theta =\frac{\vec{a} \cdot \vec{b}}{|\vec{a}| |\vec{b}|}$,寻找最大的$cos\theta$值

接下来开始实现算法

首先读取被匹配图像和模版图像,并获取尺寸

1
2
3
4
car_img = imread('car.png');
wheel_img = imread('wheel.png');
[carHeight, carWidth] = size(car_img);
[wheelHeight, wheelWidth] = size(wheel_img);

将原图像的四周扩展补充为白色

1
2
padded_img = padarray(car_img, [(wheelHeight - 1)/2, (wheelWidth - 1)/2], 'both');
corrMatrix = zeros(carHeight - wheelHeight + 1, carWidth - wheelWidth + 1);

计算相关性时,直接利用向量乘积

1
2
3
4
5
6
7
8
9
10
for i = 1:size(car_img, 1)
for j = 1:size(car_img, 2)
% 提取当前窗口
window = double(padded_img(i:i+wheelHeight-1, j:j+wheelWidth-1));
% 计算相关性
a = double(wheel_img(:));
b = window(:);
correlation_matrix(i, j) = (a' * b) / (norm(a) * norm(b));
end
end

需要注意的是,在最后需要除以向量的模norm来归一化

最后,将相关性矩阵以图像的形式输出,我们就得到了图像的相关值结果

1
2
3
figure, 
imshow(correlation_matrix, []),
title('Correlation Result');

CorrelationResult

可以看到,轮胎中心的白色非常明显,说明相关值很高

接下来我们框出这些轮胎,并输出它们的坐标

首先设置一个相关性阈值,找出超过该阈值的点

1
2
threshold = 0.9; 
[y, x] = find(correlation_matrix > threshold);

然后框出并展示匹配图像和坐标

值得注意的是,如果边缘存在高相关值点,很可能对原图求子图的索引会越界,所以我们选择将原图放在一个大的白色背景中

得到匹配结果如下

coordinatets

我们可以发现匹配结果会给出距离十分接近但其实同属一个轮胎的点

解决办法就是进行判断,选择其中相关值高的点

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
values = correlation_matrix(correlation_matrix > threshold); % 获取相关值

% 创建一个新的列表用于存储最终点
final_x = [];
final_y = [];

% 进行点之间的比较
for i = 1:length(x)
keep = true;
for j = 1:length(x)
if i ~= j
dist = sqrt((x(i) - x(j))^2 + (y(i) - y(j))^2);
if dist < max(wheelWidth, wheelHeight) && values(i) < values(j)
keep = false;
break;
end
end
end
if keep
final_x = [final_x x(i)];
final_y = [final_y y(i)];
end
end

% 使用final_x和final_y代替原来的x和y
x = final_x;
y = final_y;

这样进行一次判断后,匹配结果也变得正常,只是可能因为算法原因,还是无法识别最右边的轮胎

coordinatets

HW2 椒盐噪声与中值滤波

作业要求:

image-20231113112512939

原图sport car.pgm如下

image-20231113112604424

由于是灰度图,我们考虑使用普通的中值滤波算法,即寻找窗口内的中间值

首先我们需要产生随机的椒盐噪声

1
2
3
4
5
t1 = rand(size_of_image);
t2 = rand(size_of_image);

t1 = uint8(t1 * 255);
t2 = uint8(t2 * 255);

通过MATLAB中的rand()函数,我们可以生成0到1的随机矩阵,接着我们将其缩放到[0,255]的范围

接着我们在原图像上应用椒盐噪声

1
2
3
4
5
6
7
8
9
10
11
for x = 1:size(f0, 1)
for y = 1:size(f0, 2)
if f0(x,y) > t1(x,y)
f(x,y) = 255;
elseif f0(x,y) < t2(x,y)
f(x,y) = 0;
else
f(x,y) = f0(x,y);
end
end
end

接着使用中值滤波进行去噪

1
2
3
4
5
6
7
8
9
10
f1 = f; 
for i=2:size(f0, 1)-1
for j=2:size(f0, 2)-1
window = f(i-1:i+1,j-1:j+1);
window = window(:);
s=sort(window); %对像素进行排序
f1(i,j) = s(floor(length(window)/2)+1); %选取中值
end
end
f1 = uint8(f1);

下面直接第哦啊有medfilt2函数生成f2

1
2
f2 = medfilt2(f, [3,3]);
f2 = uint8(f2);

最后我们将所有图像放在一起对比

result

可以看到中值滤波去噪的效果还不错,而我们自己实现的中值滤波与medfilt2基本一致