Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>So, first problem is corner order. They must be in the same order in both vectors. So, if in the first vector your order is:(top-left, bottom-left, bottom-right, top-right) , they MUST be in the same order in the other vector. </p> <p>Second, to have the resulting image contain only the object of interest, you must set its width and height to be the same as resulting rectangle width and height. Do not worry, the src and dst images in warpPerspective can be different sizes.</p> <p>Third, a performance concern. While your method is absolutely accurate, because you are doing only affine transforms (rotate, resize, deskew), mathematically, you can use the affine corespondent of your functions. They are much <strong>faster</strong>.</p> <ul> <li><p>getAffineTransform()</p></li> <li><p>warpAffine().</p></li> </ul> <p>Important note: getAffine transform needs and expects ONLY 3 points, and the result matrix is 2-by-3, instead of 3-by-3.</p> <p>How to make the result image have a different size than the input:</p> <pre><code>cv::warpPerspective(src, dst, dst.size(), ... ); </code></pre> <p>use </p> <pre><code>cv::Mat rotated; cv::Size size(box.boundingRect().width, box.boundingRect().height); cv::warpPerspective(src, dst, size, ... ); </code></pre> <p>So here you are, and your programming assignment is over.</p> <pre><code>void main() { cv::Mat src = cv::imread("r8fmh.jpg", 1); // After some magical procedure, these are points detect that represent // the corners of the paper in the picture: // [408, 69] [72, 2186] [1584, 2426] [1912, 291] vector&lt;Point&gt; not_a_rect_shape; not_a_rect_shape.push_back(Point(408, 69)); not_a_rect_shape.push_back(Point(72, 2186)); not_a_rect_shape.push_back(Point(1584, 2426)); not_a_rect_shape.push_back(Point(1912, 291)); // For debugging purposes, draw green lines connecting those points // and save it on disk const Point* point = &amp;not_a_rect_shape[0]; int n = (int)not_a_rect_shape.size(); Mat draw = src.clone(); polylines(draw, &amp;point, &amp;n, 1, true, Scalar(0, 255, 0), 3, CV_AA); imwrite("draw.jpg", draw); // Assemble a rotated rectangle out of that info RotatedRect box = minAreaRect(cv::Mat(not_a_rect_shape)); std::cout &lt;&lt; "Rotated box set to (" &lt;&lt; box.boundingRect().x &lt;&lt; "," &lt;&lt; box.boundingRect().y &lt;&lt; ") " &lt;&lt; box.size.width &lt;&lt; "x" &lt;&lt; box.size.height &lt;&lt; std::endl; Point2f pts[4]; box.points(pts); // Does the order of the points matter? I assume they do NOT. // But if it does, is there an easy way to identify and order // them as topLeft, topRight, bottomRight, bottomLeft? cv::Point2f src_vertices[3]; src_vertices[0] = pts[0]; src_vertices[1] = pts[1]; src_vertices[2] = pts[3]; //src_vertices[3] = not_a_rect_shape[3]; Point2f dst_vertices[3]; dst_vertices[0] = Point(0, 0); dst_vertices[1] = Point(box.boundingRect().width-1, 0); dst_vertices[2] = Point(0, box.boundingRect().height-1); /* Mat warpMatrix = getPerspectiveTransform(src_vertices, dst_vertices); cv::Mat rotated; cv::Size size(box.boundingRect().width, box.boundingRect().height); warpPerspective(src, rotated, warpMatrix, size, INTER_LINEAR, BORDER_CONSTANT);*/ Mat warpAffineMatrix = getAffineTransform(src_vertices, dst_vertices); cv::Mat rotated; cv::Size size(box.boundingRect().width, box.boundingRect().height); warpAffine(src, rotated, warpAffineMatrix, size, INTER_LINEAR, BORDER_CONSTANT); imwrite("rotated.jpg", rotated); } </code></pre>
 

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