点检测
点检测在MATLAB中可以用函数imfilter来实现
点检测方法
>> g = abs(imfilter(double(f), w)) >= T
其中f 是输入图像,w是一个合适的点检测掩模, g是结果图像
计算已滤波的图像,即abs(imfilter(double(f),w));
使用来自己滤波的图像的数据找到T的值
将已滤波的图像与T做比较
点检测举例
>> w = [-1 -1 -1;-1 8 -1; -1 -1 -1];
>> g = abs(imfilter(double(f), w));
>> T = max(g(:));
>> g = g>=T;
方法二
>>g = imsubstract(ordfilt2(f, m*n, ones(m, n)),ordfilt2(f, 1, ones(m, n)));
>> g = g >= T;
线检测
线检测中对指定方向的线更感兴趣,这种情况下可以与该方向相关的掩模并对其输出做出阈值处理。
检测指定方向的线
>> w = [2 -1 -1 ; -1 2 -1; -1 -1 2];
>> g = imfilter(double(f), w);
>> gtop = g(1:120, 1:120);
>> gtop = pixeldup(gtop, 4);
>> subplot(1,2,1);
>> gbot = g(end-119:end, end-119:end);
>> gbot = pixeldup(gbot, 4);
>> g = abs(g);
>> T = max(g(:));
>> g = g >= T;
b 图是对a 进行 −45. 检测器处理后的节刚过,下面两幅分别是它的左上角和右下角的放大图,e 是b 的绝对值 f 是满足条件 g>= T的所有点
函数pixeldup
pixeldup(m,n)————%pixeldup函数是将图像扩大m*n倍,通过复制每个像素点m*n次。
函数edge
边缘检测的基本意图是使用如下两个基本准则之一在图像中找到亮度快速变化的地方:
[g, t] = edge(f, 'method', parameters)
其中f 是输入图像 , method 是下表中的方法
输出中 g是一个逻辑数组 ,其值如下决定:
在f 中检测到边缘的位置为1, 在其他位置为 0
t 参数是可选的,它给出edge使用的阈值,以确定那个梯度值足够大到可以称为边缘点。
Sobel边缘检测器
[g, t] = edge(f, 'soble', T, dir)
Prewitt边缘检测器
[g, t] = edge(f, 'prewitt',T, dir)
Prewitt 检测器比Sobel 检测器在计算上简单一点,但是比较容易产生一些噪声
Roberts边缘检测器
该检测器是最古老的边缘检测器之一,它也是最简单的一种边缘检测器;经常用于硬件的实现,因为既简单又快速。
Laplacian of a Gaussian 检测器
[g, t] = edge(f, 'log', T, sigma)
其中sigma是标准偏差,默认值为2
零交叉检测器
该检测器基于与LOG方法相同的概念,但卷积是使用指定的滤波函数H执行的
[g, t] = edge(f, 'zerocross',T, H)
Canny边缘检测器
该检测器是使用函数edge的最有效边缘检测器
[g, t] = edge(f, 'canny', T, sigma)
>> [gv, t] = edge(f,'sobel','vertical');
>> gv = edge(f, 'sobel', 0.15, 'vertical');
>> gboth = edge(f, 'sobel', 0.15);
>> w45 = [-2 -1 0;-1 0 1; 0 1 2]
>> g45 = imfilter(double(f), w45, 'replicate');
>> T = 0.3 * max(abs(g45(:)));
>> g45 = g45 >= T;
>> f45= [0 1 2;-1 0 1;-2 -1 0]
>> h45= imfilter(double(f), f45,'replicate');
>> T = 0.3 * max(abs(h45(:)));
>> h45 = h45 >= T;
a . 原图像
b .使用带有自动确定的阈值的一个垂直Sobel 掩模后, 函数edge导致的结果
c .使用指定阈值后的结果
d .使用指定阈值来决定垂直边缘和水平边缘的结果
e .使用函数imfilter 计算 45° 边缘的结果
f . 使用函数imfilter 计算 -45° 边缘的结果
Sobel、LOG和Canny 边缘检测器的比较
>> [g_sobel_default, ts] = edge(f, 'sobel');
>> [g_log_default, tlog] = edge(f, 'log');
>> [g_canny_default, tc] = edge(f, 'canny');
>> g_sobel_best = edge(f, 'sobel', 0.05);
>> g_log_best = edge(f, 'log', 0.003, 2.25);
>> g_canny_best = edge(f, 'canny', [0.04 0.10], 1.5);
左列: Sobel、LOG 和 Canny 边缘检测器使用默认选项产生的结果
右列:交互地显示原图像的主要特征,减少了无关的细节
综合所有,Canny 边缘检测器产生的最好结果
寻找并链接图像中线段的处理方式
函数sparse
给是一个矩阵,用函数sparse把他转换成稀疏矩阵
S = sparse(A)
更常用的方法:
S = sparse(r, c, s, m, n)
r 和 c 分别是我们希望转换为稀疏矩阵的矩阵中非零元素的行和列索引向量
S 是一个向量,它包含有相应于索引对(r, c) 的值
m n 是结果矩阵的行维数和列维数
给出任意一个稀疏矩阵,用full 函数来获得完整的矩阵
A = full(S)
使用hough变换做峰值检测
函数houghpeaks
解决上述所讲的问题
使用hough变换做先检测和链接
一旦hough变换中识别出了一组候选的峰被,则他们还要留待确定是否存在与这些峰值相关的线段以及它们的起始和结束为止。对每一个峰值来说,第一步是找到图像中影响到峰值的每一个非零值点的位置。因此,编写了函数houghpixels
这里使用该函数来找到的位置相关的像素必须结合成线段,
函数houghlines采用下面的策略
使用hough变换做先检测和链接
[H, theta, rho] = hough(f, 0.5);
imshow(imadjust(mat2gray(H)),'XData',theta,'YData',rho,'InitialMagnification','fit'),axis on, axis normal
xlabel('\theta'),ylabel('\rho')
[r, c] = houghpeaks(H, 5);
hold on
plot(theta(c), rho(r), 'linestyle', 'none', 'marker', 's', 'color', 'w')
lines = houghlines(f, theta,rho,r,c)
figure, imshow(f),hold on
In images.internal.initSize (line 71)
In imshow (line 309)
for k = 1:length(lines)
xy = [lines(k).point1 ; lines(k).point2];
plot(xy(:, 2),xy(:,1),'LineWidth', 4, 'Color', [.6 .6 .6]);
end
T = 0.5*(double(min(f(:))) + double(max(f(:))));
done = false;
while~done
g = f >= T;
Tnext = 0.5*(mean(f(g))+mean(f(~g)));
done = abs(T - Tnext) < 0.5;
T = Tnext;
end
T2 = graythresh(f);
T2 * 255
bw = im2bw(f, T2);
局部阈值处理
全局阈值处理方法在背景照明不均匀时有可能失效,在这种情况下