# Tolerance on image detection

I am trying to pick straight lines out of a photographic image to track deflections of a structure under loading.

The idea is to mark certain structural elements with straight lines, as they deflect I can then extract the vectors from the image, find the centre point and measure how much the vector has displaced and rotated since the previous image.

I have used the second answer to this question to get the bones of a process up and running, code below. Using a generic vector image from web as a test image until my rig is up and running.

i = ColorNegate@Import["http://goo.gl/5R4MAl"]
p = Closing[Binarize@ImageTake[i, 480], 1];
Show[p, Graphics[{Thick, Orange, Line /@ ImageLines[p, Segmented -> True]}]]


This seems to pick out the main vectors quite nicely.

Whilst the length of results returned is 9 which is what I expected, on closer inspection there are additional points that are very close together. I'm guessing that these are rogue parts of the arrowheads being picked up.

foo = ImageLines[p, Segmented -> True]
foo // Length


Gives the length to be 9, which is what I would have expected given there are nine primary lines, but if displayed in matrixform I'm getting additional rogue points.

foo // MatrixForm


I've tried to tinker about with limiting the MaxFeatures->9 and using DeleteSmallComponents with mixed success. I'm struggling to find any helpful guidance too on what t (threshold) and d (distinctness) actually do with regards the image recognition.

What methods exist to extract the primary straight lines from images like the one used in the above example that gives a start and and end co-ordinate of the line that can then be used in subsequent calculations please? I'd also prefer to not set the number of lines I'm expecting Mathematica to discover.

-

Here is an example returning 9 lines without additional points:

i = Import["http://goo.gl/5R4MAl"];
ii = Closing[Binarize[GradientFilter[ColorNegate@Binarize[i, .55], 2], 0.1], 1];
foo = Select[ImageLines[ii, Segmented -> True], EuclideanDistance @@ #[[1]] > 100 &];
Show[i, Graphics[{Thick, Orange, Line /@ foo}]]


Here are the details for foo:

Length /@ foo
Length@foo

{2, 2, 2, 2, 2, 2, 2, 2, 2}
9


Note that foo = ImageLines[ii, .1, Segmented -> True] produces the exact same lines.

Checking the length of the lines in foo:

EuclideanDistance @@ # & @@@ foo

{164., 163.5, 163., 163.5, 163.5, 163.5, 163.5, 163., 162.}

-
Because Segmented-> False is used on the second block of code, doesn't this extend the vectors out to the edge of the image, and this is why the y co-ordinate is always either 0 or 300. Therefore this doesn't give the actual length of the vector but a false measurement instead? Apologies if I'm misunderstanding. –  ASBO Allstar Aug 7 '14 at 10:19
@ASBOAllstar See, that's why I wanted comments :D It's obviously a mistake. Fixing it now :) –  Öskå Aug 7 '14 at 10:29
@ASBOAllstar Please check the edit. –  Öskå Aug 7 '14 at 10:44
Thanks, essentially the sensitivity has been introduced for anything longer than 100? –  ASBO Allstar Aug 7 '14 at 10:49
@ASBOAllstar Then you should use foo = ImageLines[ii, .1, Segmented -> True]. Like I said at the end of the answer, it's exactly the same as Select[..., EuclideanDistance..] –  Öskå Aug 8 '14 at 19:49