【问题标题】:How can I improve my sobel operator edge detection?如何改进我的 sobel 算子边缘检测?
【发布时间】:2014-10-17 14:49:03
【问题描述】:

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

这是我测试过的图片:

这是结果:

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

【问题讨论】:

  • 一方面,edges 是一个 double 数组。当您尝试在 MATLAB 中显示图像时,它假定 double 图像中的动态范围在 [0,1] 之间。任何低于0 或超过1 的值分别饱和到01。这可能解释了为什么您的图像看起来如此褪色。因此,尝试执行edges = im2double(mat2gray(edges)); 以便在[0,1] 之间对值进行标准化,然后看看会发生什么。或者,您可以使用imshow(edges,[]); 来显示标准化的图像。请记住,这不会修改图像 - 它只会改变图像的显示方式。

标签: matlab image-processing computer-vision sobel


【解决方案1】:

你的内核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

【讨论】:

    【解决方案2】:

    结果优先

    内核中有1个错字

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

    2 使用卷积快速调试

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

    3 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');
    

    【讨论】:

      猜你喜欢
      • 2016-10-03
      • 2021-06-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-12-12
      • 1970-01-01
      • 2011-02-25
      • 1970-01-01
      相关资源
      最近更新 更多