使用opencv进行图像扭曲
我想使用opencv执行图像扭曲。 我已经检测到图像的4个角ex 4000x4000,并使用opencv中的getPerspectiveTransform获得变换矩阵。 现在,我想在图像中心扭曲图像。 所以我用了透视法。 我输入的源图像的大小是450x450,我使用我为整个图像计算的变换矩阵 但屏幕上没有显示任何内容。 感谢您的帮助 下面是示例代码和示例图像 这是源图像。 检测到此图像 这是我希望从image.src_裁剪代码中获得的扭曲区域 这就是结果使用opencv进行图像扭曲,opencv,image-processing,warp,Opencv,Image Processing,Warp,我想使用opencv执行图像扭曲。 我已经检测到图像的4个角ex 4000x4000,并使用opencv中的getPerspectiveTransform获得变换矩阵。 现在,我想在图像中心扭曲图像。 所以我用了透视法。 我输入的源图像的大小是450x450,我使用我为整个图像计算的变换矩阵 但屏幕上没有显示任何内容。 感谢您的帮助 下面是示例代码和示例图像 这是源图像。 检测到此图像 这是我希望从image.src_裁剪代码中获得的扭曲区域 这就是结果 由于getPerspectiveTr
由于getPerspectiveTransform方法使用了错误的值,因此转换失败。您似乎混淆了如何创建输出图像以及如何从该图像的数据填充目标角点 另外,在数组左上、右上、左下、右下中链接右角也是很重要的,你似乎把它们弄混了 此示例将向您展示如何连接正确的点并在空输出图像中输出:
// Assuming your source image is called 'sourceImage' and you have the corner points you need:
// Create vectors to store the corners
vector<Point2f> originalCorners;
vector<Point2f> destinationCorners;
// Put the Sudoku corners in your originalCorners
originalCorners.clear();
originalCorners.push_back(Point2f(lt.x, lt.y);
originalCorners.push_back(Point2f(rt.x, rt.y);
originalCorners.push_back(Point2f(lb.x, lb.y);
originalCorners.push_back(Point2f(rb.x, rb.y);
// Output image size of 450x450
int ouputImageWidth = 450;
int outputImageHeight = 450;
// Create an empty image (450x450) to output your transformation result in
Mat transformedOutputImage(ouputImageWidth, outputImageHeight, sourceImage.type());
// Now put the corners of the output image so the warp knows where to warp to
destinationCorners.clear();
destinationCorners.push_back(Point2f(0, 0));
destinationCorners.push_back(Point2f(ouputImageWidth, 0));
destinationCorners.push_back(Point2f(0, outputImageHeight));
destinationCorners.push_back(Point2f(ouputImageWidth, outputImageHeight));
// Now we have all corners sorted, so we can create the warp matrix
Mat warpMatrix = getPerspectiveTransform(originalCorners, destinationCorners);
// And now we can warp the Sudoku in the new image
warpPerspective(sourceImage, transformedOutputImage, warpMatrix, Size(ouputImageWidth, ouputImageHeight));
现在,假设您知道要扭曲的图像部分的角点。如果你不知道如何得到中间正方形的点,我建议你看看
但是,只要有四个角点,这种方法就可以工作。您甚至可以通过手动查找中间的方形角点并插入这些角点来进行尝试。谢谢您的回答。我知道变换矩阵是计算整个图像的4000乘4000。但我将src_crop450 x 450图像作为源图像输入到透视图中。所以我认为src_裁剪图像也在使用变换矩阵进行扭曲。这是不可能的?如果我不知道src_裁剪图像的角点,我想为src_裁剪图像扭曲图像您应该只使用sourceImage 4000x4000,而不是裁剪它。裁剪将导致原始角点阵列指向不存在的角点。我从来没有在扭曲之前做过压缩,但这可能会导致您的输出完全是黑色的?实际上,我使用压缩图像是为了减少程序的运行时间。使用matchTemplate函数检测裁剪图像的中心点。所以我猜裁剪图像扭曲而不是整张图像扭曲是扭曲的短时间。我迭代整张图像的角点,以减少整张图像扭曲中心周围的误差。因此,我们从整个图像中得到变换矩阵,并尝试对裁剪后的图像进行扭曲后通过模板匹配找到中心点。原因是中心点误差接近中心,但扭曲整个图像需要很长时间。因此,我们尝试在仅围绕中心扭曲后,对整个图像的角点进行最终扭曲,其中中心误差较小。WarpPerspective函数不支持这种方式?据我所知,这是不可能的。您应该做的是:裁剪图像,然后在裁剪图像中检测要扭曲的角点,然后扭曲。另一种方法是首先调整原始图像的大小,然后找到角点,但这可能也很慢,尽管您可以看到是否存在性能差异。
// Assuming your source image is called 'sourceImage' and you have the corner points you need:
// Create vectors to store the corners
vector<Point2f> originalCorners;
vector<Point2f> destinationCorners;
// Put the Sudoku corners in your originalCorners
originalCorners.clear();
originalCorners.push_back(Point2f(lt.x, lt.y);
originalCorners.push_back(Point2f(rt.x, rt.y);
originalCorners.push_back(Point2f(lb.x, lb.y);
originalCorners.push_back(Point2f(rb.x, rb.y);
// Output image size of 450x450
int ouputImageWidth = 450;
int outputImageHeight = 450;
// Create an empty image (450x450) to output your transformation result in
Mat transformedOutputImage(ouputImageWidth, outputImageHeight, sourceImage.type());
// Now put the corners of the output image so the warp knows where to warp to
destinationCorners.clear();
destinationCorners.push_back(Point2f(0, 0));
destinationCorners.push_back(Point2f(ouputImageWidth, 0));
destinationCorners.push_back(Point2f(0, outputImageHeight));
destinationCorners.push_back(Point2f(ouputImageWidth, outputImageHeight));
// Now we have all corners sorted, so we can create the warp matrix
Mat warpMatrix = getPerspectiveTransform(originalCorners, destinationCorners);
// And now we can warp the Sudoku in the new image
warpPerspective(sourceImage, transformedOutputImage, warpMatrix, Size(ouputImageWidth, ouputImageHeight));