我正在使用 MATLAB。我想使用精明的方法进行边缘检测。但我需要对角线的边缘或仅在 40 到 50 度角的边缘。我怎样才能做到这一点?
2 回答
您需要在互联网上自己编写精明的边缘检测器代码(您会得到很多实现)。然后,您将在第二步中计算梯度幅度和梯度方向。在那里,您需要过滤掉角度和相应的幅度。
希望这对您有所帮助。
我已经回答了一个类似的问题,关于如何使用 Matlab 的函数通过 Canny( Orientational Canny Edge Detectionedge
)查找定向边缘,但我也想尝试 Avijit 建议的自定义实现。
从图像开始,我将使用内置的演示图像。
A = im2double(rgb2gray(imread('peppers.png')));
高斯滤波器
A_filter = imgaussfilt(A);
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);
在这一步,我们传统上按方向(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;
对剩余的边缘执行非最大抑制——这是适应不同角度的最困难的部分。要找到准确的边缘位置,您需要比较两个相邻像素:对于 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
带有滞后的边缘跟踪——确定弱边缘像素是否足够接近(我使用 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,然后使用对角线图提取对角线边缘。