# Weird result while finding angle

Hi

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:

My dy image:

edit retag 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).

( 2012-07-11 05:57:17 -0500 )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)

( 2012-07-11 06:47:24 -0500 )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?

( 2012-07-11 07:17:55 -0500 )edit

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

( 2012-07-11 11:03:47 -0500 )edit

Sort by » oldest newest most voted

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.

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!!!

( 2012-07-21 01:39:19 -0500 )edit

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
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'):
pass

more

Official site

GitHub

Wiki

Documentation