Home > Backend Development > C++ > How to Simulate Deskewing of Points Using OpenCV\'s `warpAffine`?

How to Simulate Deskewing of Points Using OpenCV\'s `warpAffine`?

Patricia Arquette
Release: 2024-11-28 11:49:10
Original
188 people have browsed it

How to Simulate Deskewing of Points Using OpenCV's `warpAffine`?

How to Achieve a Fake Deskewing Effect on a Set of Points Using cv::warpPerspective

Problem Statement

The goal is to apply a perspective transformation to a set of points to obtain a deskewing effect, similar to the one shown in the following video:

[Video Link](http://nuigroup.com/?ACT=28&fid=27&aid=1892_H6eNAaign4Mrnn30Au8d)

Result Analysis

The provided sample image and code demonstrate the deskewing effect, but it's not accurate. Specifically, the transformed image doesn't contain the entire ROI and the aspect ratio is incorrect.

Correcting the Errors

To fix the issues, the following changes were made to the code:

  1. Ensuring the same vertex order: The points in both source and destination vectors must be in the same order (e.g., top-left, bottom-left, bottom-right, top-right).
  2. Customizing the output image size: To properly contain the ROI, the destination image size should be set to the size of the bounding rectangle around the original points.
  3. Optimizing for speed: To enhance performance, the affine transform functions (getAffineTransform() and warpAffine()) were used instead of the general perspective transform functions.

Updated Code

void main()
{
    cv::Mat src = cv::imread("r8fmh.jpg", 1);

    // Points representing the corners of the paper
    vector<Point> 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));

    // Debug drawing of the points
    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);

    // Rotated rectangle around the points
    RotatedRect box = minAreaRect(cv::Mat(not_a_rect_shape));

    // Source and destination vertex points
    Point2f pts[4];
    box.points(pts);

    Point2f src_vertices[3];
    src_vertices[0] = pts[0];
    src_vertices[1] = pts[1];
    src_vertices[2] = pts[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);

    // Affine transform matrix
    Mat warpAffineMatrix = getAffineTransform(src_vertices, dst_vertices);

    // Transformation and output image
    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);
}
Copy after login

The above is the detailed content of How to Simulate Deskewing of Points Using OpenCV\'s `warpAffine`?. For more information, please follow other related articles on the PHP Chinese website!

source:php.cn
Statement of this Website
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
Latest Articles by Author
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template