Ask Your Question

Draw the lines detected by cv::HoughLines

asked 2013-09-22 11:38:40 -0600

stereomatching gravatar image

updated 2013-09-22 23:06:16 -0600

On this site(tutorial), it show us how to draw the lines detected by cv::HoughLines,but I can't understand how could it find out the Point between the lines.

    for( size_t i = 0; i < lines.size(); i++ )
     float rho = lines[i][0], theta = lines[i][1];
     Point pt1, pt2;
     double a = cos(theta), b = sin(theta);
     double x0 = a*rho, y0 = b*rho;
     pt1.x = cvRound(x0 + 1000*(-b)); //??
     pt1.y = cvRound(y0 + 1000*(a)); //??
     pt2.x = cvRound(x0 - 1000*(-b)); //??
     pt2.y = cvRound(y0 - 1000*(a)); //??
     line( cdst, pt1, pt2, Scalar(0,0,255), 3, CV_AA);

Another codes from the openCV2 cookbook.I could understand why the codes from the cookbook work but it is more verbose.

for(auto const &data : lines){
    float const rho = data[0];
    float const theta = data[1];

    if((theta < PI/4. || theta > 3. * PI/4.)){
        cv::Point pt1(rho / std::cos(theta), 0);
        cv::Point pt2( (rho - result.rows * std::sin(theta))/std::cos(theta), result.rows);
        cv::line(result, pt1, pt2, cv::Scalar(255), 1);
    }else if{
        cv::Point pt1(0, rho / std::sin(theta));
        cv::Point pt2(result.cols, (rho - result.cols * std::cos(theta))/std::sin(theta));
        cv::line(result, pt1, pt2, cv::Scalar(255), 1);
edit retag flag offensive close merge delete

2 answers

Sort by ยป oldest newest most voted

answered 2013-09-23 02:05:14 -0600

ThomasB gravatar image

updated 2013-09-23 02:06:05 -0600

I think he tries to understand what the code in the tutorial does.

double a = cos(theta), b = sin(theta);
double x0 = a*rho, y0 = b*rho;

Is just the transformation from polar coordinates to Cartesian coordinates. This is the point where the blue and the red line meets.

Illustration from Tutorial

pt1.x = cvRound(x0 + 1000*(-b));
pt1.y = cvRound(y0 + 1000*(a));
pt2.x = cvRound(x0 - 1000*(-b));
pt2.y = cvRound(y0 - 1000*(a));

These next four lines of code "calculate" the points x and y, which are then used to draw. I wrote "calculate" because they don't really do, but just move a 1000 pixels in both directions, horizontally and vertically. If you have an image much larger than thousand pixels, you'll find that most lines won't reach the outer borders of the image but end somewhere with a total x-distance of 2000 pixels and a total y-distance of 2000 pixels from end to end. However, all lines include the point (x0,y0), th e one where blue and red line meet. From this point to x, deltaY is 1000 and deltaX is also 1000, same is valid for the distance between this point and y, just deltaY is -1000 and deltaX is also -1000

edit flag offensive delete link more


Nice explanation!

StevenPuttemans gravatar imageStevenPuttemans ( 2013-09-23 04:12:35 -0600 )edit

I still have a question, how do you know the ptr1 and ptr2 are moving on the same line?How to prove it?

stereomatching gravatar imagestereomatching ( 2013-09-24 11:35:07 -0600 )edit

These are no pointers, they are POINTS, to be more precise the start and end-point of a line. OpenCV's drawLine-Algorithm simply draws a line between two given points. By respecting the angle theta and r one can construct the line with some simple geometry and the knowledge that a line (red) defined by (r, theta) is normal to the vector r (blue). Since the polar form does not hold any information on the length of the line, the author of this code used a large-enough number (1000) to get the illusion of an "endless" line since it usually exceeds the image's width and height.

ThomasB gravatar imageThomasB ( 2013-09-26 04:40:23 -0600 )edit

answered 2013-09-23 01:50:16 -0600

For process a line you can use the below code.


void darwLine(InputOutputArray _src,const Point &point1,const Point &point2)
   Mat src = _src.getMat();

   LineIterator it = LineIterator(src,point1,point2);
   for (size_t i=0; i < it.count;i++,it++)
       cv::Point cur_point = it.pos();<uchar>(cur_point.x,cur_point.y) = 255;

void main()
    Mat src = Mat::zeros(Size(550,500),CV_8UC1);
edit flag offensive delete link more

Question Tools


Asked: 2013-09-22 11:38:40 -0600

Seen: 8,385 times

Last updated: Sep 23 '13