Ask Your Question

Can I use cv::fitLine() to robustly find an intersection point?

asked 2012-07-31 03:46:05 -0500

Adi gravatar image

updated 2012-10-31 03:01:58 -0500

cv::fitLine provide robust line fitting algorithms, that ought to be better than the regular least-square fitting.
I am wondering if cv::fitLine can be "abused" to robustly find the "best" intersection point of a large number of image lines.

I can just list each image line as a 3D (homogrphic) point and then call cv::fitLine. The result after normalizing should be the best fitting point.

Is there any reason this will not work? After all lines and point are duals in 2D space, and identical in 2D projective space.

If it does work, then what should the param, reps and aeps parameters be?

edit retag flag offensive close merge delete


intersting... as answer you could post some code to show something! good job anyway

yes123 gravatar imageyes123 ( 2012-08-01 04:50:05 -0500 )edit

The code does exactly what I wrote. It's using some internal classes, so it'd take some rewrite to post here. If there's more demand I may do it anyway.

Adi gravatar imageAdi ( 2012-08-01 06:26:45 -0500 )edit

You can post an answer to your own question, signal it as the correct answer, and people will give you credit for it. Also, the better you format the answer (ex: including code snippets), the better for the community (and also will receive more upvotes) =)

Rui Marques gravatar imageRui Marques ( 2012-08-01 09:10:30 -0500 )edit

Yes, I know, but actually I was still waiting for some more answers regarding: the validity and the parameters.

Adi gravatar imageAdi ( 2012-08-01 10:11:38 -0500 )edit

2 answers

Sort by ยป oldest newest most voted

answered 2012-10-31 02:50:07 -0500

Mahdi gravatar image

There are no function in OpenCV API to calculate lines intersection, but distance is:

cv::Point2f start, end;
double length = cv::norm(end - start);

If you need a piece of code to calculate line intersections then here it is:

// Finds the intersection of two lines, or returns false.
// The lines are defined by (o1, p1) and (o2, p2).
bool intersection(Point2f o1, Point2f p1, Point2f o2, Point2f p2,
                      Point2f &r)
    Point2f x = o2 - o1;
    Point2f d1 = p1 - o1;
    Point2f d2 = p2 - o2;

    float cross = d1.x*d2.y - d1.y*d2.x;
    if (abs(cross) < /*EPS*/1e-8)
        return false;

    double t1 = (x.x * d2.y - x.y * d2.x)/cross;
    r = o1 + d1 * t1;
    return true;
edit flag offensive delete link more

answered 2012-10-31 03:02:56 -0500

Adi gravatar image

Answering myself...

I tried what I described above. I used the 2D lines as 3D point (an Nx3 matrix) and got back a 6-element vector [P,D]. I used this to create 3D points, P and Q=P+D, which I then normalized by the 3rd coordinate to get 2 2D homographic points. I found the parametric line L through P and Q, and after normalizing L by its 3rd coordinate I got the desired intersection point.

A few notes:

  1. Using CV_DIST_L2 with cv::fitLine does not give exactly the same results as using the SVD solver to find the least-square null-space of the matrix.
    In fact, in certain cases I got #INF where the SVD worked without a problem.
  2. I did not see a lot of differences between the different M-estimator methods, except when sometimes some would give a completely wrong result.
edit flag offensive delete link more

Question Tools


Asked: 2012-07-31 03:46:05 -0500

Seen: 5,340 times

Last updated: Oct 31 '12