I hav开发者_如何学Pythone 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.
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.
- Find the background color ($cBack) from a corner pixel (say, top-left)
- From the top left, move loop foreach (range(1, imagesx($img_rsrc)), setting $cCur.color = imagecolorat($img_asset, $x, $y);
- $iMarkWidth += 1; $iMarkPosStart = $cCur.x; until you hit a pixel of a different color ($cCur.color != $cBack.color), then $bMarkFound - true : else $bMarkFound = false;
- If $cCur.color == $cBack.color, $horizMarkArray[] = array( $iMarkPosStart, $iMarkPosStart + $iMarkWidth, $iMarkWidth);
- continue until end of width
- If is_empty($horizMarkArray) repeat with the next horizontal row
- .. 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.
精彩评论