Reputation: 83
I am using MATLAB. I want to use canny method for edge detection. But I need the edges that are diagonal or the edges that are only on 40 to 50 degree angle. how can i do that?
Upvotes: 2
Views: 2391
Reputation: 4721
I've answered a similar question about how to use Matlab's edge
function to find oriented edges with Canny ( Orientational Canny Edge Detection ), but I also wanted to try out a custom implementation as suggested by Avijit.
Start with an image, I'll use a built in demo image.
A = im2double(rgb2gray(imread('peppers.png')));
Gaussian Filter
A_filter = imgaussfilt(A);
Sobel Edge Detection -- We can't use the built in implementation (edge(A_filter, 'Sobel')
), because we want the edge angles, not just the edge locations, so we implement our own operator.
a. Convolution to find oriented gradients
%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');
b. Calculate the angles
A_angle = arctan(A_vertical./A_horizontal);
At this step, we traditionally bin edges by orientation (0°, 45°, 90°, 135°), but since you only want diagonal edges between 40 and 50 degrees, we will retain those edges and discard the rest.
% 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;
Perform non-max suppression on the remaining edges -- This is the most difficult portion to adapt to different angles. To find the exact edge location, you compare two adjacent pixels: for 0° edges, compare east-west, for 45° south-west pixel to north-east pixel, for 90° compare north-south, and for 135° north-west pixel to south-east pixel.
Since your desired angle is close to 45°, I just used south-west, but if you wanted 10° to 20°, for example, you'd have to put some more thought into these comparisons.
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
Edge tracking with hysteresis -- Decide whether weak edge pixels are close enough (I use a 3x3 window) to strong edge pixels. If they are, include them in the edge. If not, they are noise; remove them.
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
Here are my results.
As you can see, discarding the other edge orientations has a very negative effect on the hysteresis step because fewer strong pixels are detected. Adjusting the high_threshold would help somewhat. Another option would be to do Steps 5 and 6 using all edge orientations, and then use the diagonal_map to extract the diagonal edges.
Upvotes: 0
Reputation: 2065
You need write canny edge detector's code by your own (you would get lots of implementation )in the internet. You would then be calculating the gradient magnitudes and gradient directions in the second step. There you need to filter out the angles and corresponding magnitudes.
Hope this helps you.
Upvotes: 2