我通过使用getHomography和warpPerspective将图像从前视角更改为出价视图.
它的工作原理是图像扭曲到所需的视角,但裁剪关闭.它将扭曲的图像移动到图像框之外.我假设原因是因为操作导致负坐标.
我已经计算了手动计算翻译矩阵的点,而不是通过使用任何opencv:s函数来计算,因为棋盘函数未能检测到正确的点.
我想这可以通过对转换矩阵进行其他更改来解决.但那怎么办?另外,有没有办法确保变换后的图像沿x轴居中,然后将y轴调整到所需位置?
现在完成工作的代码段:
cv::Mat image; // image is loaded with the original image
cv::Mat warpPers; // The container for the resulting image
cv::Mat H;
std::vector<:point2f> src;
std::vector<:point2f> dst;
// In reality several more points.
src.push_back(cv::Point2f(264,301));
src.push_back(cv::Point2f(434,301));
src.push_back(cv::Point2f(243,356));
src.push_back(cv::Point2f(476,356));
dst.push_back(cv::Point2f(243,123));
dst.push_back(cv::Point2f(476,123));
dst.push_back(cv::Point2f(243,356));
dst.push_back(cv::Point2f(476,356));
H = cv::findHomography(src, dst, CV_RANSAC);
cv::warpPerspective(image,
newPers,
H,
cv::Size(3000,3000),
cv::INTER_NEAREST | CV_WARP_FILL_OUTLIERS
);
cv::namedWindow("Warped persp", cv::WINDOW_AUTOSIZE );
cv::imshow( "Warped persp", newPers);
Opencv提供了非常方便的方式来进行转换.你唯一要做的就是通过findHomography来处理单应性返回.
实际上,您提供的图像中的某些点可能位于x轴或y轴的负部分.
所以你必须在扭曲图像之前做一些检查.
步骤1:使用findHomography找到单应性H.
你会得到一个经典的单应性结构
H = [ h00, h01, h02;
h10, h11, h12;
h20, h21, 1];
第2步:在变形后搜索图像角落的位置
那么让我来定义角落的顺序:
(0,0) ________ (0, w)
| |
|________|
(h,0) (h,w)
要做到这一点,只需创建一个这样的矩阵:
P = [0, w, w, 0;
0, 0, h, h;
1, 1, 1, 1]
使用H制作产品并获得扭曲坐标:
P' = H * P
步骤3:使用这些新的4点检查x和y的最小值,并获得扭曲图像的大小
之后,您已经完成了产品,您会收到类似的东西:
P' = [s1*x1, s2*x2, s3*x3, s4*x4;
s1*y1, s2*y2, s3*y3, s4*y4;
s1 , s2 , s3 , s4]
因此,要获得新的有效坐标,只需将第1行和第2行除以第3行
之后检查第一行上列的最小值,以及第二行上行的最小值(使用cvReduce)
找到包含图像的边界框(即warpPerspective函数的dst矩阵的维度),用cvReduce查找每行的最大值
让minx成为第一行(即列)的最小值,maxx(1行的最大值)
miny和maxy为第二排.
所以扭曲图像的大小应该是cvSize(maxx-minx,maxy-miny)
步骤4:对单应性添加校正
检查minx和/或miny是否为负,如果minx < 0然后将-minx添加到h02并且如果miny< 0,然后将-miny添加到h12 所以H应该是:
H = [ h00, h01, h02-minx; //if minx <0
h10, h11, h12-miny; //if miny <0
h20, h21, 1];
第5步:扭曲图像