Note that there are some explanatory texts on larger screens.

plurals
  1. POFinding shapes in an image using opencv
    primarykey
    data
    text
    <p>I'm trying to look for shapes in an image using OpenCV. I know the shapes I want to match (there are some shapes I don't know about, but I don't need to find them) and their orientations. I don't know their sizes (scale) and locations.</p> <p>My current approach:</p> <ol> <li>Detect contours</li> <li>For each contour, calculate the maximum bounding box</li> <li>Match each bounding box to one of the known shapes separately. In my real project, I'm scaling the region to the template size and calculating differences in Sobel gradient, but for this demo, I'm just using the aspect ratio.</li> </ol> <p>Where this approach comes undone is where shapes touch. The contour detection picks up the two adjacent shapes as a single contour (single bounding box). The matching step will then obviously fail.</p> <p>Is there a way to modify my approach to handle adjacent shapes separately? Also, is there a better way to perform step 3?</p> <p>For example: (Es colored green, Ys colored blue)</p> <p><img src="https://i.stack.imgur.com/YAdtm.png" alt="enter image description here"></p> <p>Failed case: (unknown shape in red)</p> <p><img src="https://i.stack.imgur.com/tePtF.png" alt="enter image description here"></p> <p>Source code:</p> <pre><code>import cv import sys E = cv.LoadImage('e.png') E_ratio = float(E.width)/E.height Y = cv.LoadImage('y.png') Y_ratio = float(Y.width)/Y.height EPSILON = 0.1 im = cv.LoadImage(sys.argv[1], cv.CV_LOAD_IMAGE_GRAYSCALE) storage = cv.CreateMemStorage(0) seq = cv.FindContours(im, storage, cv.CV_RETR_EXTERNAL, cv.CV_CHAIN_APPROX_SIMPLE) regions = [] while seq: pts = [ pt for pt in seq ] x, y = zip(*pts) min_x, min_y = min(x), min(y) width, height = max(x) - min_x + 1, max(y) - min_y + 1 regions.append((min_x, min_y, width, height)) seq = seq.h_next() rgb = cv.LoadImage(sys.argv[1], cv.CV_LOAD_IMAGE_COLOR) for x,y,width,height in regions: pt1 = x,y pt2 = x+width,y+height if abs(float(width)/height - E_ratio) &lt; EPSILON: color = (0,255,0,0) elif abs(float(width)/height - Y_ratio) &lt; EPSILON: color = (255,0,0,0) else: color = (0,0,255,0) cv.Rectangle(rgb, pt1, pt2, color, 2) cv.ShowImage('rgb', rgb) cv.WaitKey(0) </code></pre> <p>e.png:</p> <p><img src="https://i.stack.imgur.com/6XWCG.png" alt="enter image description here"></p> <p>y.png:</p> <p><img src="https://i.stack.imgur.com/7Hssy.png" alt="enter image description here"></p> <p>good:</p> <p><img src="https://i.stack.imgur.com/fDZZT.png" alt="enter image description here"></p> <p>bad:</p> <p><img src="https://i.stack.imgur.com/jKZUm.png" alt="enter image description here"></p> <p>Before anybody asks, no, I'm <em>not</em> trying to break a captcha :) OCR per se isn't really relevant here: the actual shapes in my real project aren't characters -- I'm just lazy, and characters are the easiest thing to draw (and still get detected by trivial methods).</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload