RANSAC算法的简单理解

  图像拼接中看到了特征匹配的部分,特征匹配主要是特征点的匹配。在特征点匹配的时候,首先进行粗匹配,粗匹配通常是进行一对匹配点进行对比,误差越小越可能是一对匹配点;精匹配方法中,我们可以用到RANSAC(Random Sample Consensus 随机抽样一致性)算法。

RANSAC可以用于图片的拼接技术。在多幅图像合成时,事先会在待合成的图片中提取一些关键的特征点。计算机视觉的研究表明,不同视角下物体往往可以通过一个透视矩阵(单应矩阵)(3X3或2X2)的变换而得到。RANSAC被用于拟合这个模型的参数(矩阵各行列的值),由此便可识别出不同照片中的同一物体。

(选自:https://blog.csdn.net/l297969586/article/details/52328884)

Ransac算法中要用四对特征点对构建一个单应矩阵,关于单应矩阵的介绍参考博客:(https://blog.csdn.net/zhaocj/article/details/78799194)

  我们可以理解为,粗匹配是从两幅图像所提取的特征集中,找到特征点之间相对应的特征点对;精匹配是在粗匹配的基础上,再剔除一些不正确的匹配点对。

RANSAC算法步骤:

1.随机选取四对匹配点,计算出一个临时模型参数(单应矩阵)。

2.用该模型参数去测试匹配点对集,统计误差在允许范围内的匹配点对数目(即内点数)。

3.当内点数目占到指定比例时,则认为所选取的匹配点对是合理的。

  第一步选取的匹配点对合理:  根据内点信息重新计算得到最终的模型参数。

  第一步选取的匹配点对不合理:重新选取匹配点对,重复进行模型参数计算,直到选取的特征点对合理。

 

---------------------------------------------------------------------------

 

 

代码来源以及Ransac算法介绍:http://blog.csdn.net/luoshixian099/article/details/50217655

 

实例代码如下:OpenCV中此功能通过调用findHomography函数调用

 

#include <iostream>  
#include "opencv2/opencv.hpp"  
#include "opencv2/core/core.hpp"  
#include "opencv2/features2d/features2d.hpp"  
#include "opencv2/highgui/highgui.hpp"  using namespace cv;
using namespace std;int main(int argc, char** argv)
{Mat obj = imread("obj.jpg");   //载入目标图像  Mat scene = imread("scene.jpg"); //载入场景图像  if (obj.empty() || scene.empty()){cout << "Can't open the picture!\n";return 0;}vector<KeyPoint> obj_keypoints, scene_keypoints;Mat obj_descriptors, scene_descriptors;ORB detector;     //采用ORB算法提取特征点  detector.detect(obj, obj_keypoints);detector.detect(scene, scene_keypoints);detector.compute(obj, obj_keypoints, obj_descriptors);detector.compute(scene, scene_keypoints, scene_descriptors);BFMatcher matcher(NORM_HAMMING, true); //汉明距离做为相似度度量  vector<DMatch> matches;matcher.match(obj_descriptors, scene_descriptors, matches);Mat match_img;drawMatches(obj, obj_keypoints, scene, scene_keypoints, matches, match_img);imshow("滤除误匹配前", match_img);//保存匹配对序号  vector<int> queryIdxs(matches.size()), trainIdxs(matches.size());for (size_t i = 0; i < matches.size(); i++){queryIdxs[i] = matches[i].queryIdx;trainIdxs[i] = matches[i].trainIdx;}Mat H12;   //变换矩阵  vector<Point2f> points1; KeyPoint::convert(obj_keypoints, points1, queryIdxs);vector<Point2f> points2; KeyPoint::convert(scene_keypoints, points2, trainIdxs);int ransacReprojThreshold = 5;  //拒绝阈值  H12 = findHomography(Mat(points1), Mat(points2), CV_RANSAC, ransacReprojThreshold);vector<char> matchesMask(matches.size(), 0);Mat points1t;perspectiveTransform(Mat(points1), points1t, H12);for (size_t i1 = 0; i1 < points1.size(); i1++)  //保存‘内点’  {if (norm(points2[i1] - points1t.at<Point2f>((int)i1, 0)) <= ransacReprojThreshold) //给内点做标记  {matchesMask[i1] = 1;}}Mat match_img2;   //滤除‘外点’后  drawMatches(obj, obj_keypoints, scene, scene_keypoints, matches, match_img2, Scalar(0, 0, 255), Scalar::all(-1), matchesMask);//画出目标位置,场景图片矩形std::vector<Point2f> obj_corners(4);obj_corners[0] = cvPoint(0, 0); obj_corners[1] = cvPoint(obj.cols, 0);obj_corners[2] = cvPoint(obj.cols, obj.rows); obj_corners[3] = cvPoint(0, obj.rows);std::vector<Point2f> scene_corners(4);perspectiveTransform(obj_corners, scene_corners, H12);line(match_img2, scene_corners[0] + Point2f(static_cast<float>(obj.cols), 0),scene_corners[1] + Point2f(static_cast<float>(obj.cols), 0), Scalar(0, 0, 255), 2);line(match_img2, scene_corners[1] + Point2f(static_cast<float>(obj.cols), 0),scene_corners[2] + Point2f(static_cast<float>(obj.cols), 0), Scalar(0, 0, 255), 2);line(match_img2, scene_corners[2] + Point2f(static_cast<float>(obj.cols), 0),scene_corners[3] + Point2f(static_cast<float>(obj.cols), 0), Scalar(0, 0, 255), 2);line(match_img2, scene_corners[3] + Point2f(static_cast<float>(obj.cols), 0),scene_corners[0] + Point2f(static_cast<float>(obj.cols), 0), Scalar(0, 0, 255), 2);imshow("滤除误匹配后", match_img2);waitKey(0);return 0;
}

 

代码实现的效果:

 

---。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/492883.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

IEEE论文:城市大脑,基于互联网大脑模型的智慧城市建设

作者&#xff1a;刘锋 互联网进化论作者 计算机博士前言&#xff1a;基于互联网大脑模型与智慧城市建设的结合&#xff0c;2015年2月在csdn第一次发布文章《基于互联网大脑架构的智慧城市建设探讨》提出了城市大脑的建设方向&#xff0c;地址&#xff1a;https://blog.csdn.net…

vb6 枚举对象属性

Option Explicit引用Library TLIC:\WINDOWS\system32\TLBINF32.DLLTypeLib InformationPrivate Sub Form_Load()Dim oTLB As InterfaceInfo, I As LongSet oTLB TLI.InterfaceInfoFromObject(Me)Debug.Print oTLB.NameFor I 1 To oTLB.Members.CountSelect Case oTLB.Members…

Python利用turtle绘制五角星

绘制用到的参数我们存放在data.txt文件中&#xff0c;data.txt文件内容如下&#xff1a; 300,0,144,1,0,0 300,0,144,0,1,0 300,0,144,0,0,1 300,0,144,1,1,0 300,0,108,0,1,1 184,0,72,1,0,1 184,0,72,0,0,0 184,0,72,0,0,0 184,0,72,0,0,0Python代码如下&#xff1a; # data.…

关于c#静态构造函数

http://baike.baidu.com/view/2634573.htm?fraladdin 在百科上看到C#的新特性静态构造函数&#xff0c;其中提到静态构造函数“不能继承” 今天做了个试验&#xff0c;发现实际上静态构造函数是可以继承的&#xff0c;代码如下&#xff1a; using System; using System.Collec…

Python语言数据类型-----数字和字符串

Python语言的数字类型 整数类型 浮点数类型 复数类型 整数类型与数学中的整数类型概念一致&#xff0c;没有取值范围。 十进制数为 1010,99,-217 十六进制为 0x9a, -0x89 (0x,0X开头表示16进制数) 二进制为 0b010, -0B101(0b,0B开头的表示二进制数) 八进制为 0o123, -0O456(…

深度观察|工业物联网的应用场景和市场潜力

来源&#xff1a;readwrite编译&#xff1a;郭仁贤从人力资源到数字技术&#xff0c;物联网&#xff08;IoT&#xff09;改变了我们与周围世界互动的方式。在每一次的挑战和新的风险中&#xff0c;我们生活中最个人化的领域也迎来了新的机遇。物联网数字产业真正颠覆的是农业、…

scrapy 工作流程

Scrapy的整个数据处理流程由Scrapy引擎进行控制&#xff0c;其主要的运行方式为&#xff1a; 引擎打开一个域名&#xff0c;蜘蛛处理这个域名&#xff0c;然后获取第一个待爬取的URL。引擎从蜘蛛那获取第一个需要爬取的URL&#xff0c;然后作为请求在调度中进行调度。引擎从调度…

Python数据类型-----列表

Python中列表类型 列表是有序的元素集合。 列表中的元素可以通过索引进行访问列表中的每个元素类型可以是不一样的列表的大小没有限制&#xff0c;随时可以修改 列表的操作 序列操作符操纵符含义< seq >< seq >连接两个序列< seq >*<整数类型>对序…

观五官知罕见病,AI“望诊”靠谱吗

新型人脸识别软件可助力罕见病诊断来源&#xff1a;中国科学报将人工智能&#xff08;AI&#xff09;用于医疗辅助诊断早已经不是什么新鲜事&#xff0c;仅AI医学影像辅助诊疗一项就有非常多的应用场景。然而&#xff0c;近日来自美国波士顿一家名为FDNA的数字医疗公司的研究人…

Python数据类型-元组类型

Python的元组类型 tuple 元组特点 元组中的元素可以是不同类型元组中的各个元素存在先后关系&#xff0c;可以通过索引访问元组中元素元组定义后内部的元素不能更改&#xff0c;也不能删除&#xff0c;但是可以给元组添加元素与字符串类型类似&#xff0c;可以通过索引区间来…

持续集成:CruiseControl.NET + VisualSVN.Server

刚换了工作&#xff0c;有需要搭建一套持续集成的平台&#xff0c;做一下总结。 首先是我用到的工具&#xff1a; 上面缺少了Microsoft Fxcop&#xff0c;可以用来做代码校验&#xff0c;不过实际情况暂时还没有用到。主要的需求目前是&#xff0c;使用已发布的稳定版本代码作为…

学会动态丨中国人工智能学会重磅发布《2018人工智能产业创新评估白皮书》

来源&#xff1a;中国人工智能学会摘要&#xff1a;《2018人工智能产业创新评估白皮书》由中国人工智能学会、国家工信安全中心、华夏幸福产业研究院、思保环球联合发布。白皮书聚焦人工智能的使能技术与应用场景两个层面&#xff0c;基于论文、专利、人才、行业壁垒等多个维度…

图像的几种变换简单介绍

刚体变换 平移旋转 保持欧式距离的变换&#xff0c;这意味着图像只进行2D平移和2D旋转运动。它只有3个自由度。 相似变换 平移旋转缩放 相比刚体变换增加了均匀的缩放。均匀的意思是各个方向的缩放比例相同。尺度变换增加了一个自由度&#xff0c;所以自由度为4。和刚体一…

《C语言编写 学生成绩管理系统》

/* (程序头部凝视開始) * 程序的版权和版本号声明部分 * Copyright (c) 2011, 烟台大学计算机学院学生 * All rights reserved. * 文件名&#xff1a; 学生成绩管理系统 * 作 者&#xff1a; 刘江波 * 完毕日期&#xff1a; 2012 年 6 月 23 日 * 版 本 号&#xff1a; v.62…

人工智能顶刊TPAMI2019最新《多模态机器学习综述》

来源&#xff1a;专知摘要&#xff1a;”当研究问题或数据集包括多个这样的模态时&#xff0c;其特征在于多模态。【导读】人工智能领域最顶级国际期刊IEEE Transactions on Pattern Analysis and Machine Intelligence(IEEE TPAMI,影响因子为 9.455)&#xff0c;2019年1月最新…

Python数据类型--字典

Python中的字典 存储数据时不保持元素的顺序通过任意键值查找集合中值信息的过程叫做映射&#xff0c;Python中通过字典实现映射。字典是一个键值对的集合。 – 该集合以键为索引&#xff0c;同一个键信息对应一个值。 >>> passwd {"China": "BigC…

编程基本功训练:流程图画法及练习

对于“程序设计”的工作&#xff0c;很多刚開始学习的人的理解就是“写代码”。相同&#xff0c;新手们苦恼的问题是&#xff0c;他们仅仅会“写代码”。当接到一个新的任务&#xff0c;不少人总是在第一时间就爬到键盘上去敲代码。敲着敲着&#xff0c;就把自己绕糊涂了。头晕…

python简单练习 -统计文本词频并用柱状图显示

函数功能&#xff1a;统计文本中单词频率&#xff0c;并用柱状图显示前10个最高的单词 这里统计的是函数所在文件本身 import turtlecount 10 data [] words [] # y yScale 6 # X xScale 30def drawLine(t, x1, y1, x2, y2):t.penup()t.goto(x1, y1)t.pendown()t.goto(x…

今日《科学》封面:纳米级清晰度看大脑是怎样一种体验?

来源&#xff1a;药明康德微信团队摘要&#xff1a;在最新出版的《科学》杂志上&#xff0c;由麻省理工学院&#xff08;MIT&#xff09;和霍华德休斯医学研究所&#xff08;HHMI&#xff09;的科学家们领衔的一支团队&#xff0c;成功对果蝇的完整大脑进行了成像&#xff0c;清…

java的System.getProperty()方法能够获取的值

java.version Java 执行时环境版本号 java.vendor Java 执行时环境供应商 java.vendor.url Java 供应商的 URL java.home Java 安装文件夹 java.vm.specification.version Java 虚拟机规范版本号 java.vm.specification.vendor Java 虚拟机规范供应商 java.vm.spec…