首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何改进我的sobel算子边缘检测?

如何改进我的sobel算子边缘检测?
EN

Stack Overflow用户
提问于 2014-08-24 14:46:20
回答 2查看 1.7K关注 0票数 1

我正在尝试进入计算机视觉领域,首先我在MATLAB中实现了一个Sobel滤波器,我在这里读到了它:http://en.wikipedia.org/wiki/Sobel_operator

代码如下:

代码语言:javascript
复制
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; 

这是我测试过的一张图片:

这就是结果:

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

EN

回答 2

Stack Overflow用户

发布于 2014-08-26 21:16:13

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

1,2,1;0,0,0;-1,-2,-1;

此外,如果你想改进边缘检测,你可以查看滞后,这是一种简单的方法来完成图像中可能遗漏的一些明显的轮廓。

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

票数 2
EN

Stack Overflow用户

发布于 2014-08-26 22:07:23

结果优先

内核中的1个Typo

正如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传递它,也会发生同样的情况。

代码

代码语言:javascript
复制
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');
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25469203

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档