2016-12-07 146 views
2

我想用Canny方法检测边缘。最后我想要两个边缘地图:1代表水平1代表垂直方向。方向性Canny边缘检测

在MATLAB中,可以通过使用带有额外方向参数的Sobel或Prewitt运算符来实现,但对于Canny,我们没有这个选项。

E = edge(I,'Sobel','horizontal') 

任何想法如何通过使用Canny分别提取水平和垂直边缘?

+0

应该先阅读是如何工作的Canny边缘算法... Canny边缘检测是bidirectionnal,这是没有意义的提取水平或垂直边缘。 – obchardon

+0

[如何工作canny边缘检测](http://docs.opencv.org/2.4/doc/tutorials/imgproc/imgtrans/canny_detector/canny_detector.html#steps) – obchardon

+0

@obchardon从您提供的链接:“方向被四舍五入为四个可能的角度之一(即0,45,90或135)“所以我假设那些是垂直的,水平的,对角线左的,对角线的右边的。我只对垂直和水平感兴趣。 –

回答

2

有没有办法使用edge内置功能。但是,Canny边缘检测使用Sobel Operator的角度。重现这些值非常容易。

  1. 从图像开始,我将使用内置的演示图像。

    A = im2double(rgb2gray(imread('peppers.png'))); 
    
  2. 获取坎尼边缘

    A_canny = edge(A, 'Canny'); 
    
  3. Sobel算子 - 我们不能使用内置的实现(edge(A_filter, 'Sobel')),因为我们要的棱角,不只是边缘位置,所以我们实施自己的运营商。

    a。高斯滤波器。这是Canny的预处理步骤,所以我们应该在这里复制它

    A_filter = imgaussfilt(A); 
    

    b。卷积找到定向梯度

    %These filters measure the difference in values between vertically or horizontally adjacent pixels. 
    %Effectively, this finds vertical and horizontal gradients. 
    vertical_filter = [-1 0 1; -2 0 2; -1 0 1]; 
    horizontal_filter = [-1 -2 -1; 0 0 0; 1 2 1]; 
    A_vertical = conv2(A_filter, vertical_filter, 'same'); 
    A_horizontal = conv2(A_filter, horizontal_filter, 'same'); 
    

    c。计算角度

    A_angle = arctan(A_vertical./A_horizontal); 
    
  4. 在边缘位置获取的角度值

    A_canny_angles = nan(size(A)); 
    A_canny_angles(A_canny) = A_angle(A_canny); 
    
  5. 选择您感兴趣的

    angle_tolerance = 22.5/180*pi; 
    target_angle = 0; 
    A_target_angle = A_canny_angles >= target_angle*pi/180 - angle_tolerance & ... 
        A_canny_angles<= target_angle*pi/180 + angle_tolerance; 
    

所以,如果我的角度寻找水平线,我的目标角度将为零。下图显示了步骤1,2,4和5.提取的水平线的最终结果显示在右下角。你可以看到它们并不完全水平,因为我使用了这么大的角度容差窗口。这是一个可调参数,取决于您想要达到目标角度的准确程度。

Result

+0

对我来说看起来不错。谢谢! –