Note that there are some explanatory texts on larger screens.

plurals
  1. POWhy cvFindContours() method doesn't detect Contours correctly in javacv?
    text
    copied!<p>I went through many questions in StackOverflow and able to develop small program to detect squares and rectangles correctly. This is my sample code</p> <pre><code>public static CvSeq findSquares(final IplImage src, CvMemStorage storage) { CvSeq squares = new CvContour(); squares = cvCreateSeq(0, sizeof(CvContour.class), sizeof(CvSeq.class), storage); IplImage pyr = null, timg = null, gray = null, tgray; timg = cvCloneImage(src); CvSize sz = cvSize(src.width(), src.height()); tgray = cvCreateImage(sz, src.depth(), 1); gray = cvCreateImage(sz, src.depth(), 1); // cvCvtColor(gray, src, 1); pyr = cvCreateImage(cvSize(sz.width() / 2, sz.height() / 2), src.depth(), src.nChannels()); // down-scale and upscale the image to filter out the noise // cvPyrDown(timg, pyr, CV_GAUSSIAN_5x5); // cvPyrUp(pyr, timg, CV_GAUSSIAN_5x5); // cvSaveImage("ha.jpg",timg); CvSeq contours = new CvContour(); // request closing of the application when the image window is closed // show image on window // find squares in every color plane of the image for (int c = 0; c &lt; 3; c++) { IplImage channels[] = { cvCreateImage(sz, 8, 1), cvCreateImage(sz, 8, 1), cvCreateImage(sz, 8, 1) }; channels[c] = cvCreateImage(sz, 8, 1); if (src.nChannels() &gt; 1) { cvSplit(timg, channels[0], channels[1], channels[2], null); } else { tgray = cvCloneImage(timg); } tgray = channels[c]; // // try several threshold levels for (int l = 0; l &lt; N; l++) { // hack: use Canny instead of zero threshold level. // Canny helps to catch squares with gradient shading if (l == 0) { // apply Canny. Take the upper threshold from slider // and set the lower to 0 (which forces edges merging) cvCanny(tgray, gray, 0, thresh, 5); // dilate canny output to remove potential // // holes between edge segments cvDilate(gray, gray, null, 1); } else { // apply threshold if l!=0: cvThreshold(tgray, gray, (l + 1) * 255 / N, 255, CV_THRESH_BINARY); } // find contours and store them all as a list cvFindContours(gray, storage, contours, sizeof(CvContour.class), CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE); CvSeq approx; // test each contour while (contours != null &amp;&amp; !contours.isNull()) { if (contours.elem_size() &gt; 0) { approx = cvApproxPoly(contours, Loader.sizeof(CvContour.class), storage, CV_POLY_APPROX_DP, cvContourPerimeter(contours) * 0.02, 0); if (approx.total() == 4 &amp;&amp; Math.abs(cvContourArea(approx, CV_WHOLE_SEQ, 0)) &gt; 1000 &amp;&amp; cvCheckContourConvexity(approx) != 0) { double maxCosine = 0; for (int j = 2; j &lt; 5; j++) { // find the maximum cosine of the angle between // joint edges double cosine = Math.abs(angle( new CvPoint(cvGetSeqElem( approx, j % 4)), new CvPoint(cvGetSeqElem( approx, j - 2)), new CvPoint(cvGetSeqElem( approx, j - 1)))); maxCosine = Math.max(maxCosine, cosine); } if (maxCosine &lt; 0.2) { CvRect x = cvBoundingRect(approx, l); if ((x.width() * x.height()) &lt; 50000) { System.out.println("Width : " + x.width() + " Height : " + x.height()); cvSeqPush(squares, approx); } } } } contours = contours.h_next(); } contours = new CvContour(); } } return squares; } </code></pre> <p>I use this image to detect rectangles and squares</p> <p><img src="https://i.stack.imgur.com/cZ2Ka.jpg" alt="enter image description here"></p> <p>I need to identify the following output</p> <p><img src="https://i.stack.imgur.com/uiDtZ.jpg" alt="enter image description here"></p> <p>and</p> <p><img src="https://i.stack.imgur.com/MAHmR.jpg" alt="enter image description here"></p> <p>But when I run the above code, it detects only the following rectangles. But I don't know the reason for that. Please can someone explain the reason for that.</p> <p>This is the output that I got.</p> <p><img src="https://i.stack.imgur.com/jaUsX.png" alt="enter image description here"></p> <p>Please be kind enough to explain the problem in above code and give some suggensions to detect this squares and rectangles.</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