Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

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.

enter image description here

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

enter image description here

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.

share|improve this question

1 Answer 1

up vote 4 down vote accepted

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}]]

Mathematica graphics

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.}
share|improve this answer
    
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 at 10:19
    
@ASBOAllstar See, that's why I wanted comments :D It's obviously a mistake. Fixing it now :) –  Öskå Aug 7 at 10:29
    
@ASBOAllstar Please check the edit. –  Öskå Aug 7 at 10:44
    
Thanks, essentially the sensitivity has been introduced for anything longer than 100? –  ASBO Allstar Aug 7 at 10:49
1  
@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 at 19:49

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.