Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>OpenCV finds contours of the white objects in black background. In your case it is reverse, objects are black. And in that way, even image border is also an object. So to avoid that, just reverse image such that background is black.</p> <p>Below I have demonstrated it (using OpenCV-Python):</p> <pre><code>import numpy as np import cv2 im = cv2.imread('sofsqr.png') img = cv2.cvtColor(im,cv2.COLOR_BGR2GRAY) ret,thresh = cv2.threshold(img,127,255,1) </code></pre> <p>Remember, instead of using seperate function for inverting, I used it in threshold. Just convert the threshold type to BINARY_INV (ie '1').</p> <p>Now you have an image as below :</p> <p><img src="https://i.stack.imgur.com/eRT0u.png" alt="enter image description here"></p> <p>Now we find the contours. Then for each contour, we approximate it and check if it is a rectangle by looking at the length of approximated contour, which should be four for a rectangle.</p> <p>If drawn, you get like this:</p> <p><img src="https://i.stack.imgur.com/Nztuq.png" alt="enter image description here"></p> <p>And at the same time, we also find the bounding rect of each contour. The bounding rect has a shape like this : [initial point x, initial point y, width of rect, height of rect]</p> <p>So you get the width and height.</p> <p>Below is the code:</p> <pre><code>contours,hierarchy = cv2.findContours(thresh,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE) for cnt in contours: approx = cv2.approxPolyDP(cnt,cv2.arcLength(cnt,True)*0.02,True) if len(approx)==4: cv2.drawContours(im,[approx],0,(0,0,255),2) x,y,w,h = cv2.boundingRect(cnt) </code></pre> <p><strong>EDIT :</strong> </p> <p>After some comments, I understood that, the real aim of the question is to avoid large rectangles and select only smaller ones. </p> <p>It can be done using bounding rect values we obtained. ie, Select only those rectangles whose length is less than a threshold value, or breadth or area. As an example, in this image, I took area should be less than 10000.(A rough estimate). If it is less than 10000, it should be selected and we denote it in red color, otherwise, false candidate, represented in blue color ( just for visualization).</p> <pre><code>for cnt in contours: approx = cv2.approxPolyDP(cnt,cv2.arcLength(cnt,True)*0.02,True) if len(approx)==4: x,y,w,h = cv2.boundingRect(approx) if w*h &lt; 10000: cv2.drawContours(im,[approx],0,(0,0,255),-1) else: cv2.drawContours(im,[approx],0,(255,0,0),-1) </code></pre> <p>Below is the output i got :</p> <p><img src="https://i.stack.imgur.com/A2w06.png" alt="enter image description here"></p> <p><strong>How to get that threshold value? :</strong></p> <p>It completely depends on you and your application. Or you can find it by trial and error methods. ( i did so).</p> <p>Hope that solves your problem. All functions are standard opencv functions. So i think you won't find any problem to convert to JavaCV.</p>
 

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