Home >Backend Development >C++ >How to Deskew a Set of Points Using cv::warpPerspective?

How to Deskew a Set of Points Using cv::warpPerspective?

Linda Hamilton
Linda HamiltonOriginal
2024-12-03 17:40:12786browse

How to Deskew a Set of Points Using cv::warpPerspective?

Executing cv::warpPerspective for a Fake Deskewing on a Set of cv::Point

Question: How do I achieve a deskewing effect on a set of points using cv::warpPerspective? The points are not in a particular order and are stored within a vector.

Understanding the Issue:

  • Incorrect point ordering: The order of points in the input and output vectors must match to achieve the desired transformation.
  • Incorrect image size: The output image should have a width and height matching the bounding rectangle of the deskewed object.

Steps for Fake Deskewing:

  1. Correct Point Ordering: Ensure the order of points in both input and output vectors follows the same sequence (e.g., top-left, bottom-left, bottom-right, top-right).
  2. Rotated Rectangle Adjustment: Use cv::minAreaRect() to create a rotated rectangle around the input points. However, note that this method may slightly alter the original point coordinates.
  3. Affine Transform: Utilize the affine transform functions, cv::getAffineTransform() and cv::warpAffine(), as they are computationally more efficient for this specific deskewing operation.
  4. Different Output Size: To have the deskewed image contain only the object of interest, define a new image size (e.g., cv::Size(width, height)) that matches the bounding rectangle size.
  5. Apply Affine Transform: Pass the input image, input points, output points, and the defined output size to cv::warpAffine() to perform the actual deskewing transformation.

Example Code:

#include <opencv2/opencv.hpp>

int main() {
    // Input image
    Mat src = imread("input.jpg");

    // Input points (not in particular order)
    vector<Point> points = {
        Point(408, 69), // Top-left
        Point(72, 2186), // Bottom-left
        Point(1584, 2426), // Bottom-right
        Point(1912, 291), // Top-right
    };

    // Rotated rectangle (bounding box)
    RotatedRect boundingRect = minAreaRect(Mat(points));

    // Corrected point ordering
    Point2f vertices[3];
    vertices[0] = boundingRect.center + boundingRect.size * 0.5f; // Top-left
    vertices[1] = boundingRect.center + boundingRect.size * 0.5f; // Bottom-left
    vertices[1].y += boundingRect.size.height;
    vertices[2] = boundingRect.center - boundingRect.size * 0.5f; // Bottom-right

    // Output point ordering
    Point2f outputVertices[3];
    outputVertices[0] = Point(0, 0); // Top-left
    outputVertices[1].x = outputVertices[0].x + boundingRect.size.width; // Bottom-left
    outputVertices[1].y = outputVertices[1].x;
    outputVertices[2] = outputVertices[0]; // Bottom-right

    // Affine transformation matrix
    Mat transformationMatrix = getAffineTransform(vertices, outputVertices);

    // Deskewed image with corrected size
    Mat deskewedImage;
    Size outputSize(boundingRect.size.width, boundingRect.size.height);
    warpAffine(src, deskewedImage, transformationMatrix, outputSize, INTER_LINEAR);

    // Save deskewed image
    imwrite("deskewed.jpg", deskewedImage);
}

The above is the detailed content of How to Deskew a Set of Points Using cv::warpPerspective?. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn