【问题标题】:how to change the image from Irregular rectangle to a rectangle?如何将图像从不规则矩形更改为矩形?
【发布时间】:2016-07-26 06:36:58
【问题描述】:

我想要做的是将矩阵从图像1 的左侧更改为右侧。据我所知,我们不能仅仅通过基本的转换方法来改变。

真正的问题是我在下图中有一个矩形。我需要把不规则的矩形改成规则的矩形。

【问题讨论】:

  • 也许这可以帮助你:link
  • @s1h 非常感谢你。 link 是我的正确答案。

标签: c++ image opencv


【解决方案1】:

所以,第一个问题是角顺序。它们在两个向量中的顺序必须相同。因此,如果在第一个向量中您的顺序是:(top-left, bottom-left, bottom-right, top-right) ,则它们在另一个向量中的顺序必须相同。

其次,要使生成的图像仅包含感兴趣的对象,您必须将其宽度和高度设置为与生成的矩形宽度和高度相同。不用担心,warpPerspective 中的 src 和 dst 图像大小可以不同。

第三,性能问题。虽然您的方法绝对准确,因为您只进行仿射变换(旋转、调整大小、歪斜),但在数学上,您可以使用函数的仿射对应对象。它们的速度要快得多。

getAffineTransform()
warpAffine().

重要提示:getAffine 变换只需要和期望 3 个点,结果矩阵是 2×3,而不是 3×3。

如何使结果图像具有与输入不同的大小:

cv::warpPerspective(src, dst, dst.size(), ... );
use

cv::Mat rotated;
cv::Size size(box.boundingRect().width, box.boundingRect().height);
cv::warpPerspective(src, dst, size, ... );

你到了,你的编程任务已经结束了。

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<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));

    // For debugging purposes, draw green lines connecting those points 
    // and save it on disk
    const Point* point = &not_a_rect_shape[0];
    int n = (int)not_a_rect_shape.size();
    Mat draw = src.clone();
    polylines(draw, &point, &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 << "Rotated box set to (" << box.boundingRect().x << "," << box.boundingRect().y << ") " << box.size.width << "x" << box.size.height << 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 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);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-17
    • 1970-01-01
    • 2014-05-09
    相关资源
    最近更新 更多