特征点匹配是图像处理领域寻找不同图像间信息关联的重要方法.由于相机移动导致成像视场发生改变,因此同一个物体会出现在图像中不同的位置,通过特征点匹配可以快速定位物体在新图像中的位置 为后续对图像的进一 步处理提供数据支持。特征点匹配由于数据量小、匹配精确而被 广泛应用在三维重建、视觉定位、运动估计、图像配准等领域.
1.DescriptorMatcher类:
2.暴力匹配
暴力匹配就是计算 训练描述子集合中每个描述子与查询描述 子之间的距离,之后将所有距离排
序,选择距离最小或者距离满足阈值要求的描述子作为匹配结果.
3.显示特征点匹配结果
void visionagin:: MyORBmatch()
{
Mat imgquery = imread("C:\\Users\\86176\\Downloads\\visionimage\\box.png");
Mat imgtrain = imread("C:\\Users\\86176\\Downloads\\visionimage\\box_in_scene.png");
if (imgquery.empty() == true||imgtrain.empty()==true)
{
cout << "读取失败!" << endl;
}
Ptr orb = ORB::create(100);
vector querykeypoints, trainkeypoints;
//计算两幅图的关键点
orb->detect(imgquery, querykeypoints);
orb->detect(imgtrain, trainkeypoints);
Mat querydes, traindes;
//计算两幅图的描述子
orb->compute(imgquery, querykeypoints, querydes);
orb->compute(imgtrain, trainkeypoints, traindes);
//特征点匹配
vector matchout;//存放特征点匹配的结果
BFMatcher matcher(NORM_HAMMING);//定义暴力匹配类,orb特征点用hanming距离
matcher.match(querydes, traindes, matchout);//进行匹配
cout << "匹配的特征点:" << matchout.size() << "个" << endl;
//通过汉明距离筛选特征点
double min_dist = 1000;
double max_dist = 0;
//筛选出匹配结果中得最大和最小汉明距离
for (int i = 0; i < matchout.size(); ++i)
{
double dist = matchout[i].distance;
if (dist = max_dist)
{
max_dist = dist;
}
}
cout << "max hanming dist is :" << max_dist << endl;
cout << "min hanming dist is :" << min_dist << endl;
//创建合适的匹配结果
vector goodmatches;
for (int j = 0; j < matchout.size(); ++j)
{
if (matchout[j].distance
void visionagin:: Myflannmatch()
{
Mat imgquery = imread("C:\\Users\\86176\\Downloads\\visionimage\\box.png");
Mat imgtrain = imread("C:\\Users\\86176\\Downloads\\visionimage\\box_in_scene.png");
if (imgquery.empty() == true || imgtrain.empty() == true)
{
cout << "读取失败!" << endl;
}
Ptr orb = ORB::create(1000);
vector trainkeypoints, querykeypoints;
orb->detect(imgquery, querykeypoints);
orb->detect(imgtrain, trainkeypoints);
Mat querydescriptions, traindescriptions;
orb->compute(imgquery, querykeypoints, querydescriptions);
orb->compute(imgtrain, trainkeypoints, traindescriptions);//flann中的描述子需32f
querydescriptions.convertTo(querydescriptions, CV_32F);
traindescriptions.convertTo(traindescriptions, CV_32F);
vectorout;
FlannBasedMatcher flannmatch;
flannmatch.match(querydescriptions, traindescriptions, out);
double min_dist = 100, max_dist = 0;
for (int i = 0; i < out.size(); i++)//out.rows
{
double dist = out[i].distance;
if (dist max_dist)
{
max_dist = dist;
}
}
cout << "max_dist is :" << max_dist << endl;
cout << "min_dist is :" << min_dist << endl;
vector goodout;
for (int j = 0; j < out.size(); j++)
{
if (out[j].distance < 0.4 * max_dist)
{
goodout.push_back(out[j]);
}
}
Mat outimg, goodimg;
drawMatches(imgquery, querykeypoints, imgtrain, trainkeypoints,out,outimg);
drawMatches(imgquery, querykeypoints, imgtrain, trainkeypoints, goodout, goodimg);
imshow("outimg", outimg);
imshow("goodimg", goodimg);
}
5.RANSAC优化特征点匹配
//以下皆为RANSAC算法优化特征点匹配程序
void orb_det_comp(Mat& image, vector& pts1, Mat& out)
{
Ptr orb = ORB::create(1000, 1.2);
orb->detect(image, pts1);
orb->compute(image, pts1, out);
}
void min_match(vector& soursematcher, vector& outmatcher)
{
double min_dist = 1000, max_dist = 0;
for (int i = 0; i < soursematcher.size(); ++i)
{
double dist = soursematcher[i].distance;
if (dist < min_dist)
{
min_dist = dist;
}
if (dist > max_dist)
{
max_dist = dist;
}
}
cout << "min_dist is :" << min_dist << endl;
cout << "max_dist is :" << max_dist << endl;
for (int j = 0; j < soursematcher.size(); ++j)
{
if (soursematcher[j].distance & querykpt, vector& trainkpt, vector& match1, vector& matchransac)
{
vectorqueryp(match1.size()), trainp(match1.size());//定义匹配点对坐标
//保存从关键点中提取的点对
for (int i = 0; i < match1.size(); ++i)
{
queryp[i] = querykpt[match1[i].queryIdx].pt;//match1[i].queryIdx 是结果中对应的query的index
trainp[i] = trainkpt[match1[i].trainIdx].pt;
}
//匹配点对进行RANSAC过滤
vector mask(queryp.size());
findHomography(queryp, trainp, RANSAC, 3, mask);
for (int j = 0; j < mask.size(); ++j)
{
if (mask[j])
{
matchransac.push_back(match1[j]);
}
}
}
void visionagin:: MyRANSAC()
{
Mat imgquery = imread("C:\\Users\\86176\\Downloads\\visionimage\\box.png");
Mat imgtrain = imread("C:\\Users\\86176\\Downloads\\visionimage\\box_in_scene.png");
if (imgquery.empty() == true || imgtrain.empty() == true)
{
cout << "读取失败!" << endl;
}
vector trainkeypoints, querykeypoints;
Mat querydescriptions, traindescriptions;
//计算关键点和特征点
orb_det_comp(imgquery, querykeypoints, querydescriptions);
orb_det_comp(imgtrain, trainkeypoints, traindescriptions);
//建立暴力匹配类
BFMatcher bfmatch(NORM_HAMMING);
// 存放结果的Dmatch vector
vector matchers, min_matchers, ransac_matchers;//分别为初始结果,最小汉明距离筛选后的结果以及RANSAC优化后的结果
bfmatch.match(querydescriptions, traindescriptions, matchers);
cout << "初始匹配结果 nums :" << matchers.size()<
Original: https://blog.csdn.net/m0_57747965/article/details/121734125
Author: Callmegodyu、
Title: day32:特征点匹配
原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/645235/
转载文章受原作者版权保护。转载请注明原作者出处!