点、线、边缘检测

点的检测

我们可以使用空域的滤波器来检测孤立点

点检测的算法描述

  1. 设定阈值T,如T=32、64等,计算滤波值R
  2. 如果R值=0,说明当前检测点的灰度值与周围点相同
  3. 当R的值足够大时,说明该点的值与周围的点非常不同,是孤立点,通过阈值来检测孤立点

示例

线的检测

对哪个方向都线感兴趣,就用哪个方向的模版与图像做卷积,并进行二值化。

下面是几个模版的示例

比如我们对下面这张图像分别用上面的四种模版进行计算

1
2
3
4
5
分别计算:
R水平 = -6+30 = 24
R45度 = -14+14 = 0
R垂直 = -14+14 = 0
R135度 = -14 + 14 = 0

模版设计规则

  1. 可能大于3*3
  2. 模版系数和为0
  3. 感兴趣的方向的系数大

示例

下面是检测-45度角线的示例

边缘的检测

定义:两个具有相对不同灰度值特性的区域的边界线。在一幅图像中,边缘有方向和幅度两个特性。一般认为沿边缘走向的灰度变化较为平缓,而垂直边缘走向的灰度变化剧烈。即灰度梯度是指边缘的垂直方向

梯度算子

Roberts交叉梯度算子

Prewitt梯度算子

一个水平,一个垂直

Sobel算子

和Prewitt的区别在于系数不同,可以检测到边缘的存在

Sobel梯度算子的使用和分析

  1. 直接计算Gx、Gy可以检测到边的存在,以及从暗到亮,从亮到暗到变化
  2. 仅计算|Gx|,产生最强的响应式正交于x轴的边;|Gy|则是正交于y轴的边

三种算子的例子如下:

下面给出的是检测35度和135度的Prewitt和Sobel算子

Matlab实现方法

边缘检测函数edge

下面是一个例子

1
2
3
4
I = imread('building.tif');
BW = edge(I,'sobel',0.1,'horizontal');
subplot(1,2,1); imshow(I);
subplot(1,2,2); imshow(BW);

效果如下:

边缘检测示例

下面我们尝试对图片进行水平、垂直以及水平垂直叠加三种边缘检测操作

1
2
3
4
5
6
7
8
9
10
I = imread('building.tif');
I = im2double(I);
w = [-1,-2,-1;0,0,0;1,2,1];
I_h = abs(imfilter(I,w));
I_v = abs(imfilter(I,w'));
I_m = I_h+I_v;
subplot(2,2,1); imshow(I);
subplot(2,2,2); imshow(I_h);
subplot(2,2,3); imshow(I_v);
subplot(2,2,4); imshow(I_m);

在上面的基础上,我们在进行边缘检测之前先进行噪声处理,发现效果有明显的提升

1
2
3
4
5
6
7
8
9
10
11
12
I = imread('building.tif');
I = im2double(I);
t = fspecial('average',5);
I = imfilter(I,t);
w = [-1,-2,-1;0,0,0;1,2,1];
I_h = abs(imfilter(I,w));
I_v = abs(imfilter(I,w'));
I_m = I_h+I_v;
subplot(2,2,1); imshow(I);
subplot(2,2,2); imshow(I_h);
subplot(2,2,3); imshow(I_v);
subplot(2,2,4); imshow(I_m);

孤立点检测

孤立点检测可以通过图像和模版进行卷积操作来实现,然后再设置阈值,孤立点检测的个数可以通过控制阈值来控制

例子如下:

1
2
3
4
5
6
7
8
I = imread('lena-gray.tif');
w = [-1,-1,-1;-1,8,-1;-1,-1,-1];
G = imfilter(im2double(I),w);
T = 0.3;
J = abs(G)>T;
subplot(1,3,1); imshow(I);
subplot(1,3,2); imshow(G,[]);
subplot(1,3,3); imshow(J);

线检测

下面是实现135度模版的线检测

1
2
3
4
5
6
7
8
9
I = imread('wirebond_mask.tif');
w = [2,-1,-1;-1,2,-1;-1,-1,2];
G = imfilter(im2double(I),w);
T = max(G(:));
J = abs(G);
J=J>=T;
subplot(1,3,1); imshow(I);
subplot(1,3,2); imshow(G,[]);
subplot(1,3,3); imshow(J);

实现135度和45度sobel模版的边缘检测

函数只能实现水平和边缘检测,我们这里只能通过和模版卷积实现,下面是135度

1
2
3
4
5
6
7
8
9
I = imread('building.tif');
w = [0,1,2;-1,0,1;-2,-1,0];
G = imfilter(im2double(I),w);
T = max(G(:));
J = abs(G);
J = J>=0.2*T;
subplot(1,3,1); imshow(I);
subplot(1,3,2); imshow(G,[]);
subplot(1,3,3); imshow(J);

下面是45度

1
2
3
4
5
6
7
8
9
I = imread('building.tif');
w = [-2,-1,0;-1,0,1;0,1,2];
G = imfilter(im2double(I),w);
T = max(G(:));
J = abs(G);
J = J>=0.2*T;
subplot(1,3,1); imshow(I);
subplot(1,3,2); imshow(G,[]);
subplot(1,3,3); imshow(J);

对比Sobel,Log和prewitt的边缘检测结果

1
2
3
4
5
6
7
I = im2double(imread('building.tif'));
g_sobel = edge(I,'sobel');
g_log = edge(I,'log');
g_prewitt = edge(I,'prewitt');
subplot(1,3,1); imshow(g_sobel);
subplot(1,3,2); imshow(g_log);
subplot(1,3,3); imshow(g_prewitt);

实现135度和45度prewitt模版的边缘检测

下面是135度prewitt模版

1
2
3
4
5
6
7
8
9
I = imread('building.tif');
w = [0,1,1;-1,0,1;-1,-1,0];
G = imfilter(im2double(I),w);
T = max(G(:));
J = abs(G);
J = J>=0.2*T;
subplot(1,3,1); imshow(I);
subplot(1,3,2); imshow(G,[]);
subplot(1,3,3); imshow(J);

下面是45度prewitt模版

1
2
3
4
5
6
7
8
9
I = imread('building.tif');
w = [-1,-1,0;-1,0,1;0,1,1];
G = imfilter(im2double(I),w);
T = max(G(:));
J = abs(G);
J = J>=0.2*T;
subplot(1,3,1); imshow(I);
subplot(1,3,2); imshow(G,[]);
subplot(1,3,3); imshow(J);

不同阈值条件下如图

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
I = imread('building.tif');
w = [-1,-1,0;-1,0,1;0,1,1];
G = imfilter(im2double(I),w);
T = max(G(:));
J = abs(G);
J1 = J>=0.1*T;
J2 = J>=0.2*T;
J3 = J>=0.3*T;
J4 = J>=0.4*T;
J5 = J>=0.5*T;
subplot(2,3,1); imshow(I);
subplot(2,3,2); imshow(J1);
subplot(2,3,3); imshow(J2);
subplot(2,3,4); imshow(J3);
subplot(2,3,5); imshow(J4);
subplot(2,3,6); imshow(J5);

Author: YihangBao
Link: https://roarboil.github.io/2020/06/11/pointlineedge/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.