由于在实际应用过程中,sift,surf等匹配方法很难达到实时匹配的效果要求,故而采用双帧法进行匹配,即目标图像与第一帧之间默认有较大差异,故此之间采用复杂匹配算法,而在此后视频播放过程中,默认帧与帧之间的变化程度不大,故此可以采用简单匹配算法以满足匹配的实时性要求。
此方法具体过程为:目标模板与第一帧采用复杂匹配算法,之后对匹配结果进行RANSAC方法求出两帧之间的基础变换矩阵H1。而第一帧与后面帧采用简单算法匹配,之后对匹配结果进行RANSAC方法求出两帧之间的基础变换矩阵H2.之后求出H3=H1*H2为目标模板与待匹配图像之间的基础变换矩阵H3.此方法不但可以解决匹配的实时性问题,而且抗干扰能力强,如若发生目标物体被遮挡等现象,我们仍旧可以通过变换矩阵来求出目标物体在待匹配图像上方的位置。具体实验方法与结果如下:
#include<opencv2\opencv.hpp>
#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"
#include<iostream>
using namespace std;
using namespace cv;
#define sizes 20
int x = 0;
int y = 0;
bool match(Mat a,Mat b, vector<DMatch> &vec)
{
BFMatcher matches;
vector<DMatch>matcher;
matches.match(a, b, matcher);
vec = matcher;
return 1;
}
Mat geth(vector<DMatch>&vec,vector<KeyPoint>&a,vector<KeyPoint>&b)
{
Mat H;
vector<Point>x, y;
for (int i = 0; i < vec.size(); i++)
{
x.push_back(a.at(vec.at(i).queryIdx).pt);
y.push_back(b.at(vec.at(i).trainIdx).pt);
}
H = findHomography(x, y, RANSAC);
return H;
}
Mat Orb(Mat a, Mat b)
{
vector<KeyPoint>keypoint1, keypoint2;
Mat des1, des2;
Mat result;
Ptr<ORB>orb = ORB::create();
orb->detect(a, keypoint1);
orb->detect(b, keypoint2);
orb->compute(a, keypoint1, des1);
orb->compute(b, keypoint2, des2);
vector<DMatch>vec;
match(des1, des2, vec);
result = geth(vec, keypoint1, keypoint2);
return result;
}
Mat Sift(Mat a, Mat b)
{
vector<KeyPoint>keypoint1, keypoint2;
Mat des1, des2;
Mat result;
Ptr<Feature2D>sift = xfeatures2d::SIFT::create();
sift->detect(a, keypoint1);
sift->detect(b, keypoint2);
sift->compute(a, keypoint1, des1);
sift->compute(b, keypoint2, des2);
vector<DMatch>vec;
match(des1, des2, vec);
result=geth(vec, keypoint1, keypoint2);
return result;
}
Mat FastBreif(Mat &a, Mat &b)
{
Mat des1, des2,result;
vector<KeyPoint> keypoint1,keypoint2;//关键点KeyPoint类
Ptr<FastFeatureDetector> fast = FastFeatureDetector::create();
fast->detect(a, keypoint1);;
fast->detect(b, keypoint2);
Ptr<Feature2D>breif = xfeatures2d::BriefDescriptorExtractor::create();
breif->compute(a, keypoint1, des1);
breif->compute(b, keypoint2, des2);
vector<DMatch>vec;
match(des1, des2, vec);
result = geth(vec, keypoint1, keypoint2);
return result;
}
void printH(Mat &H)
{
for (int i = 0; i < H.rows; i++)
{
for (int j = 0; j < H.cols; j++)
{
cout << H.at<double>(i, j) << " ";
}
cout << endl;
}
}
void draw(Mat &a,int length,int width)
{
line(a, cvPoint(length - sizes / 2, width), cvPoint(length + sizes / 2, width), Scalar(0, 0, 255), 5);
line(a, cvPoint(length, width - sizes / 2), cvPoint(length, width + sizes / 2), Scalar(0, 0, 255), 5);
}
void sub(Mat &d,Mat &H,int c,int b)
{
int z1, v1, q1;
z1 = c * H.at<double>(0, 0) + b * H.at<double>(0, 1) + H.at<double>(0, 2);
v1 = c * H.at<double>(1, 0) + b* H.at<double>(1, 1) + H.at<double>(1, 2);
q1 = c * H.at<double>(2, 0) + b* H.at<double>(2, 1) + H.at<double>(2, 2);
cout << z1 << " " << v1 << " " << q1 << endl;
if (q1 != 0)
{
z1 = z1 / q1;
v1 = v1 / q1;
}
x = z1;
y = v1;
draw(d, z1, v1);
}
void main()
{
const int x1 = 518;
const int y1 = 179;
const int length_x = 250;
const int width_y = 250;
Mat img_1 = imread("7.jpg");
VideoCapture capture("6.mp4");
Mat img_2,img_3;
capture >> img_2;
for (int i = 0; i <40; i++)
{
capture >> img_3;
}
resize(img_3, img_3, Size(img_3.cols / 2, img_3.rows / 2), 0, 0, INTER_CUBIC);
resize(img_2, img_2, Size(img_2.cols / 2, img_2.rows / 2), 0, 0, INTER_CUBIC);
imwrite("8.jpg", img_2);
imwrite("9.jpg", img_3);
Mat img_4 = img_2.clone();
Mat img_5 = img_1.clone();
Mat img_6 = img_3.clone();
Mat H1=Sift(img_1, img_2);
//Mat H1 = Orb(img_1, img_2);
printH(H1);
draw(img_1,length_x,width_y);
sub(img_2, H1, length_x, width_y);
//
Mat H2 = FastBreif(img_4, img_3);
printH(H2);
draw(img_4, x, y);
sub(img_3, H2, x, y);
//
Mat H3 = H2*H1;
printH(H3);
draw(img_5, x1, y1);
sub(img_6, H3, x1, y1);
imshow("img_1", img_1);
imshow("img_2", img_2);
imshow("img_3", img_3);
imshow("img_4", img_4);
imshow("img_5", img_5);
imshow("img_6", img_6);
waitKey(0);
}
实验结果如下:
H矩阵与变换坐标为:
1.18139 -0.00914043 -120.436
0.0067695 1.17805 -62.865
6.55392e-006 -1.79877e-005 1
172 233 0
1.00411 0.000401082 -2.31253
0.000444301 1.00373 -1.31413
5.7269e-006 3.37023e-006 1
170 232 1
1.18624 -0.00866394 -123.269
0.00731099 1.18246 -64.4668
1.33424e-005 -1.40697e-005 0.999098
489 150 1