IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 人工智能 -> day32:特征点匹配 -> 正文阅读

[人工智能]day32:特征点匹配

特征点匹配就是在不同的图像中寻找同一个物体的同一个特征点.因为每个特征点都具有标志着唯一身份和特点的描述子,因此特征点匹配其实就是在两个图像中寻找具有相似描述子的两个特征点.根据描述子特点的不同 ,寻 找两个相似描述子的方法也不尽相同,总体上可以总结为两类:
第一类是计算两个描述子之间的欧氏距离,这种匹配方式的特征点有 SIFT 特征点、 SURF 特征点
等.
第二类是计算两个描述子之间的汉明距离 这种匹配方式的特征点有 ORB 特征点、 BRISK特征点等.
特征点匹配是图像处理领域寻找不同图像间信息关联的重要方法.由于相机移动导致成像视场发生改变,因此同一个物体会出现在图像中不同的位置,通过特征点匹配可以快速定位物体在新图像中的位置 为后续对图像的进一 步处理提供数据支持。特征点匹配由于数据量小、匹配精确而被 广泛应用在三维重建、视觉定位、运动估计、图像配准等领域.
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 = ORB::create(100);
	vector<KeyPoint> querykeypoints, trainkeypoints;
	//计算两幅图的关键点
	orb->detect(imgquery, querykeypoints);
	orb->detect(imgtrain, trainkeypoints);
	Mat querydes, traindes;
	//计算两幅图的描述子
	orb->compute(imgquery, querykeypoints, querydes);
	orb->compute(imgtrain, trainkeypoints, traindes);
	//特征点匹配
	vector<DMatch> 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 <= min_dist)
		{
			min_dist = dist;
		}
		if (dist >= max_dist)
		{
			max_dist = dist;
		}
	}
	cout << "max hanming dist is :" << max_dist << endl;
	cout << "min hanming dist is :" << min_dist << endl;
	//创建合适的匹配结果
	vector<DMatch> goodmatches;
	for (int j = 0; j < matchout.size(); ++j)
	{
		if (matchout[j].distance <=max(2*min_dist,20.0))//汉明距离大于最小距离的两倍属于误匹配
		{
			goodmatches.push_back(matchout[j]);
		}
	}
	cout << "剩余的合适的特征点数目:" << goodmatches.size() << endl;
	//绘制匹配的结果
	Mat outbad, outok;
	drawMatches(imgquery, querykeypoints, imgtrain, trainkeypoints, matchout,outbad);
	drawMatches(imgquery, querykeypoints, imgtrain, trainkeypoints, goodmatches, outok);
	imshow("outbad", outbad);
	imshow("outok", outok);
}

?4.FLANN匹配

?

?

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 = ORB::create(1000);
	vector<KeyPoint> 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);
	vector<DMatch>out;
	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 <min_dist)
		{
			min_dist = dist;
		}
		if (dist >max_dist)
		{
			max_dist = dist;
		}
	}
	cout << "max_dist is :" << max_dist << endl;
	cout << "min_dist is :" << min_dist << endl;
	vector<DMatch> 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<KeyPoint>& pts1, Mat& out)
{
	Ptr <ORB> orb = ORB::create(1000, 1.2);
	orb->detect(image, pts1);
	orb->compute(image, pts1, out);
}
void min_match(vector<DMatch>& soursematcher, vector<DMatch>& 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 <=max(2 * min_dist, 20.0))
		{
			outmatcher.push_back(soursematcher[j]);
		}
	}
}
void ransacmatch(vector<KeyPoint>& querykpt, vector<KeyPoint>& trainkpt, vector<DMatch>& match1, vector<DMatch>& matchransac)
{
	vector<Point2f>queryp(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<int> 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<KeyPoint> trainkeypoints, querykeypoints;
	Mat querydescriptions, traindescriptions;
	//计算关键点和特征点
	orb_det_comp(imgquery, querykeypoints, querydescriptions);
	orb_det_comp(imgtrain, trainkeypoints, traindescriptions);
	//建立暴力匹配类
	BFMatcher bfmatch(NORM_HAMMING);
	//	存放结果的Dmatch vector
	vector<DMatch> matchers, min_matchers, ransac_matchers;//分别为初始结果,最小汉明距离筛选后的结果以及RANSAC优化后的结果
	bfmatch.match(querydescriptions, traindescriptions, matchers);
	cout << "初始匹配结果 nums :" << matchers.size()<<endl;
	//最小汉明距离筛选
	min_match(matchers,min_matchers);
	cout << "汉明距离筛选后 num :"<< min_matchers.size()<<endl;
	//ransac优化
	ransacmatch(querykeypoints, trainkeypoints, min_matchers, ransac_matchers);
	cout << "RANSAC优化后 num :" << ransac_matchers.size() << endl;
	//绘制结果
	Mat out1, out2, out3;
	drawMatches(imgquery, querykeypoints, imgtrain, trainkeypoints, matchers, out1);
	drawMatches(imgquery, querykeypoints, imgtrain, trainkeypoints, min_matchers, out2);
	drawMatches(imgquery, querykeypoints, imgtrain, trainkeypoints, ransac_matchers, out3);
	imshow("初始匹配结果", out1);
	imshow("汉明距离筛选后匹配结果", out2);
	imshow("ransac优化后匹配结果", out3);
}
//Myransac() 结束 ......

?

?

?

?

  人工智能 最新文章
2022吴恩达机器学习课程——第二课(神经网
第十五章 规则学习
FixMatch: Simplifying Semi-Supervised Le
数据挖掘Java——Kmeans算法的实现
大脑皮层的分割方法
【翻译】GPT-3是如何工作的
论文笔记:TEACHTEXT: CrossModal Generaliz
python从零学(六)
详解Python 3.x 导入(import)
【答读者问27】backtrader不支持最新版本的
上一篇文章      下一篇文章      查看所有文章
加:2021-12-07 12:01:51  更:2021-12-07 12:03:00 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/27 2:33:11-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码