title: Why cvFindContours() method doesn't detect Contours correctly in javacv?
body: <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>