How to detect a partial vertical/horizontal line in a image?

I have an image and I have a partial line in the image. They are all the time horizontal or vertical lines. I don't know the color of the line, neither the width of the line.

How can I use PHP to detect such a line?

As you see in the uploaded image, there are 3x3 sections I need to slice. I need the 3 vertical, and 3 horizantal sections to slice the parts. Please note there is a rectangle with some markes around the content area, that is part of the images.

We can use those markers to get the coordinates.

Answers


You're better off using the markers by comparing the first and last N pixels of each line if they have the same color/length. It will be more efficient that way than parsing all pixels on each line.


You must check the image row-wise and column-wise. You will most probably use imagecolorat(). Loop over all columns and rows. If two (or any arbitrary limit) or more pixels have the same (or very close) colors, they constitute a line.


Definitely use the marks, otherwise this is a hard problem.

To use the marks, you just need to find their positions. To do this, start at the edges, take successive single pixel wide strips and look for periodic deviations. The classic, and fairly easy, way to do this is using the autocorrelation. Since your marks are so clear (i.e. there's very little, if any noise), you might find an even easier way, such as average the pixel value for the whole strip and everything that deviates from that by more than a small amount is a mark; or, make a histogram of you pixel values and it should have two sharp bumps, one big bump for the background, and on small bump for your marks, etc. But whatever approach you use, find the marks, and you're done.


  1. Find the background color ($cBack) from a corner pixel (say, top-left)
  2. From the top left, move loop foreach (range(1, imagesx($img_rsrc)), setting $cCur.color = imagecolorat($img_asset, $x, $y);
  3. $iMarkWidth += 1; $iMarkPosStart = $cCur.x; until you hit a pixel of a different color ($cCur.color != $cBack.color), then $bMarkFound - true : else $bMarkFound = false;
  4. If $cCur.color == $cBack.color, $horizMarkArray[] = array( $iMarkPosStart, $iMarkPosStart + $iMarkWidth, $iMarkWidth);
  5. continue until end of width
  6. If is_empty($horizMarkArray) repeat with the next horizontal row
  7. .. and through 11. Repeat for height/verticals, with $vertMarkArray[]

At step 4 & 8 you can do any averaging, noise detection, etc. At steps 7 & 11 you can repeat the previous steps and average the $iMarkWidth in order to avoid aliasing errors at the top of the line. In that case you stop either:

  • after N lines, or
  • after $iMarkWidth > {something that obviously wider than any line}

You can try doing edge detection and then using Hough transform to detect lines. The problem in your case is that the edges corresponding to the lines are very faint. On the other hand, you only need to look for vertical and horizontal lines, so you can constrain the problem a lot.


Need Your Help

Assigning a structure to another structure results in garbage

c++ arrays struct

The two structures used in my code, one is nested

CodeRush XPress | Code Intelliassist Shortcut

visual-studio visual-studio-2008 keyboard-shortcuts coderush-xpress

I've installed coderush and wanted to refactor my code. I also tried to do some things they did in the introduction video. But the only way I get into the coderush intelliassist is the right-click

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.