gpt4 book ai didi

c++ - 在 OpenCV 中展开一组矩形以形成正方形网格

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:18:56 28 4
gpt4 key购买 nike

我正在尝试映射包含这些点的图像,使用左上角点和右下角点绘制为矩形,尽管我确实将这些点作为四边形

enter image description here

我正在尝试将带有上面方 block 的图像映射到下面的方 block :

enter image description here

我相信我应该从每个四边形获得透视变换。这是我编写的一些代码来尝试促进这一点:

cv::Mat output = cv::Mat::zeros(outputSize,CV_32F);


// Uses the size of the quadOutput to
std::vector<std::vector<cv::Point2f>> quadOutputImage = quadralateralsFromImageOutput(imageToWarp.size().height);

cv::Mat perspectiveMatrix = cv::Mat(3,3,CV_32F);

cv::Mat warp = cv::Mat::zeros(outputSize,CV_32F);

for (int i = 0; i < quadOutputImage.size(); i ++) {

// get the mapping from the quadtriangles
perspectiveMatrix = cv::getPerspectiveTransform(quadCentroids[i],quadOutputImage[i]);

// perform the warp with the current quadtriangles
cv::warpPerspective(imageToWarp,warp,perspectiveMatrix,output.size());

// copy roi to output

}

return warp;

我一个四边形地做这个,但图像看起来根本不正确。看起来有点歪斜。

编辑

我也试过寻找单应矩阵,但我得到了一个奇怪的结果。这是我写的代码

    cv::Mat warpedImageGeneration(const cv::Mat& imageToWarp,cv::Size outputSize, std::vector<std::vector<cv::Point2f>> quadCentroids) {        

// Uses the size of the quadOutput 50 by 50 squares
std::vector<std::vector<cv::Point2f>> quadOutputImage = quadralateralsFromImageOutput(450);

// flatten the matrices
std::vector<cv::Point2f> flattenedQuads = flattenMatrix(quadOutputImage);
std::vector<cv::Point2f> flattenedCentroids = flattenMatrix(quadCentroids);

cv::Mat perspectiveMatrix = cv::Mat(3,3,CV_32F);

cv::Mat warp = cv::Mat::zeros(450,450,CV_32F);

perspectiveMatrix = cv::findHomography(flattenedCentroids, flattenedQuads);

cv::warpPerspective(imageToWarp, warp, perspectiveMatrix, warp.size());

return warp;
}

在示例图像上,这是我得到的未变形结果:

enter image description here

我认为问题可能是源的顶点不符合四边形顺序,即左上角、右上角、左下角和右下角。

最佳答案

单独扭曲每个矩形不会通过 getPerspectiveTransform 为您提供最佳结果。相反,如果您知道每个四边形从原始图像映射到变形图像的确切坐标,请尝试定义包含所有这些对应关系的一个透视变换矩阵。具体来说,查看源图像中每个四边形的所有角点,确定它们在变形图像中的映射位置,并定义一个描述所有这些点的透视变换矩阵。这样,当您提供来自源图像的点时,它们应该准确地映射到扭曲中的扭曲点,并且其他所有内容都应该干净地插值。

在实现方面,有两个 vector 容器,其中一个容器包含所有 source 图像点,另一个 vector 容器包含所有扭曲图像点。顺序很重要,因此请确保源 vector 容器中的每个位置对应于扭曲的 vector 容器中的相同位置。

但是,您将不得不换档并使用 findHomography反而。 findHomographygetPerspectiveTransform 的更一般情况,因为您要确定一个变换矩阵,该变换矩阵最好将一组点扭曲到另一组点,并且误差最小。 getPerspectiveTransform 只允许您指定 4 个点。 findHomography 允许您指定任意数量的点。

如果您想将其修改为您当前的框架,您已经拥有包含输入和变形图像的每个相应四边形的点 vector 的 vector 的代码。您正在访问每个 vector 并将其指定到 getPerspectiveTransform 中以获取每个四边形的透视变换矩阵。只需为输入指定一个 vector ,为包含所有四边形点的变形图像指定一个 vector ,然后调用一次 findHomography。显然顺序很重要,因此请确保输入图像中四边形的每个位置都与变形图像的输出位置相匹配。

此外,请确保您的坐标系正确无误。 OpenCV 的Point 结构假定x水平 坐标,而y垂直协调。由于您已将我建议的修改放在您的原始帖子中,为了完整性和使答案独立,我将把它们放在这里:

 cv::Mat warpedImageGeneration(const cv::Mat& imageToWarp,cv::Size outputSize, std::vector<std::vector<cv::Point2f>> quadCentroids) {

// Uses the size of the quadOutput 50 by 50 squares
std::vector<std::vector<cv::Point2f>> quadOutputImage = quadralateralsFromImageOutput(450);

// flatten the matrices
std::vector<cv::Point2f> flattenedQuads = flattenMatrix(quadOutputImage);
std::vector<cv::Point2f> flattenedCentroids = flattenMatrix(quadCentroids);

cv::Mat perspectiveMatrix = cv::Mat(3,3,CV_32F);

cv::Mat warp = cv::Mat::zeros(450,450,CV_32F);

perspectiveMatrix = cv::findHomography(flattenedCentroids, flattenedQuads);

cv::warpPerspective(imageToWarp, warp, perspectiveMatrix, warp.size());

return warp;
}

关于c++ - 在 OpenCV 中展开一组矩形以形成正方形网格,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29385212/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com