我创建了一种拼接算法,可以将许多图像拼接在一起。它没有使用捆绑调整,但这是后来的补充。
在找到两个图像之间的单应性后,我正在缝合我做一系列翻译,透视变换和warpPerspectives来实现我的最终结果。以下两个图像是两个图像拼接,第一个是从左到右传递的图像,后者是从右到左传递的图像。每个图像包括关于为缝合图像而创建的平移矩阵的信息。结果图像是空白图像的新填充大小,其中包含拼接图像(您所看到的图像)。
Image 1: Min x 478.711 Min y 3.16 Max x 1853.66 Max y 1449.42
Image 2: Min x 0 Min y 0 Max x 1200 Max y 900
Result Image: Min x 0 Min y 0 Max x 1853.66 Max y 1449.42
[1, 0, 0;
0, 1, 0; Stitch 2
0, 0, 1]
Image 1: Min x -671.462 Min y -461.816 Max x 652.656 Max y 655.324
Image 2: Min x 0 Min y 0 Max x 1200 Max y 900
Result Image: Min x -671.462 Min y -461.816 Max x 1200 Max y 900
[1, 0, 672;
0, 1, 462; Stitch2/Rev
0, 0, 1]
看起来效果很好,非常棒。然而,当我在3个图像中运行代码管道时,我会得到奇怪的线条,黑色背景应该是,然后我的填充开始失败。再次参考图像和翻译。
---------------------
Image 1: Min x 390.279 Min y 72.4343 Max x 1658.93 Max y 1110.17
Image 2: Min x 0 Min y 0 Max x 1200 Max y 900
Result Image: Min x 0 Min y 0 Max x 1658.93 Max y 1110.17
[1, 0, 0;
0, 1, 0;
0, 0, 1]
Image 1: Min x 439.817 Min y -20.4711 Max x 2205.2 Max y 1288.93
Image 2: Min x 0 Min y 0 Max x 1200 Max y 900
Result Image: Min x 0 Min y -20.4711 Max x 2205.2 Max y 1288.93
[1, 0, 0;
0, 1, 21;
0, 0, 1]
---------------------
本节的代码如下。任何帮助表示赞赏。
Mat result, descriptors_updated;
vector<Point2f> fourPointImage1, fourPointImage2, image1dst, image2dst;
vector<KeyPoint> keypoints_updated;
float min_x, min_y, max_x, max_y, result_x, result_y, img1_min_x, img1_min_y, img2_min_x, img2_min_y,img1_max_x, img1_max_y, img2_max_x, img2_max_y, result_min_x, result_max_x, result_min_y, result_max_y;
//get four corners of image MATs
fourPointImage1 = fourCorners(image1);
fourPointImage2 = fourCorners(image2);
//get the min and max corners
tie(min_x, min_y, max_x, max_y) = minMaxCorners(fourPointImage1);
//- Htr use to map image one to result in line with the already warped image two
Mat Htr = Mat::eye(3,3,CV_64F);
if (min_x < 0){
max_x = image2.size().width - min_x;
Htr.at<double>(0,2)= -min_x;
}
if (min_y < 0){
max_y = image2.size().height - min_y;
Htr.at<double>(1,2)= -min_y;
}
//- Need to create a padded blank image to accomodate stitched images.
//- Must first determine where the translations of the two images will end up to determine if shift is needed and how much to pad blank image
perspectiveTransform(fourPointImage1, image1dst, Htr*homography);
perspectiveTransform(fourPointImage2, image2dst, Htr);
//- Now determine what is out of bounds
//New coordinates for image 1
tie(img1_min_x, img1_min_y,img1_max_x,img1_max_y) = minMaxCorners(image1dst);
cout << "Image 1: Min x " << img1_min_x << " Min y " << img1_min_y << " Max x " << img1_max_x << " Max y " << img1_max_y << endl;
//New coordinates for iamge 2
tie(img2_min_x, img2_min_y,img2_max_x,img2_max_y) = minMaxCorners(image2dst);
cout << "Image 2: Min x " << img2_min_x << " Min y " << img2_min_y << " Max x " << img2_max_x << " Max y " << img2_max_y << endl;
//determine bounding area for resulting images
result_min_x = min(img1_min_x, img2_min_x);
result_max_x = max(img1_max_x, img2_max_x);
result_min_y = min(img1_min_y, img2_min_y);
result_max_y = max(img1_max_y, img2_max_y);
cout << "Result Image: Min x " << result_min_x << " Min y " << result_min_y << " Max x " << result_max_x << " Max y " << result_max_y << endl;
//Determine size of padded result (blank image) to be used for stitching
result_x = (abs(floor(result_min_x)) + abs(ceil(result_max_x)));
result_y = (abs(floor(result_min_y)) + abs(ceil(result_max_y)));
result = Mat(Size(result_x,result_y), CV_32FC1,Scalar(0,0,0));
//-Move the images to the postiive by creating a matrix to represent the translation
int anchor_x, anchor_y = 0;
Mat translation = Mat::eye(3,3,CV_64F);
if(result_min_x < 0){
anchor_x = (int) floor(result_min_x);
translation.at<double>(0,2) -= anchor_x;
}
if(result_min_y < 0){
anchor_y = (int) floor(result_min_y);
translation.at<double>(1,2) -= anchor_y;
}
cout << translation << endl;
//Warp each image accordingly to the new padded result image
warpPerspective(image2, result, translation, result.size(), INTER_LINEAR, BORDER_TRANSPARENT, 0);
warpPerspective(image1, result, (translation*homography), result.size(), INTER_LINEAR, BORDER_TRANSPARENT,0);
vector<Point2f> fourCorners(Mat image){
vector<Point2f> corners;
corners.push_back(Point2f (0,0));
corners.push_back(Point2f (image.size().width,0));
corners.push_back(Point2f (0, image.size().height));
corners.push_back(Point2f (image.size().width, image.size().height));
return(corners);
}
tuple<float, float, float, float> minMaxCorners(vector<Point2f> imageMatrix){
float min_x1, min_x2, min_y1, min_y2, max_x1, max_x2, max_y1, max_y2,img_min_x, img_min_y, img_max_x, img_max_y;
min_x1 = min(imageMatrix.at(0).x, imageMatrix.at(1).x);
min_x2 = min(imageMatrix.at(2).x, imageMatrix.at(3).x);
min_y1 = min(imageMatrix.at(0).y, imageMatrix.at(1).y);
min_y2 = min(imageMatrix.at(2).y, imageMatrix.at(3).y);
max_x1 = max(imageMatrix.at(0).x, imageMatrix.at(1).x);
max_x2 = max(imageMatrix.at(2).x, imageMatrix.at(3).x);
max_y1 = max(imageMatrix.at(0).y, imageMatrix.at(1).y);
max_y2 = max(imageMatrix.at(2).y, imageMatrix.at(3).y);
img_min_x = min(min_x1, min_x2);
img_min_y = min(min_y1, min_y2);
img_max_x = max(max_x1, max_x2);
img_max_y = max(max_y1, max_y2);
return{img_min_x,img_min_y, img_max_x, img_max_y };
}
编辑我不确定,但有时只会出现,如下图所示。