2017-04-05 185 views
0

我想使用opencv执行图像变形。 我已经检测到图像的4个角((ex)4000x4000),并在opencv中使用getPerspectiveTransform获得了变换矩阵。 现在,我想在图像中心扭曲图像。 所以我用warpPerspective。 我输入的源图像的大小是450x450,我使用我为整个图像计算的变换矩阵。图像使用opencv变形

但屏幕上没有显示任何内容。 任何帮助表示赞赏。

这里是示例代码和示例图像。

这是源图像。 This is source image.

该图像被检测到的 This image is detected

这是我从图像要翘曲区域。(src_crop在代码)

enter image description here

这是结果。

enter image description here

 source[0] = Point2f(lt.x, lt.y); 
     source[1] = Point2f(rt.x, rt.y); 
     source[2] = Point2f(rb.x, rb.y); 
     source[3] = Point2f(lb.x, lb.y); 

     dst[0] = Point2f(6, 10); 
     dst[1] = Point2f(3899, 7); 
     dst[2] = Point2f(3901, 3899); 
     dst[3] = Point2f(9, 3902); 

     Mat transformMatrix ; 
     transformMatrix = getPerspectiveTransform(source, dst); 



     Mat dstFrame ; 
     warpPerspective(src_crop, dstFrame, transformMatrix, Size(450, 450)); 

回答

1

,因为你使用了错误的值,请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)); 

现在,这是假定你知道你要扭曲的图像部分的角点。如果你不知道如何获得中间广场的积分,我建议你看看these excellent answers

但是,只要你有四个角点这个方法将工作。您甚至可以通过手动查找中间方角点并插入这些点来尝试。

+0

感谢您的回答。我知道计算整个图像的转换矩阵(4000乘4000)。但我输入src_crop(450乘450)的图像warpPerspective作为源图像。所以我认为src_crop图像使用变换矩阵变形。是不可能的?如果我不知道src_crop图像的角点,我想为src_crop图像翘曲图像 – eonjeo

+0

您应该使用'sourceImage'(4000x4000)而不是剪裁它。裁剪将导致您的'originalCorners'数组指向不存在的角点。在翘曲之前,我从来没有做过纠错,但这可能会导致您的输出完全黑色的事实? – Jurjen

+0

其实我使用裁剪图像是因为减少了程序的运行时间。我使用matchTemplate函数来检测裁剪图像的中心点。所以我猜想裁剪图像变形而不是整个图像变形是变形的时间很短。 – eonjeo