Ask Your Question

Weird result while finding angle

asked 2012-07-10 11:52:57 -0600

Abid Rahman K gravatar image

updated 2020-09-29 03:01:47 -0600


I wanted to find the angle of a curve at every pixel. For that, I applied canny edge detection. For test image, i took a filled rectangle. So obviously, canny edge result is just a rectangle.

Then i applied Sobel derivative in x and y direction and to find the angle, i took arctan(dy/dx). ( dx = dx+0.001 to avoid divide by zero)

For vertical side, i got an angle of 0 which is true since dy=0 in vertical direction and dx is some high value.

But for horizontal side also, i got zero. I don't understand why. When i took its corresponding dx,dy values, dx = 0.001... and dy = 0. Isn't it wrong to get dy = 0 on the horizontal side of the rectangle?

I checked the dy image, and it clearly shows the top and bottom sides of the rectangle. But still, why dy = 0 on that side?

Below is my dx image:

image description

My dy image:

image description

edit retag flag offensive close merge delete


You have a rectangle (I'm suppose it sides are parallel to coordinate axises), so one of angles must be 90 degrees (on vertical side) and the other is 0 (on horizontal side).

Daniil Osokin gravatar imageDaniil Osokin ( 2012-07-11 05:57:17 -0600 )edit

I know. But I get both as zero. that is my question. since equation is arctan(dy/dx), we should get 90 for horizontal sides. ( ie dy is high on horizontal side , and dx = 0 there, check out the images)

Abid Rahman K gravatar imageAbid Rahman K ( 2012-07-11 06:47:24 -0600 )edit

Could you explain, what is dx an dy image? Sobel gets an one input array and produces one output. Why you have two images?

Daniil Osokin gravatar imageDaniil Osokin ( 2012-07-11 07:17:55 -0600 )edit

dx is result i got while applying sobel in horizontal direction. and dy in vertical direction.

Abid Rahman K gravatar imageAbid Rahman K ( 2012-07-11 11:03:47 -0600 )edit

2 answers

Sort by ยป oldest newest most voted

answered 2012-07-20 13:34:26 -0600

Sobel uses the following kernel to compute y-derivative:

-1 -2 -1
 0  0  0
 1  2  1

So if you have a 1-pixel wide horizontal line from Canny edges then it will be taken with zero weight in Sobel. That is why dy = 0 on this line.

Try to run the Sobel operator on the original image instead of Canny edges and you should get correct results.

edit flag offensive delete link more


yeah. I already found it and did as you mentioned and it worked. So I was about to answer my own question. But before that, you answered it . Anyway thanks!!!

Abid Rahman K gravatar imageAbid Rahman K ( 2012-07-21 01:39:19 -0600 )edit

answered 2012-07-18 10:42:00 -0600

blue gravatar image

I'm not sure I understand the question, but here is a an example which might help you. Usually when I have an nonsense numerical result as you describe, it is due to a data type error. For example, if you are somehow casting to an integer before dividing or passing to arctan the fractional part would be discarded resulting in a zero angle.

#!/usr/bin/env python
import cv2, cv                                                                   
import numpy as np                                                               

# draw a rectangle                                                               
image = np.zeros((100,100), dtype='f4')                                          
image[25:75,30:70] = 50                                                          

# take the x and y sobel derivative                                              
dx = cv2.Sobel(image, -1, 1, 0)                                                  
dy = cv2.Sobel(image, -1, 0, 1)                                                  

# display the results with nice scaling                                          
cv2.imshow("original", image)                                                    
cv2.imshow("dx", cv2.convertScaleAbs(dx, None, 1./2, 100))                       
cv2.imshow("dy", cv2.convertScaleAbs(dy, None, 1./2, 100))                       

# convert dx, dy to magnitude and angle                                          
# angle is in radians                                                            
mag, theta = cv2.cartToPolar(dx, dy)                                             

# display in HSV so angle has a simple mapping                                   
theta_hsv = np.zeros((100,100,3), dtype='f4')                                    
# Hue is angle in degrees                                                        
theta_hsv[...,0] = np.degrees(theta)                                             
# S and V are 1.0                                                                
theta_hsv[...,1:] = 1.0                                                          
# Perform the colorspace conversion                                              
# Note that you need to import the old                                           
# cv modlue to get the conversion constants                                      
theta_bgr = cv2.cvtColor(theta_hsv, cv.CV_HSV2BGR)                               

# and show the angles                                                            
cv2.imshow("theta", theta_bgr)                                                   

# press 'q' to exit                                                              
while cv2.waitKey(10) != ord('q'):                                               
edit flag offensive delete link more

Question Tools


Asked: 2012-07-10 11:52:57 -0600

Seen: 2,888 times

Last updated: Jul 20 '12