我正试图进入计算机视觉领域,开始我在MATLAB中实现了一个Sobel滤波器,我在这里读到:http://en.wikipedia.org/wiki/Sobel_operator
以下是代码:
image = double(image);
kernelx = [ -1, 0, 1;
-2, 0, 2;
-1, 0, 1];
kernely = [ 1, 2, 1;
0, 0, 0;
-1, 0, 1];
height = size(image,1);
width = size(image,2);
channel = size(image,3);
for i = 2:height - 1
for j = 2:width - 1
for k = 1:channel
magx = 0;
magy = 0;
for a = 1:3
for b = 1:3
magx = magx + (kernelx(a, b) * image(i + a - 2, j + b - 2, k));
magy = magy + (kernely(a, b) * image(i + a - 2, j + b - 2, k));
end;
end;
edges(i,j,k) = sqrt(magx^2 + magy^2);
end;
end;
end;
这是我测试过的图像:
结果如下:
我不知道从哪里开始,我已经尝试过线条细化或阈值处理,我应该采取哪些措施让这次运行得更好?
答案 0 :(得分:2)
y方向的内核似乎不正确,应该是
[1,2,1; 0,0,0; -1,-2,-1];
此外,如果你想改进边缘检测,你可以看一下滞后,它是一种简单的方法来完成一些可能错过的图像中明显的轮廓
答案 1 :(得分:2)
正如Bharat Singh指出的那样,你的y-Kernel看起来不对。 (后来的分析显示它改变了结果,但这不是主要问题。)如果你想要,你可以在我下面的代码中使用原始内核来查看结果。 (对于子孙后代:kernely(3,:) = [-1, 0, 1];
)基本上,它看起来像输入图像。
在您做任何其他事情之前,只需使用Matlab提供的卷积功能。
另外,为了加快速度,请使用conv2
。在进行实验时,您可能希望使用parfor
而不是外部for
- 循环。卷积在我的机器上瞬间完成,parfor
版本需要几分钟。
imshow
导致问题还有一个名为imagesc
的替代方案,可以自动缩放图像。或者你可以致电imshow(image, [])
。但是在这种情况下的问题是每个通道看起来都正确但是Matlab自动混合通道不起作用。 (请记住它们不再是RGB,而更像是R通道衍生物| dR |的大小等)
通过单独查看每个结果通道(imshow(E(:,:,1), [])
)或欧几里德平均值(请参阅我的代码)来检查这一点。如果你运行imshow(E, [])
,你会得到惊人的亮点。如果您先通过rgb2gray
传递,也会发生同样的情况。
image = imread('cat.jpg');
image = double(image);
kernelx = [ -1, 0, 1;
-2, 0, 2;
-1, 0, 1];
kernely = [ 1, 2, 1;
0, 0, 0;
-1, -2, -1];
height = size(image,1);
width = size(image,2);
channel = size(image,3);
edges = zeros(height, width, channel);
if exist('chooseSlow', 'var')
parfor i = 2:height - 1
for j = 2:width - 1
for k = 1:channel
magx = 0;
magy = 0;
for a = 1:3
for b = 1:3
magx = magx + (kernelx(a, b) * image(i + a - 2, j + b - 2, k));
magy = magy + (kernely(a, b) * image(i + a - 2, j + b - 2, k));
end;
end;
edges(i,j,k) = sqrt(magx^2 + magy^2);
end;
end;
end;
end
%% Convolution approach
E = zeros(height, width, channel);
for k=1:channel
Magx = conv2(image(:,:,k), kernelx, 'same');
Magy = conv2(image(:,:,k), kernely, 'same');
E(:,:,k) = sqrt(Magx .^2 + Magy .^2);
end
imshow(sqrt(E(:,:,1).^2 + E(:,:,2).^2 + E(:, :, 3) .^2 ), []);
print('result.png', '-dpng');