I have created a stitching program that can stitch any number of images together into a single mosaic. The efficiency of the program needs work which I am trying to improve. My goal is to create a list of the already found keypoints and descriptors so the program doesn't need to re do work it has already done and this way memory isn't overloaded if there are too many images. To do this I need to have the keypoints and descriptors transformed along side the actual images themselves. Here is the code I camp up with ( I think i am getting mixed up with warpPerspective()
and perspectiveTransform()
) .
std::tuple<Mat, std::vector<KeyPoint>, Mat> stitchMatches(Mat image1,Mat image2, Mat homography, std::vector<KeyPoint> kp1, std::vector<KeyPoint> kp2 , Mat desc1, Mat desc2){
Mat result, destination, descriptors_updated;
vector<Point2f> fourPoint;
std::vector<KeyPoint> kp1New, kp2New, keypoints_updated;
//-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));
perspectiveTransform(Mat(fourPoint), destination, homography);
//- Get points used to determine Htr
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);
//- Htr use to map image one to result in line with the alredy warped image 1
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_8UC3,cv::Scalar(0,0,0));
warpPerspective(image2, result, Htr, result.size(), INTER_LINEAR, BORDER_TRANSPARENT, 0);
warpPerspective(image1, result, (Htr*homography), result.size(), INTER_LINEAR, BORDER_TRANSPARENT,0);
// transform perspective of keypoints and descriptros of kp1 and desc1
perspectiveTransform(kp2, kp2New, (Htr));
perspectiveTransform(kp1, kp1New, (Htr*homography));
perspectiveTransform(desc2, desc2, (Htr));
perspectiveTransform(desc1, desc1, (Htr*homography));
//create new vector of keypoints containing the thranformed kp1 and kp2
keypoints_updated.reserve(kp1New.size() + kp2New.size());
keypoints_updated.insert(keypoints_updated.end(), kp1New.begin(), kp1New.end());
keypoints_updated.insert(keypoints_updated.end(), kp2New.begin(), kp2New.end());
//create a new Mat including the descriports from desc1 and desc2
descriptors_updated.push_back(desc1);
descriptors_updated.push_back(desc2);
//------------TEST TO see if keypoints have moved
Mat img_keypoints;
drawKeypoints( result, keypoints_updated, img_keypoints, Scalar::all(-1), DrawMatchesFlags::DEFAULT );
imshow("Keypoints 1", img_keypoints );
waitKey();
destroyAllWindows();
return {result, keypoints_updated, descriptors_updated};
}