2

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

4

2 回答 2

2

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

希望这对您有所帮助。

于 2016-11-25T07:25:43.967 回答
0

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

Canny 边缘检测步骤

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

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

    A_filter = imgaussfilt(A);
    
  3. Sobel 边缘检测——我们不能使用内置的实现 ( 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
    

这是我的结果。

结果图片

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

于 2016-12-22T22:31:19.017 回答