Ask Your Question
3

How do the rho and theta values work in HoughLines?

asked 2012-10-07 20:12:56 -0600

ZachTM gravatar image

I have found some source code that finds lines in an image like I want and it uses the following HoughLines:

HoughLines( edges, lines, 1, CV_PI/180, 50, 0, 0 );

What I want to do is add the top, left, right, and bottom borders into the lines vector after Houghlines. From what I read in the documentation:

lines – The output vector of lines. Each line is represented by a two-element vector (rho, theta) . rho is the distance from the coordinate origin (0,0) (top-left corner of the image) and theta is the line rotation angle in radians

lines uses the rho and theta values to represent lines. And that the 1, and CV_PI/180 arguments are called rho and theta. So I did some research on this algorithm and found this diagram: image description

This looks like a good explanation of what im trying to understand but I still cant wrap my head around how to add the borders using the appropriate rho and theta values. Can somone explain this a little more so that I can possibly understand it? I would really appreciate it! Thanks.

edit retag flag offensive close merge delete

4 answers

Sort by » oldest newest most voted
3

answered 2012-10-08 04:11:19 -0600

elmiguelao gravatar image

updated 2012-10-08 04:13:21 -0600

The resulting rho and theta are indeed one step away from the line(s) you are looking for in the image. They represent a line passing through the origin that is perpendicular to the line you want to find. This page has a great introduction to Hough transform concepts, and explains this point.

You might want to use cvHoughLines2 instead, which will allow finding segments instead of lines and a couple of other improvements.

In this example you find some code to draw the lines from rho and theta; the idea is simple: calculate a point of that line, namely x0 = rho cos(theta), y0 = rho sin(theta), and notice that the slope of the line is (-theta), cos(-theta)=cos(theta), sin(-theta)=-sin(theta), and the very large numbers are there to use integer arithmetic.

for( size_t i = 0; i < lines.size(); i++ )
{
    float rho = lines[i][0];
    float theta = lines[i][1];
    double a = cos(theta), b = sin(theta);
    double x0 = a*rho, y0 = b*rho;
    Point pt1(cvRound(x0 + 1000*(-b)),
              cvRound(y0 + 1000*(a)));
    Point pt2(cvRound(x0 - 1000*(-b)),
              cvRound(y0 - 1000*(a)));
    line( color_dst, pt1, pt2, Scalar(0,0,255), 3, 8 );
}
edit flag offensive delete link more

Comments

Great resource it was very helpful. Thank you for your answer!

ZachTM gravatar imageZachTM ( 2012-10-08 08:48:10 -0600 )edit
0

answered 2017-09-08 12:23:02 -0600

paj006@gmail.com gravatar image

Rho is the size of the 'bucket' or accumulator array for all incoming rho, or distance from origin. The longest possible distance in an image is from the top left to bottom right, so for maximum accuracy, plug that value into houghlines rho.

Theta is the size of the bucket for all incoming theta. For maximum accuracy you need a value of 180. To only detect even angles, theta should be 90. to only detect angles divisible by 30, theta should be 6

edit flag offensive delete link more
0

answered 2019-03-11 10:46:04 -0600

twasnow gravatar image

I hate this method for finding points it doesn't take in to account the size of the image. And makes obvious translations way harder.

Instead I recommend solving for X given Y or Y given X

Y = (rho - aX)/b

X= (rho - bX)/a

(Where a = cos(theta) and b = sin(theta)

Now just sub in the intersects you want to find

[fX(Y=0), fY(X=0) | fX(Y=image height), fY(X=image width)]

Better yet let's say you need to know where the line crosses in the middle of the screen. Now you have the formula.

edit flag offensive delete link more
0

answered 2020-04-30 19:30:45 -0600

imgL = cv.imread('left_image_path',0)  
imgR = cv.imread('right_image_path',0)

stereo = cv.StereoBM_create(numDisparities=32, blockSize=15)
disparity = stereo.compute(imgL,imgR)

vdisp = np.zeros((disparity.shape[0],np.amax(disparity)))

for x in range(0, disparity.shape[0]):
    for y in range(0, disparity.shape[1]):
        if disparity[x, y] > 0:
            vdisp[x, disparity[x,y]-1] += 1

edges = cv.Canny(vdisp.astype(np.uint8),0,10,apertureSize = 3)
lines = cv.HoughLines(edges, 10, np.pi/90, 100)

for rho,theta in lines[0]:
    a = np.cos(theta)
    b = np.sin(theta)
    y1 = int(rho/b)
    x1 = int(rho/a)
    y2 = int((rho - (a*lines.shape[1]) )/b)
    x2 = int((rho - (b*lines.shape[0]) )/a)    
    cv.line(lines,(x1,y1),(x2,y2),(255,0,0),1)

This seems to be working.

edit flag offensive delete link more

Question Tools

Stats

Asked: 2012-10-07 20:12:56 -0600

Seen: 20,743 times

Last updated: Mar 11 '19