OpenCV 中心单应
OpenCV Center Homography
我正在尝试创建拼接算法。我已经成功地创建了它,需要进行一些调整。下面的照片是到目前为止我的拼接程序的示例。我能够为它提供一个无序列表的图像(只要图像在飞行路径上或并排放置,无论它们彼此的方向如何,它都会起作用。
问题是如果图片颠倒了,有些图片就不会出现在最终产品中。这是实际拼接的代码。假设正确完成了查找关键点、匹配和单应性。
通过更改此代码,是否可以将第一张图片居中放置在目标空白图片上,并仍然与其拼接。此外,我在堆栈溢出 (Opencv Image Stitching or Panorama ) 上得到了这段代码,但我不确定它是如何工作的,如果有人能解释它我会很高兴。
提前感谢您的帮助!
Mat stitchMatches(Mat image1,Mat image2, Mat homography){
Mat result;
vector<Point2f> fourPoint;
//-Get the four corners of the first image (master)
fourPoint.push_back(Point2f (0,0));
fourPoint.push_back(Point2f (image1.size().width,0));
fourPoint.push_back(Point2f (0, image1.size().height));
fourPoint.push_back(Point2f (image1.size().width, image1.size().height));
Mat destination;
perspectiveTransform(Mat(fourPoint), destination, homography);
double min_x, min_y, tam_x, tam_y;
float min_x1, min_x2, min_y1, min_y2, max_x1, max_x2, max_y1, max_y2;
min_x1 = min(fourPoint.at(0).x, fourPoint.at(1).x);
min_x2 = min(fourPoint.at(2).x, fourPoint.at(3).x);
min_y1 = min(fourPoint.at(0).y, fourPoint.at(1).y);
min_y2 = min(fourPoint.at(2).y, fourPoint.at(3).y);
max_x1 = max(fourPoint.at(0).x, fourPoint.at(1).x);
max_x2 = max(fourPoint.at(2).x, fourPoint.at(3).x);
max_y1 = max(fourPoint.at(0).y, fourPoint.at(1).y);
max_y2 = max(fourPoint.at(2).y, fourPoint.at(3).y);
min_x = min(min_x1, min_x2);
min_y = min(min_y1, min_y2);
tam_x = max(max_x1, max_x2);
tam_y = max(max_y1, max_y2);
Mat Htr = Mat::eye(3,3,CV_64F);
if (min_x < 0){
tam_x = image2.size().width - min_x;
Htr.at<double>(0,2)= -min_x;
}
if (min_y < 0){
tam_y = image2.size().height - min_y;
Htr.at<double>(1,2)= -min_y;
}
result = Mat(Size(tam_x*2,tam_y*2), CV_32F);
warpPerspective(image2, result, Htr, result.size(), INTER_LINEAR, BORDER_CONSTANT, 0);
warpPerspective(image1, result, (Htr*homography), result.size(), INTER_LINEAR, BORDER_TRANSPARENT,0);
return result;`
通常很容易将图像居中;您只需创建一个更大的矩阵,用零(或您想要的任何颜色)填充,然后在中心定义一个与图像大小相同的 ROI,然后将其放置在那里。但是,您通常不能对两个图像执行此操作。问题是,如果图像被移动或旋转,使其部分超出目标图像边界,那么从 warpPerspective
返回的变形图像会在这些边界处被截断。您需要做的是创建填充图像,将未扭曲的图像插入您喜欢的任何位置,并通过向这些像素添加平移来修改变换(在本例中为单应性)。
例如,如果居中图像的左上角点位于填充图像的 (400,500)
处,则您需要将 (400, 500)
的翻译添加到单应性中,以便像素得到映射到正确的 space,只要你填充的图像足够大,它的 none 就会被截掉。
您需要创建平移单应性并将其与原始单应性组合以添加翻译。例如,假设填充图像内非扭曲图像的锚点位于 (x,y)
.最后两列给出了单应性的翻译;如果你的单应性是 3x3
矩阵 H
那么(使用正常的数学索引) H(1,3)
是你在 x
中的翻译而 H(2,3)
是 [=20 中的翻译=] 由你的单应性给出。所以我们需要创建一个新的身份单应性 H_t
并将这些翻译添加到:
1 0 x
H_t = 0 1 y
0 0 1
然后你可以用你原来的单应性 H
(使用矩阵乘法):H_n = H_t * H
来组合它。使用新的单应性 H_n
我们可以像往常一样使用 warpPerspective
将图像变形到这个填充的 space 并添加平移以将其移动到正确的位置。
您也可以自动执行此操作以根据需要精确地填充图像,这样您就不会有多余的填充,并且填充只会根据需要拉伸。请参阅我的回答 ,详细了解如何计算它并将图像变形为填充 space。
我正在尝试创建拼接算法。我已经成功地创建了它,需要进行一些调整。下面的照片是到目前为止我的拼接程序的示例。我能够为它提供一个无序列表的图像(只要图像在飞行路径上或并排放置,无论它们彼此的方向如何,它都会起作用。
问题是如果图片颠倒了,有些图片就不会出现在最终产品中。这是实际拼接的代码。假设正确完成了查找关键点、匹配和单应性。
通过更改此代码,是否可以将第一张图片居中放置在目标空白图片上,并仍然与其拼接。此外,我在堆栈溢出 (Opencv Image Stitching or Panorama ) 上得到了这段代码,但我不确定它是如何工作的,如果有人能解释它我会很高兴。
提前感谢您的帮助!
Mat stitchMatches(Mat image1,Mat image2, Mat homography){
Mat result;
vector<Point2f> fourPoint;
//-Get the four corners of the first image (master)
fourPoint.push_back(Point2f (0,0));
fourPoint.push_back(Point2f (image1.size().width,0));
fourPoint.push_back(Point2f (0, image1.size().height));
fourPoint.push_back(Point2f (image1.size().width, image1.size().height));
Mat destination;
perspectiveTransform(Mat(fourPoint), destination, homography);
double min_x, min_y, tam_x, tam_y;
float min_x1, min_x2, min_y1, min_y2, max_x1, max_x2, max_y1, max_y2;
min_x1 = min(fourPoint.at(0).x, fourPoint.at(1).x);
min_x2 = min(fourPoint.at(2).x, fourPoint.at(3).x);
min_y1 = min(fourPoint.at(0).y, fourPoint.at(1).y);
min_y2 = min(fourPoint.at(2).y, fourPoint.at(3).y);
max_x1 = max(fourPoint.at(0).x, fourPoint.at(1).x);
max_x2 = max(fourPoint.at(2).x, fourPoint.at(3).x);
max_y1 = max(fourPoint.at(0).y, fourPoint.at(1).y);
max_y2 = max(fourPoint.at(2).y, fourPoint.at(3).y);
min_x = min(min_x1, min_x2);
min_y = min(min_y1, min_y2);
tam_x = max(max_x1, max_x2);
tam_y = max(max_y1, max_y2);
Mat Htr = Mat::eye(3,3,CV_64F);
if (min_x < 0){
tam_x = image2.size().width - min_x;
Htr.at<double>(0,2)= -min_x;
}
if (min_y < 0){
tam_y = image2.size().height - min_y;
Htr.at<double>(1,2)= -min_y;
}
result = Mat(Size(tam_x*2,tam_y*2), CV_32F);
warpPerspective(image2, result, Htr, result.size(), INTER_LINEAR, BORDER_CONSTANT, 0);
warpPerspective(image1, result, (Htr*homography), result.size(), INTER_LINEAR, BORDER_TRANSPARENT,0);
return result;`
通常很容易将图像居中;您只需创建一个更大的矩阵,用零(或您想要的任何颜色)填充,然后在中心定义一个与图像大小相同的 ROI,然后将其放置在那里。但是,您通常不能对两个图像执行此操作。问题是,如果图像被移动或旋转,使其部分超出目标图像边界,那么从 warpPerspective
返回的变形图像会在这些边界处被截断。您需要做的是创建填充图像,将未扭曲的图像插入您喜欢的任何位置,并通过向这些像素添加平移来修改变换(在本例中为单应性)。
例如,如果居中图像的左上角点位于填充图像的 (400,500)
处,则您需要将 (400, 500)
的翻译添加到单应性中,以便像素得到映射到正确的 space,只要你填充的图像足够大,它的 none 就会被截掉。
您需要创建平移单应性并将其与原始单应性组合以添加翻译。例如,假设填充图像内非扭曲图像的锚点位于 (x,y)
.最后两列给出了单应性的翻译;如果你的单应性是 3x3
矩阵 H
那么(使用正常的数学索引) H(1,3)
是你在 x
中的翻译而 H(2,3)
是 [=20 中的翻译=] 由你的单应性给出。所以我们需要创建一个新的身份单应性 H_t
并将这些翻译添加到:
1 0 x
H_t = 0 1 y
0 0 1
然后你可以用你原来的单应性 H
(使用矩阵乘法):H_n = H_t * H
来组合它。使用新的单应性 H_n
我们可以像往常一样使用 warpPerspective
将图像变形到这个填充的 space 并添加平移以将其移动到正确的位置。
您也可以自动执行此操作以根据需要精确地填充图像,这样您就不会有多余的填充,并且填充只会根据需要拉伸。请参阅我的回答