7

I'm trying to solve the following problem:

  • I'm analyzing an image and I obtain from this analysis a set of segments
  • I want to know the intersection of these lines (best fit)

I'm using for this opencv's function cvSolve. For reasonably good input everything works fine.

The problem that I have comes from the fact that when I have just a single bad segment as input the result is different from the one expected.

Bad lines influencing result

Details:

  • Upper left image show the "lonely" purple lines influencing the result (all lines are used as input).

  • Upper right image shows how a single purple line (one removed) can influence the result.

  • Lower left image show what we want - the intersection of lines as expected (both purple lines eliminated).

  • Lower right image show how the other purple line (the other is removed) can influence the result.

As you can see only two lines and the result is completely different from the one expected. Any ideas on how to avoid this are appreciated.

Thanks,

Iulian

INS
  • 10,594
  • 7
  • 58
  • 89

3 Answers3

8

The algorithm you are using finds, as described in the link, the least square error solution to the problem. This means that if there are more intersection points, the result will be an average (for a reasonable definition of average) of the real solutions.

I would try an iterative solution: if the error of the first solution is too large, remove from the set of segments the one farthest to the solution, and iterate until the error is acceptably small. This should remove one of the many intersection point, and converge on the one with most lines nearby.

Coffee on Mars
  • 988
  • 6
  • 21
  • +1 Interesting approach. I will check the complexity of the algorithm and give it a try after that. – INS Jun 15 '11 at 12:31
  • 2
    You could skip a few steps using the "80/20 rule", i.e. find the best-fit intersection of all lines, sort lines by distance from the intersection, eliminate the worst 20% and solve again using the remaining 80%. – finnw Jun 15 '11 at 14:04
3

A general answer to this kind of problems is the RANSAC algorithm (question dealing with this), however it has a few disadvantages, for example you need to estimate things like "the expected number of outliers" beforehand. Another Problem I see with your sample is that removing the two green lines also results in a pretty good fit, so that might be a more general problem.

Community
  • 1
  • 1
etarion
  • 16,935
  • 4
  • 43
  • 66
  • You are right but as you can see the lines coming from the lower left corner determine a unique intersection point that fits the intersection of the green lines which is what I want... So there might be a solution for eliminating the buggy purple lines – INS Jun 15 '11 at 14:57
0

you can solve using SVD incase line1 =(x1,y1)-(x2,y2) ; line2 =(x2,y2)-(x3,y3)

let Ax = b where;

A = [-(y2-y1) (x2-x1);
     -(y3-y2) (x3-x2);
    .................
    .................] -->(nx2)
x = transpose[s t]     -->(2x1)
b = [-(y2-y1)x1 + (x2-x1)y1 ;
     -(y3-y2)x2 + (x3-x2)y2 ;
    ........................
    ........................] --> (nx1)

Example; Matlab Code

line1=[0,10;5,10]
line2=[10,0;10,5]
line3=[0,0;5,5]

A=[-(line1(2,2)-line1(1,2)),(line1(2,1)-line1(1,1));
-(line2(2,2)-line2(1,2)),(line2(2,1)-line2(1,1));
-(line3(2,2)-line3(1,2)),(line3(2,1)-line3(1,1))];


b=[(line1(1,1)*A(1,1))+ (line1(1,2)*A(1,2));
   (line2(1,1)*A(2,1))+ (line2(1,2)*A(2,2));
   (line3(1,1)*A(3,1))+ (line3(1,2)*A(3,2))];

[U D V] = svd(A)
bprime = U'*b

y=[bprime(1)/D(1,1);bprime(2)/D(2,2)]

x=V*y