title: neither findContour for largest rectangle nor corner detection by hough transform working for me
body: <p>I have been trying to detect largest rectangle/square on clicked image. I tried both contour <a href="https://stackoverflow.com/questions/17512234/android-opencv-find-largest-square-or-rectangle">Android OpenCV Find Largest Square or Rectangle</a> and hough transform <a href="http://opencv-code.com/tutorials/automatic-perspective-correction-for-quadrilateral-objects/" rel="nofollow noreferrer">http://opencv-code.com/tutorials/automatic-perspective-correction-for-quadrilateral-objects/</a> . </p>
  
  <p>Both work like charm on image selected from gallery. But when I integrate with image taken from camera , it fails most of the times.</p>
  
  <p>Can anyone tell me what is the reason behind it ? what am I missing here ?</p>
  
  <p>As far as I know ,it's possible as many scan apps like camscanner does it very beautifully with more than 90% accuracy.</p>
  
  <p>Please suggest. I have tried alot.</p>
  
  <p>For reference :</p>
  
  <pre><code>public static String houghTransform(Mat original_image ,String outFile) {
          Mat imgSource = original_image;
          Mat untouched = original_image.clone();
  
          //convert the image to black and white
          Imgproc.cvtColor(imgSource, imgSource, Imgproc.COLOR_BGR2GRAY);
  
  
          //apply gaussian blur to smoothen lines of dots
          Imgproc.GaussianBlur(imgSource, imgSource, new Size(5, 5), 0); 
  
          //adaptive threshold thresholds the image taking an optimum value for a local neighbourhood. 
          //Imgproc.adaptiveThreshold(imgSource, imgSource, 255, Imgproc.ADAPTIVE_THRESH_GAUSSIAN_C, Imgproc.THRESH_BINARY, 3, 1);
  
          //convert the image to black and white does (8 bit)
          Imgproc.Canny(imgSource, imgSource, 80, 100);
          Mat lines = new Mat();
          int threshold = 70;
          int minLineSize = 20;
          int lineGap = 20;
  
          Imgproc.HoughLinesP(imgSource, lines, 1, Math.PI/180, threshold, minLineSize, lineGap);
  
          ArrayList&lt;Point&gt; corners = new ArrayList&lt;Point&gt;();
          for (int i = 0; i &lt; lines.cols(); i++)
          {
              for (int j = i+1; j &lt; lines.cols(); j++)
              {
                  Point pt = computeIntersect(lines.get(0,i), lines.get(0,j));
                  if (pt.x &gt;= 0 &amp;&amp; pt.y &gt;= 0)
                      corners.add(pt);
              }
          }
          L.v("Points corner size: ", ""+corners.size());
          if(corners.size()&lt;4){
              return "";
          }
  
          Point center = new Point(0,0);
          // Get mass center
          for (int i = 0; i &lt; corners.size(); i++){
              center.x += corners.get(i).x;
              center.y+= corners.get(i).y;
          }
          center.x = (center.x / corners.size());
          center.y = (center.y / corners.size());
  
          Core.circle(untouched, center, 20, new Scalar(255, 0, 0), 5); //p1 is colored red
  
          Core.circle(untouched, corners.get(0), 20, new Scalar(255, 0, 0), 5); 
          Core.circle(untouched, corners.get(1), 20, new Scalar(255, 0, 0), 5); 
          Core.circle(untouched, corners.get(2), 20, new Scalar(255, 0, 0), 5); 
          Core.circle(untouched, corners.get(3), 20, new Scalar(255, 0, 0), 5);
  
          Highgui.imwrite(outFile, untouched);
           return outFile;
  
   } 
  </code></pre>
  
  <p>Here is the computerIntersect module to detect four points which are the corners.</p>
  
  <pre><code>  private static Point computeIntersect(double[] a, double[] b) {
      double x1 = a[0], y1 = a[1], x2 = a[2], y2 = a[3], x3 = b[0], y3 = b[1], x4 = b[2], y4 = b[3];
      double denom = ((x1 - x2) * (y3 - y4)) - ((y1 - y2) * (x3 - x4));
      Point pt = new Point();
      if (denom!=0)
      {
  
              pt.x = ((x1 * y2 - y1 * x2) * (x3 - x4) - (x1 - x2) * (x3 * y4 - y3 * x4)) / denom;
              pt.y = ((x1 * y2 - y1 * x2) * (y3 - y4) - (y1 - y2) * (x3 * y4 - y3 * x4)) / denom;
              return pt;
      }
      else
              return new Point(-1, -1);
  }
  </code></pre>
  
  <p>Here it returns more than four points when I apply it for image taken from camera.</p>
  
  <p>Another method I tried is:</p>
  
  <pre><code>  public static String findLargestRectangle(Mat original_image ,String outFile) {
          Mat imgSource = original_image;
          Mat untouched = original_image.clone();
  
          //convert the image to black and white
          Imgproc.cvtColor(imgSource, imgSource, Imgproc.COLOR_BGR2GRAY);
  
  
          //apply gaussian blur to smoothen lines of dots
          Imgproc.GaussianBlur(imgSource, imgSource, new Size(5, 5), 0); 
  
          //convert the image to black and white does (8 bit)
          Imgproc.Canny(imgSource, imgSource, 80, 100);
  
              //find the contours
          List&lt;MatOfPoint&gt; contours = new ArrayList&lt;MatOfPoint&gt;();
          Imgproc.findContours(imgSource, contours, new Mat(), Imgproc.RETR_TREE, Imgproc.CHAIN_APPROX_SIMPLE);
  
          double maxArea = -1;
          int maxAreaIdx = -1;
  
          MatOfPoint temp_contour = contours.get(0); //the largest is at the index 0 for starting point
          MatOfPoint2f approxCurve = new MatOfPoint2f();
          MatOfPoint2f maxCurve = new MatOfPoint2f();
          List&lt;MatOfPoint&gt; largest_contours = new ArrayList&lt;MatOfPoint&gt;();
          for (int idx = 0; idx &lt; contours.size(); idx++) {
              temp_contour = contours.get(idx);
              double contourarea = Imgproc.contourArea(temp_contour);
              //compare this contour to the previous largest contour found
              if (contourarea &gt; maxArea) {
                  // Imgproc.drawContours(untouched, contours, maxAreaIdx, new Scalar(0, 255, 0), 1); 
                  //check if this contour is a square
                  MatOfPoint2f new_mat = new MatOfPoint2f( temp_contour.toArray() );
                  int contourSize = (int)temp_contour.total();
                  Imgproc.approxPolyDP(new_mat, approxCurve, contourSize*0.05, true);
                  if (approxCurve.total() == 4) {
                      maxCurve = approxCurve;
                      maxArea = contourarea;
                      maxAreaIdx = idx;
                      largest_contours.add(temp_contour);
                  }
              }
          }
    Imgproc.drawContours(imgSource, contours, maxAreaIdx, new Scalar(0, 255, 0), 5); //will draw the largest square/rectangle
   }
  </code></pre>
  
  <p>Thanks. </p>
  
  <p><img src="https://i.stack.imgur.com/EL65q.jpg" alt="enter image description here">
  <img src="https://i.stack.imgur.com/2F4uy.jpg" alt="enter image description here"></p>