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

C++ cv::warpPerspective仅显示扭曲图像的一部分,c++,opencv,image-processing,perspectivecamera,C++,Opencv,Image Processing,Perspectivecamera,我使用getHomography和warpPerspective将图像从正面透视图更改为人眼透视图 它的工作原理是图像扭曲到所需的透视图,但裁剪已关闭。它将扭曲的图像大部分移动到图像框外。我想原因是因为操作导致负坐标 我已经手动计算了用于计算平移矩阵的点,而不是使用任何opencv:s函数进行计算,因为棋盘函数无法检测到正确的点 我想这可以通过对变换矩阵做额外的修改来解决。但这是怎么做到的呢?另外,是否有办法确保变换后的图像沿x轴居中,然后将y轴调整到所需位置 现在执行此任务的代码段: cv::

我使用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);
cv::Mat image;//图像与原始图像一起加载
cv::垫式整经机;//结果图像的容器
cv::Mat H;
std::向量src;
std::向量dst;
//实际上还有几点。
src.push_back(cv::Point2f(264301));
src.push_back(cv::Point2f(434301));
src.push_back(cv::Point2f(243356));
src.push_back(cv::Point2f(476356));
dst.推回(cv::Point2f(243123));
dst.推回(cv::Point2f(476123));
dst.推回(cv::Point2f(243356));
dst.推回(cv::Point2f(476356));
H=cv::findHomography(src、dst、cv_-RANSAC);
cv::透视图(图像,
纽伯斯,
H
cv::尺寸(30003000),
cv::最近点之间的cv扭曲填充异常值
);
cv::namedWindow(“扭曲的persp”,cv::WINDOW\u AUTOSIZE);
cv::imshow(“翘曲persp”,纽伯斯);

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]
P' = [s1*x1, s2*x2, s3*x3, s4*x4;
      s1*y1, s2*y2, s3*y3, s4*y4;
      s1   , s2   , s3   , s4]
使用H制作产品并获得翘曲坐标:

P' = H * P
步骤3:用这4个新点检查x和y的最小值,得到扭曲图像的大小 完成产品后,您将收到以下内容:

P = [0, w, w, 0;
     0, 0, h, h;
     1, 1, 1, 1]
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行的最大值 第二排是米尼和马克西

因此,扭曲图像的大小应为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];
H=[h00,h01,h02 minx;//如果minx我认为这个问题与当前的问题类似

所以我在这里也给你们我的答案:

尝试下面的
单应_warp

void homography_warp(const cv::Mat& src, const cv::Mat& H, cv::Mat& dst);
src
是源图像

H
是您的单应性

dst
是扭曲的图像

homography\u warp
按照他的答案中所述调整你的单应性

//将非齐次二维点的向量转换为齐次二维点的向量。
空到齐次(常数std::vector和非齐次,std::vector和齐次)
{
齐次.调整大小(非齐次.大小());
对于(size_t i=0;i<非齐次.size();i++){
齐次[i].x=非齐次[i].x;
齐次[i].y=非齐次[i].y;
齐次[i].z=1.0;
}
}
//将均匀二维点的向量转换为非均匀二维点的向量。
来自同质(常量std::vector和同质,std::vector和非同质)
{
非齐次.resize(齐次.size());
对于(size_t i=0;i<非齐次.size();i++){
非齐次[i].x=齐次[i].x/齐次[i].z;
非齐次[i].y=齐次[i].y/齐次[i].z;
}
}
//通过单应变换变换二维非齐次点的向量。
std::向量变换通过单应(常数std::向量和点,常数cv::Matx33f和单应)
{
std::载体ph;
至均匀(点、ph);
对于(尺寸i=0;ix;
浮点x_max=std::max_元素(p.begin(),p.end(),[](常量cv::Point2f&lhs,常量cv::Point2f&rhs){return lhs.xx;
浮点y_min=std::min_元素(p.begin(),p.end(),[](常量cv::Point2f&lhs,常量cv::Point2f&rhs){返回lhs.yy;
浮点y_max=std::max_元素(p.begin(),p.end(),[](常量cv::Point2f&lhs,常量cv::Point2f&rhs){return lhs.yy;
返回cv::Rect_(x_min,y_min,x_max-x_min,y_max-y_min);
}
//通过单应H将图像src扭曲到图像dst中。
//生成的dst图像包含整个扭曲图像,如下所示:
//行为与Octave的imperspectivewarp(在“图像”中)相同
//包)参数bbox等于“loose”时的行为。
//看http://octave.s