1

我正在尝试进入计算机视觉领域,首先我在 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; 

这是我测试过的图像:

这是结果:

我不知道从哪里开始,我已经尝试过细线或阈值,我应该采取哪些步骤来使这个运行更好?

4

2 回答 2

2

您在 y 方向上的内核似乎不正确,应该是

[ 1, 2, 1; 0, 0, 0; -1,-2,-1];

此外,如果您想改进边缘检测,您可以研究 Hysteresis,它是一种简单的方法来完成图像中一些可能被遗漏的明显轮廓

http://en.wikipedia.org/wiki/Canny_edge_detector#Tracing_edges_through_the_image_and_hysteresis_thresholding

于 2014-08-26T13:16:12.893 回答
2

结果第一

被索贝尔碾压后产生的猫

1 内核中的错字

正如Bharat Singh指出的那样,您的 y 内核看起来不对。(后来的分析表明它改变了结果,但这不是主要问题。)如果你愿意,你可以在我下面的代码中使用你原来的内核来看看结果是什么。(后人:)kernely(3,:) = [-1, 0, 1];基本上,它看起来像输入图像。

2 使用卷积使调试快速

在你做任何事情之前,只需使用 Matlab 提供的卷积函数。此外,为了加快速度,请使用conv2. 在您进行试验时,您可能希望使用parfor而不是外部for循环。卷积在我的机器上是瞬时的,parfor版本需要几分钟。

3imshow造成问题

有一个名为 的替代方法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');
于 2014-08-26T14:07:23.020 回答