目录
一,特征识别
常用的有ORB、SIFT、SURF
c++ opencv中的SURF不是免费开源的,ORB、SIFT是免费开源的。
这里以SIFT为例
vector<KeyPoint> keyPoints;
Mat descriptors;
Ptr<cv::SIFT> detector = cv::SIFT::create(); //创建一个检测器
detector->detectAndCompute(img, Mat(), keyPoints, descriptors);
每个特征点由2部分数据组成,一个是KeyPoint,里面是特征点的具体坐标,一个是描述符,里面是描述特征的向量。
特征识别的输出结果是一堆特征点,vector<KeyPoint> keyPoints里面放所有的坐标,Mat descriptors相当于矩阵,里面放所有的描述符向量。
即,vector<KeyPoint> keyPoints的长度和Mat descriptors的行数一致,按顺序对应。
如果是ORB:
vector<KeyPoint> keyPoints;
Mat descriptors;
cv::Ptr<cv::ORB> orb = cv::ORB::create();//创建一个检测器
orb->detectAndCompute(img, Mat(), keyPoints, descriptors);
二,特征匹配
参考匹配器
这里以knnMatch为例
vector<vector<DMatch>> matches;
try {
FlannBasedMatcher().knnMatch(descriptors2, descriptors1, matches, 2);
}
catch (Exception &e) {
cout << e.what();
}
vector<DMatch> goodMatch;
for (int i = 0; i < matches.size(); i++)goodMatch.push_back(matches[i][0]);
这样就拿到了vector<DMatch> goodMatch,长度取决于descriptors2和descriptors1中长度的较小值。
DMatch里面存着2个特征列表的id,按照id去把对应的特征点依次扣出来,即得到2个匹配好的特征列表。
三,变换求解
根据2个匹配好的特征列表,求仿射变换
vector<Point2f> target_pts, template_pts;
Mat inliers, homography;
homography = cv::findHomography(target_pts, template_pts, RANSAC, 5, inliers);
输出的inliers是一个1列的矩阵,每一行的数表示对应的2个特征是否真实匹配上。
输出的homography 是一个3*3的矩阵,表示的变换含义如下: