cv :: warpPerspective仅显示扭曲图像的一部分

Ein*_*ren 3 c++ opencv image-processing perspectivecamera

我通过使用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<cv::Point2f> src;
std::vector<cv::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);
Run Code Online (Sandbox Code Playgroud)

小智 7

Opencv提供了非常方便的方式来进行转换.你唯一要做的就是通过findHomography来处理单应性返回.实际上,您提供的图像中的某些点可能位于x轴或y轴的负部分.所以你必须在扭曲图像之前做一些检查.

步骤1:使用findHomography找到单应性H,您将获得单应性的经典结构

H = [ h00, h01, h02;
      h10, h11, h12;
      h20, h21,   1];
Run Code Online (Sandbox Code Playgroud)

第2步:在变形后搜索图像角落的位置

那么让我来定义角落的顺序:

(0,0) ________ (0, w)
     |        |
     |________|
(h,0)          (h,w)
Run Code Online (Sandbox Code Playgroud)

要做到这一点,只需创建一个这样的矩阵:

P = [0, w, w, 0;
     0, 0, h, h;
     1, 1, 1, 1]
Run Code Online (Sandbox Code Playgroud)

使用H制作产品并获得扭曲坐标:

P' = H * P
Run Code Online (Sandbox Code Playgroud)

第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]
Run Code Online (Sandbox Code Playgroud)

因此,要获得新的有效坐标,只需将第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];
Run Code Online (Sandbox Code Playgroud)

第5步:扭曲图像

  • 这在第 4 步之前都是正确的。向单应变换矩阵添加偏移不起作用。相反,创建一个 3x3 单位矩阵(我将其称为 `T`),将转换值放入 `t02` 和 `t12`,然后创建一个新的单应矩阵 `H' = T * H`。在对 `warpPerspective` 的调用中使用 `H'。 (2认同)