数字图像之边缘检测(1)
2019-04-13 15:22发布
生成海报
图像梯度法
1、图像梯度
对于图像函数 f(x,y) ,它在点 (x,y) 处的梯度是一个矢量,定义为
梯度的重要性质是:
(1)最大变化率方向:函数 f(x,y) 在梯度方向变化率最大。
(2)最大变化率:梯度的末就是 f(x,y) 在其最大变化率方向上的单位距离所增加的量。梯度的模用 G[f(x,y)] 表示,
对于数字图像而言,上式可以差分近似为
可进一步简化为(水平垂直差分法):
也就是如图所以求图中两个箭头所指之点的差的绝对值和
还有一种简化方法是罗伯特梯度法(交叉差分计算法)。
2、代码实现
代码中对边界一行和一列的各像素梯度无法求得,就用前后一行和前后前一列的梯度值近似代替。在实际运行过程中发现,如果只是将梯度值全部用右下两个点与中点的差值值简化,样图中有一条45°的边无法检测出来,而如果同时也检测左上两个点与中点的差值,则可以检测出来,下面的图将会展示两种结果。左图是只考虑右下,右图是同时考虑右下和左上。
代码如下:(贴代码的时候想了一下,单纯地将图像边界点的梯度考虑为0是否真的正确,还是按照经典的套路取前后一行和前后一列为好;而且好像算法的效率也不高,在我的电脑上计算 512 * 512 的图像是平均用时约为 2s ,计算的过程应该还可以优化的,如果有时间再找找资料。)
%% 锐化空间滤波器 微分梯度法 使用水平垂直差分法进行简化计算
% 作者:杨宇东
% 日期:2014.09.28
% 参数:待均衡化的图片的文件名
% 输出:均衡化处理之后的图片数组
%%
function newImg = EdgeDetectionXY(imgFile)
% 设置的阈值
threshold = 10;
im = imread(imgFile);
[nHeight, nWidth, nDim] = size(im);
if nDim == 3
imGray = rgb2gray(im);
end
newImg = zeros(nHeight, nWidth);
% 边界处外面的取值为边界的值
for i = 1:nHeight
for j = 1:nWidth
if i == nHeight || j == nWidth
g = 0;
else
if i == 1 || j == 1
g = 0;
else
% 如果只对右边和下边处理,则 45° 的边界检测不出来,通过这两个判断,可以将横向和纵向的边界比较好地找出来
g1 = abs(imGray(i, j) - imGray(i + 1, j)) + abs(imGray(i, j) - imGray(i ,j + 1));
g2 = abs(imGray(i, j) - imGray(i - 1, j)) + abs(imGray(i, j) - imGray(i, j - 1));
% 这个是只对右下与中点的差值处理
% g = abs(imGray(i, j) - imGray(i + 1, j)) + abs(imGray(i, j) - imGray(i ,j + 1));
if g1 >= g2
g = g1;
else
g = g2;
end
end
end
if g > threshold
newImg(i, j) = 0;
else
newImg(i, j) = 255;
end
end
end
figure(1);
subplot(2, 1, 1),imshow(imGray);
subplot(2, 1, 2),imshow(newImg);
最后,我发现边缘检测就是很多软件中好像很高端的素描效果的算法原型了吧。
打开微信“扫一扫”,打开网页后点击屏幕右上角分享按钮