Calculating mean angles of edge detection

Hello,
I'm a new user of Matlab and am looking to calculate the mean and median angles of an image after performing an edge detection. I am using the following edge detection script adapted from the MathWorks edge detection example code and am looking to take it a step further in order to calculate the mean and median angles of the edge detection for each image I input. I eventually am looking to change the code from a specific image to a moving window. Additionally, I'm curious whether it is possible to calculate the number of horizontal, vertical, and diagonal edges from the edge detection output?
Thank you!
clear
RGB=imread('DJI_0022.jpg'); %inputs image
I=rgb2gray(RGB); %convers to grayscale
figure
imshow(I)
%%
%https://www.mathworks.com/help/images/ref/edge.html
%two different types of edge detection
BW1 = edge(I,'Canny');
BW2 = edge(I,'Prewitt');
figure
imshowpair(BW1,BW2,'montage')
%%
%https://www.mathworks.com/matlabcentral/answers/8591-edge-direction
%vertical
BWv = imopen(BW1,[1 1 1]');
%horizontal:
BWh = imopen(BW1,[1 1 1]);
%top left to lower right
BWd = imopen(BW1,[1 0 0; 0 1 0; 0 0 1]);
%%
%plot results
figure
subplot(3,1,1)
imshow(BWv);
title('vertical')
subplot(3,1,2)
imshow(BWh);
title('horizontal')
subplot(3,1,3)
imshow(BWd);
title('diagonal')

3 Comments

This is the image I am currently using for reference!
  • I'm curious whether it is possible to calculate the number of horizontal, vertical, and diagonal edges from the edge detection output?
Yes. THe answer is yes. Use bwlabel
[L,n] = bwlabel(BWh,4); % '4' is connection
Little explanation:
I'd use 4 connected object for horizontal and vertical lines. And 8 connected object for diagonals
See more here: bwlabel
Thanks so much! I tried it out and bwlabel works great. Any ideas on how to calculate mean angles for each direction (horizontal, vertical, and diagonal)?

Sign in to comment.

 Accepted Answer

Try regionprops with orientation property
Example
BWd1 = 1.0*BWd;
data = regionprops(BWd,'orientation','pixelidxlist'); % get orientation and pixels list of each region
for i = 1:numel(data)
idx = data(i).PixelIdxList; % pixel indices of current region
ori = data(i).Orientation; % orintation of region
BWd1(idx) = ori; % assign angle value
end
imagesc(BWd1)
colorbar

15 Comments

Thank you! The orientation of the region is a neat calculation.Is the orientation calculating from 0-360 degrees? I did notice when I ran it for each of the horizontal (ori value of 0), vertical (ori value of 90), and diagonal images (ori value of -45) , which were more "standard" values than I might expect.
  • Is the orientation calculating from 0-360 degrees?
No. As you can notice it's -180 .. +180
  • I did notice when I ran it for each of the horizontal (ori value of 0), vertical (ori value of 90), and diagonal images (ori value of -45) , which were more "standard" values than I might expect.
Please see values of orientation
data(:).Orientation;
@darova- I have a belated follow-up question on this. In thinking about the goal a bit more, I think it makes more sense to gather all orientation values (i.e. the gradient of all horizontal values, the gradient of all vertical values, etc.) Is there a way to get all the orientation values as an output instead of just the mean orientation values?
Thanks!
I don't understand what you say
I = imread('im.png');
I1 = ~im2bw(I);
data = regionprops(I1,'orientation','centroid');
cent = cat(1,data.Centroid);
ori = cat(1,data.Orientation);
imshow(I1)
for i = 1:length(ori)
h = text(cent(i,1)+5,cent(i,2)+5,num2str(ori(i)));
set(h,'color','y')
end
Can you make a simple drawing of what the result you want to see? Here is my sketch
Absolutely. Your drawing is what I am trying to achieve. I have code that adds up the number of edges at each specified orientation (horizontal, vertical, left diagonal, right diagonal) and then calculates the mean angle of each orientation. What I would like is to modify my code to instead calculate EACH angle and report those values. Below is the code I have for average orientation from my binary edge detected image:
%vertical
BWv = imopen(BW1,[1 1 1]');
%horizontal:
BWh = imopen(BW1,[1 1 1]);
%top left to lower right
BWdleft = imopen(BW1,[1 0 0; 0 1 0; 0 0 1]);
%top right to lower left
BWdright = imopen(BW1,[0 0 1; 0 1 0; 1 0 0]);
%calculate horizontal # of edges
[H,Hnum] = bwlabel(BWh,4);
%calculate vertical # of edges
[V,Vnum] = bwlabel(BWv,4);
%calculate diagonal left # of edges
[DL,DLnum] = bwlabel(BWdleft,8);
%calculate diagonal right # of edges
[DR,DRnum] = bwlabel(BWdright,8);
%% Diagonal Left orientation
BWdl1 = 1.0*BWdleft;
% get orientation and pixels list of each region
data = regionprops(BWdleft,'orientation','pixelidxlist');
for i = 1:numel(data)
% pixel indices of current region
idxDL = data(i).PixelIdxList;
% orientation of region
oriDL = data(i).Orientation;
% assign angle value
BWdl1(idxDL) = oriDL;
end
imagesc(BWdl1)
colorbar
%% Vertical Orientation
BWv1 = 1.0*BWv;
data = regionprops(BWv,'orientation','pixelidxlist'); % get orientation and pixels list of each region
for i = 1:numel(data)
idxV = data(i).PixelIdxList; % pixel indices of current region
oriV = data(i).Orientation; % orintation of region
BWv1(idxV) = oriV; % assign angle value
end
imagesc(BWv1)
colorbar
%% Horizontal Orientation
BWh1 = 1.0*BWh;
data = regionprops(BWh,'orientation','pixelidxlist'); % get orientation and pixels list of each region
for i = 1:numel(data)
idxH = data(i).PixelIdxList; % pixel indices of current region
oriH = data(i).Orientation; % orintation of region
BWh1(idxH) = oriH; % assign angle value
end
imagesc(BWh1)
colorbar
%%
%% Diagonal Right orientation
BWdr1 = 1.0*BWdright;
data = regionprops(BWdright,'orientation','pixelidxlist'); % get orientation and pixels list of each region
for i = 1:numel(data)
idxDR = data(i).PixelIdxList; % pixel indices of current region
oriDR = data(i).Orientation; % orintation of region
BWdr1(idxDR) = oriDR; % assign angle value
end
imagesc(BWdr1)
colorbar
That's very close. Because my image has so many angles, I'm hoping to have the values in the workspace as a table rather than printed on the image. What are m and n in your script? I've attached my edge detection script with orientations for reference.
  • What are m and n in your script?
Please see this line
[m,n] = size(I2);
What should i do with your script?
Do you have any suggestions on how to get these angles to print as a table in the workspace instead of on the image?
print it like this
sprintf('angle: %4d; center = (%3d, %3d)\n',round([ori cent])')
Neat- that works great for printing! Thank you!
Do you know of any functions that convert the angles from -90 to 90 to 0 to 360 degrees?
Try wrapTo360
Thanks! I'll give that a try

Sign in to comment.

More Answers (1)

If you have the Computer Vision Toolbox, try extractHOGFeatures() to get the histogram of oriented gradients.

1 Comment

The extractHOGFeatures() tool is neat just from working throught the examples. Is there a way to clip the tool to a specific area of the image or train it so that it is only extratcting the HOG features for the area of interest. For example, in the image attached, I am interested in looking at the logs but not the vegetation and trees. Thank you!

Sign in to comment.

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!