Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>This is a recurring subject in Stackoverflow and since I was unable to find a relevant implementation I decided to accept the challenge.</p> <p>I made some modifications to the squares demo present in OpenCV and the resulting C++ code below is able to detect a sheet of paper in the image:</p> <pre><code>void find_squares(Mat&amp; image, vector&lt;vector&lt;Point&gt; &gt;&amp; squares) { // blur will enhance edge detection Mat blurred(image); medianBlur(image, blurred, 9); Mat gray0(blurred.size(), CV_8U), gray; vector&lt;vector&lt;Point&gt; &gt; contours; // find squares in every color plane of the image for (int c = 0; c &lt; 3; c++) { int ch[] = {c, 0}; mixChannels(&amp;blurred, 1, &amp;gray0, 1, ch, 1); // try several threshold levels const int threshold_level = 2; for (int l = 0; l &lt; threshold_level; l++) { // Use Canny instead of zero threshold level! // Canny helps to catch squares with gradient shading if (l == 0) { Canny(gray0, gray, 10, 20, 3); // // Dilate helps to remove potential holes between edge segments dilate(gray, gray, Mat(), Point(-1,-1)); } else { gray = gray0 &gt;= (l+1) * 255 / threshold_level; } // Find contours and store them in a list findContours(gray, contours, CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE); // Test contours vector&lt;Point&gt; approx; for (size_t i = 0; i &lt; contours.size(); i++) { // approximate contour with accuracy proportional // to the contour perimeter approxPolyDP(Mat(contours[i]), approx, arcLength(Mat(contours[i]), true)*0.02, true); // Note: absolute value of an area is used because // area may be positive or negative - in accordance with the // contour orientation if (approx.size() == 4 &amp;&amp; fabs(contourArea(Mat(approx))) &gt; 1000 &amp;&amp; isContourConvex(Mat(approx))) { double maxCosine = 0; for (int j = 2; j &lt; 5; j++) { double cosine = fabs(angle(approx[j%4], approx[j-2], approx[j-1])); maxCosine = MAX(maxCosine, cosine); } if (maxCosine &lt; 0.3) squares.push_back(approx); } } } } } </code></pre> <p>After this procedure is executed, the sheet of paper will be the largest square in <code>vector&lt;vector&lt;Point&gt; &gt;</code>:</p> <p><img src="https://i.stack.imgur.com/JQ0DH.jpg" alt="opencv paper sheet detection"></p> <p>I'm letting you write the function to find the largest square. ;)</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