使用canny方法在一定程度上进行边缘检测

时间:2016-11-25 05:55:59

标签: matlab image-processing edge-detection diagonal canny-operator

我正在使用MATLAB。我想使用canny方法进行边缘检测。但我需要对角线的边缘或仅40到50度角的边缘。我怎么能这样做?

2 个答案:

答案 0 :(得分:2)

你需要在互联网上自己编写canny边缘检测器的代码(你会得到很多实现)。然后,您将在第二步中计算梯度幅度和梯度方向。在那里你需要滤除角度和相应的大小。

希望这会对你有所帮助。

答案 1 :(得分:0)

我已经回答了一个类似的问题,关于如何使用Matlab的edge函数来找到Canny(Orientational Canny Edge Detection)的定向边,但我也想尝试Avijit建议的自定义实现。

Canny Edge Detection steps

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

    A = im2double(rgb2gray(imread('peppers.png')));
    
  2. 高斯滤波器

    A_filter = imgaussfilt(A);
    
  3. Sobel Edge Detection - 我们无法使用内置实现(edge(A_filter, 'Sobel')),因为我们需要边缘角度,而不仅仅是边缘位置,因此我们实现了自己的运算符。

    一个。卷积找到定向梯度

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

    湾计算角度

    A_angle = arctan(A_vertical./A_horizontal);
    
  4. 在此步骤中,我们传统上按方向(0°,45°,90°,135°)对边缘进行分类,但由于您只需要40到50度之间的对角线边缘,我们将保留这些边缘并丢弃其余的。

    % I lowered the thresholds to include more pixels
    % But for your original post, you would use 40 and 50
    lower_angle_threshold = 22.5; 
    upper_angle_threshold = 67.5;
    diagonal_map = zeros(size(A), 'logical');
    diagonal_map (A_angle>(lower_angle_threshold*pi/180) & A_angle<(upper_angle_threshold*pi/180)) = 1;
    
  5. 对剩余边缘执行非最大抑制 - 这是适应不同角度的最难部分。为了找到确切的边缘位置,比较两个相邻的像素:对于0°边缘,比较东西向,45°西南像素到东北像素,90°比较南北,和135°北 - 西像素到东南像素。

    由于您所需的角度接近45°,我只是使用了西南方向,但是如果您想要10°到20°,那么您必须更多地考虑这些比较。

    non_max = A_sobel;
    [n_rows, n_col] = size(A);
    %For every pixel
    for row = 2:n_rows-1
        for col = 2:n_col-1
            %If we are at a diagonal edge
            if(diagonal_map(row, col))
                %Compare north east and south west pixels
                if(A_sobel(row, col)<A_sobel(row-1, col-1) || ...
                        A_sobel(row, col)<A_sobel(row+1, col+1))
                    non_max(row, col) = 0;
                end
            else
                non_max(row, col) = 0;
            end
        end
    end
    
  6. 带滞后的边缘跟踪 - 确定弱边缘像素是否足够接近(我使用3x3窗口)到强边缘像素。如果是,请将它们包含在边缘。如果没有,它们就是噪音;删除它们。

    high_threshold = 0.5; %These thresholds are tunable parameters
    low_threshold = 0.01;
    
    weak_edge_pixels = non_max > low_threshold & non_max < high_threshold;
    strong_edge_pixels = non_max > high_threshold;
    
    final = strong_edge_pixels;
    for row = 2:n_rows-1
        for col = 2:n_col-1
           window = strong_edge_pixels(row-1:row+1, col-1:col+1);
           if(weak_edge_pixels(row, col) && any(window(:)))
               final(row, col) = 1;
           end
        end
    end
    
  7. 以下是我的结果。

    Result image

    如您所见,丢弃其他边缘方向对滞后步骤有非常不利的影响,因为检测到较少的强像素。调整high_threshold会有所帮助。另一种选择是使用所有边缘方向执行步骤5和6,然后使用diagonal_map提取对角线边缘。