由于第一帧与第二帧很难做到实时匹配故采用两帧法,第一帧与第二帧匹配,第二帧与第三帧匹配,计算出两个匹配结果的H矩阵,再默认连续帧的情况下图像不会发生较大变化,故第三帧的特征点为 P3=P1*H1*H2
#include <stdio.h>
#include <iostream>
#include "opencv2/core.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/features2d.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/calib3d.hpp"
#include "opencv2/xfeatures2d.hpp"
using namespace std;
using namespace cv;
void on_MouseHandle(int event, int x, int y, int flags, void*param);
int a = 0;
int main()
{
VideoCapture capture("2.avi");
Mat a0;
namedWindow("a0");
while (true)
{
if (!capture.read(a0))
{
cout << "读取视频结束" << endl;
return 0;
}
if (a == 1)
break;
imshow("a0", a0);
setMouseCallback("a0", on_MouseHandle, (void*)&a0);
waitKey(1);
}
Mat img_1, img_2,img_3,img_4,img_5;
Mat des1, des2,des3,des4;
Mat result,result1;
int minHessian = 2000;
capture >> img_1;
capture >> img_2;
Ptr<Feature2D>surf = xfeatures2d::SURF::create(minHessian);
vector<KeyPoint> keypoint1, keypoint2,keypoint3,keypoint4,keypoint5;
double start1 = static_cast<double>(getTickCount());
surf->detect(img_1, keypoint1);
surf->detect(img_2, keypoint2);
surf->compute(img_1, keypoint1, des1);
surf->compute(img_2, keypoint2, des2);
BFMatcher matcher,matcher1;
vector<DMatch>match,match1;
matcher.match(des1, des2, match);
drawMatches(img_1, keypoint1, img_2, keypoint2, match, result, Scalar(255,0,255), Scalar(255,255,0),vector<char>(), DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS);
double time1 = ((double)getTickCount() - start1) / getTickFrequency();
cout << "所用时间为:" << time1 << "秒" << endl;
std::vector<Point2f> obj;
std::vector<Point2f> scene;
for (size_t i = 0; i < match.size(); i++)
{
obj.push_back(keypoint1[match[i].queryIdx].pt);
scene.push_back(keypoint2[match[i].trainIdx].pt);
}
Mat H = findHomography(obj, scene, RANSAC);
for (int i = 0; i < H.cols; i++){
for (int j = 0; j<H.rows; j++)
std::cout << H.at<double>(i, j) << " ";
std::cout << std::endl;
}
imshow("result", result);
img_3=img_2.clone();
capture >> img_4;
img_5 = img_4.clone();
Ptr<ORB>orb = ORB::create();
double start = static_cast<double>(getTickCount());
orb->detect(img_3, keypoint3);
orb->detect(img_4, keypoint4);
orb->compute(img_3, keypoint3, des3);
orb->compute(img_4, keypoint4, des4);
matcher1.match(des3, des4, match1);
drawMatches(img_3, keypoint3, img_4, keypoint4, match1, result1, Scalar(255, 0, 255), Scalar(255, 255, 0), vector<char>(), DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS);
double time = ((double)getTickCount() - start) / getTickFrequency();
cout << "所用时间为:" << time << "秒" << endl;
imshow("result1", result1);
std::vector<Point2f> obj1;
std::vector<Point2f> scene1;
for (size_t i = 0; i < match1.size(); i++)
{
obj1.push_back(keypoint3[match1[i].queryIdx].pt);
scene1.push_back(keypoint4[match1[i].trainIdx].pt);
}
Mat H1 = findHomography(obj1, scene1, RANSAC);
for (int i = 0; i < H1.cols; i++){
for (int j = 0; j<H1.rows; j++)
std::cout << H1.at<double>(i, j) << " ";
std::cout << std::endl;
}
Mat H2 = H*H1;
for (int i = 0; i < H2.cols; i++){
for (int j = 0; j<H2.rows; j++)
std::cout << H2.at<double>(i, j) << " ";
std::cout << std::endl;
}
for (int i = 0; i < keypoint1.size(); i++)
{
keypoint5.push_back(keypoint1.at(i));
keypoint5.at(i).pt.x = keypoint1.at(i).pt.x*H2.at<double>(0, 0) + keypoint1.at(i).pt.y*H2.at<double>(0, 1) + H2.at<double>(0, 2);
keypoint5.at(i).pt.y = keypoint1.at(i).pt.x*H2.at<double>(1, 0) + keypoint1.at(i).pt.y*H2.at<double>(1, 1) + H2.at<double>(1, 2);
}
drawKeypoints(img_5, keypoint5, img_5,Scalar(0,255,255));
drawKeypoints(img_1, keypoint1, img_1, Scalar(0, 255, 255));
imshow("img_1", img_1);
imshow("img_5", img_5);
waitKey(0);
return 0;
}
void on_MouseHandle(int event, int x, int y, int falgs, void* param)
{
if (event == EVENT_LBUTTONDOWN)
{
a = 1;
}
}