# 定向Canny边缘检测 [英] Orientational Canny Edge Detection

### 问题描述

` ` E =边缘（我，'Sobel'，'水平'） ` `

I want to detect edges using Canny method. In the end I want two edge maps: 1 for horizontal 1 for vertical direction.

In MATLAB this can be achieved by using Sobel or Prewitt operators with an extra direction argument, but for Canny we do not have this option.

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

Any idea how to extract both horizontal and vertical edges, separately, by using Canny?

There is no way using the built in `edge` function. However, Canny edge detection uses the angles from the Sobel Operator. It is very easy to reproduce these values.

1. Start with an image, I'll use a built in demo image.

``````A = im2double(rgb2gray(imread('peppers.png')));
``````

2. Get the Canny edges

``````A_canny = edge(A, 'Canny');
``````

3. Sobel Operator -- 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. Gaussian filter. This is a preprocessing step for Canny, so we should probably reproduce it here

``````A_filter = imgaussfilt(A);
``````

b. 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');
``````

c. Calculate the angles

``````A_angle = arctan(A_vertical./A_horizontal);
``````

4. Get the angle values at the edge locations

``````A_canny_angles = nan(size(A));
A_canny_angles(A_canny) = A_angle(A_canny);
``````

5. Choose the angles that you are interested in

``````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;
``````

So if I'm looking for horizontal lines, my target angle would be zero. The image below illustrates steps 1, 2, 4 and 5. The final result of the extracted horizontal lines is shown in the bottom right. You can see that they are not exactly horizontal because I used such a large angle tolerance window. This is a tunable parameter depending on how exactly you want to hit your target angle.