【发布时间】:2015-04-01 07:32:19
【问题描述】:
我正在尝试映射包含这些点的图像,使用左上角和右下角绘制为矩形,尽管我确实将这些点作为四边形
我正在尝试将带有上述正方形的图像映射到下面的正方形:
我相信我应该从每个四边形获得透视变换。这是我编写的一些代码来尝试和促进这一点:
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;
}
在示例图像上,这是我得到的未变形结果:
我认为问题可能是源的顶点不符合四边形顺序,即左上角、右上角、左下角和右下角。
【问题讨论】:
-
如果您知道每个四边形从原始图像映射到扭曲后的确切坐标,请尝试定义包含所有这些对应关系的 一个 透视变换矩阵。具体来说,查看源图像中每个四边形的所有角点,确定它们应该在扭曲图像中映射的位置,并定义一个描述所有这些点的透视变换矩阵。这样,当您提供源图像中的点时,它们应该精确地映射到扭曲中的扭曲点,并且其他所有内容都应该干净地插值。
-
如何从一张图像的所有四边形中获得一个透视变换矩阵?
-
简单。您已经有代码,其中包含输入和扭曲图像的每个相应四边形的点向量的向量。您正在访问每个向量并将其指定为
getPerspectiveTransform以获得每个四边形的透视变换矩阵。只需为输入指定 one 向量,为包含 所有 个四边形点的扭曲图像指定 one 向量,然后制作一个 单个呼叫getPerspectiveTransform。显然顺序很重要,因此请确保输入图像中四边形的每个位置都与变形图像的输出位置相匹配。 -
哦,我不做我正在做的那个循环,而是把我所有的点都按顺序用于两个向量,然后把它塞进 2 个单个向量中,然后运行我不知道的 getPerspectiveTransform你可以这样做,我试试看!
-
糟糕。看来我说得太早了。如果你想像我指定的那样做,
getPerspectiveTransform不会像预期的那样工作 4 分 - 我认为它确实如此。您想要其他可以处理> 4分的东西。代替getPerspectiveTransform,使用findHomography: docs.opencv.org/modules/calib3d/doc/…。它基本上接受与getPerspectiveTransform相同的输入。findHomography确定将一组点从一幅图像映射到另一幅图像的最佳变换矩阵,并且误差量最小。
标签: c++ opencv image-processing computer-vision