当前位置: 首页 > 编程日记 > 正文

akaze特征匹配怎么去掉不合适的点_SIFT特征点

SIFT特征点

图像特征点检测一直是研究的热点,从早期的harris角点检测开始,一直有很多人关注图像特征点的检测。最早人们关注图像中的角点,主要是因为角点能够代表图像中的一些特征。比如,通过检测两幅图像中的角点,可以实现图像匹配、分类等。

但是,早前的角点检测算法不具有放射不变性,即对于旋转、平移、缩放等图像的适应性不好。此外,光照不变性的性能也比较差。直到SIFT算法横空出世,很好的解决了这方面的问题。SIFT算法算是一个相对有点复杂的算法,对于初学者如果要完全弄懂,可能需要花一些时间。这里我简单介绍下该算法,有兴趣的可以重点研究一下。

Sift算法主要分为以下几个步骤:

(1)建立高斯金字塔,利用高斯差分进行图像极值点检测;

(2)去掉边界和对比度小的极值,拟合函数确定亚像素精度的极值,得到稳定的极值点;

(3)计算极值点16X16邻域范围内梯度直方图,将16X16范围分为16个4X4的像素块,每个块计算8个方向的梯度直方图,得到关键点的128维描述向量并归一化消除光照影响。

(4)图像进行匹配时,通过比较两图中的关键点128维向量的欧式距离找到匹配点。

4401210420196f63febb3d7f0ade0017.png

图1 David Lowe和检测出来的SIFT特征点

英属哥伦比亚大学教授大卫·罗伊(DavidLowe)1999年提出SIFT算法,该算法具有光照不变性,放射不变性等特点。而且,找出来的特征点非常稳定。该算法专利属于英属哥伦比亚大学,在opencv3.0以后不能直接使用,需要自己编译opencv扩展库才能调用。但是该算法也有一个缺陷,就是计算速度太慢了,很难满足实时检测的要求,如果要提高速度,对硬件的要求比较高。

SIFT算法除了提出的特征点检测算法比较稳定之外,其实该算法的特征点描述算子也是相当优秀。SIFT的特征点描述算子采用128维的梯度方向向量来描述特征点,由于梯度本身就比较稳定,并且不受光照变化的影响。因此,采用该描述算子可以唯一的表达对应的特征点。2005年Navneet Dalal提出的HOG算法用于行人检测,其提出的HOG描述符应该也是受到SIFT算法的启发。下面以具体的opencv代码来实现SIFT特征点检测。代码上对关键代码进行了注释。要调用SIFT算子,必须自己编译opencv扩展库的源代码。

#include

#include

#include"opencv2/core.hpp"

#include"opencv2/core/utility.hpp"

#include"opencv2/highgui.hpp"

#include"opencv2/features2d.hpp"

#include

#include"opencv2/imgproc.hpp"

#include"opencv2/flann.hpp"

#include"opencv2/xfeatures2d.hpp"

usingnamespace cv;

usingnamespace std;

usingnamespace cv::xfeatures2d;

int main(intargc, char** argv)

{

Mat src1, src2;

src1 = imread("E:\\boat\\img1.pgm", 0);

src2 = imread("E:\\boat\\img2.pgm", 0);

namedWindow("src1", 0);

namedWindow("src2", 0);

imshow("src1", src1);

imshow("src2", src2);

vector<KeyPoint> keyPoint1,keyPoint2;

//创建SIFT变量,可以直接指定一些参数,也可以不指定,采用默认的参数

//Ptr sift = xfeatures2d::SIFT::create();

Ptr<Feature2D> sift =xfeatures2d::SIFT::create(500, 3);

//进行特征点检测

sift->detect(src1,keyPoint1);

sift->detect(src2,keyPoint2);

Mat result1, result2;

//将检测侧的特征点绘制在图像上

drawKeypoints(src1,keyPoint1, result1, Scalar(0, 255, 0), DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS);//画出特征点

namedWindow("src1特征点", 0);

imshow("src1特征点", result1);

//将检测侧的特征点绘制在图像上

drawKeypoints(src2,keyPoint2, result2, Scalar(0, 255, 0), DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS);//画出特征点

namedWindow("src2特征点", 0);

imshow("src2特征点", result2);

Mat descriptors_1,descriptors_2;

//计算图像上每个特征点的128维描述算子

sift->compute(src1,keyPoint1, descriptors_1);

sift->compute(src2,keyPoint2, descriptors_2);

BFMatcher matcher;

vector<DMatch> matches;

//两幅图像特征点匹配

matcher.match(descriptors_1,descriptors_2, matches);

Mat img_matches;

//绘制匹配结果

drawMatches(src1,keyPoint1, src2, keyPoint2, matches, img_matches, Scalar(0, 0, 255), Scalar(0, 0, 255));

namedWindow("match1", 0);

imshow("match1", img_matches);

//提取出最佳匹配结果

nth_element(matches.begin(),matches.begin() + 50, matches.end());

//剔除掉其余的匹配结果

matches.erase(matches.begin()+ 50, matches.end());

Mat img_matches2;

//绘制匹配结果

drawMatches(src1,keyPoint1, src2, keyPoint2, matches, img_matches2, Scalar(0, 0, 255), Scalar(0, 0, 255));

namedWindow("match2", 0);

imshow("match2", img_matches2);

waitKey(0);

return 0;

}

5e692565ab8caf5c2a2b9038b2037ee0.png

图2  原图

d99c1e6027269fa08ce913d68070838e.png

图3 特征点

cf5b608a1eef77652a94d2184071fbb6.png

图4 特征点匹配结果

6658fd4aa5aed57dbd3f394b40ad7a1e.png

图5提取出最佳匹配结果

上面的第二张图像相对于第一张图像,有一定的放射变换。但是,可以看出,SIFT算法能够很好的检测出两张图像中的特征点,并且得到很好的匹配结果。由于第一次检测出来的特征点比较多,可能存在有些特征点不匹配的情况。因此,可以过滤掉一些点,只保留最前面匹配结果最好的一些点来匹配。图5是取出的前面50个点匹配的结果。看得出来,SIFT算法还是相当优秀的。在最新的opencv5.0版本中,SIFT算法的专利已经过期了,所以将该算法放在了主仓库里面,可以直接调用,不用编译扩展库了。但是,由于扩展库里面还有其他很多优秀的算法,因此,要把opencv的功能发挥出来,还是要自己编译opencv以及扩展库的源代码。

相关文章:

fopen 中 按文本读写与按二进制读写 实例

参考&#xff1a;http://blog.csdn.net/hinyunsin/article/details/6401854 #include <stdio.h>int main(int argc, char *argv[]) {char he[20] "hello world\n";FILE *outfile fopen("t.txt", "wt");fwrite(he, sizeof(char), 20, out…

狼奔代码生成工具使用心得

狼奔代码生成工具(http://ltfwan.d33140.jit8.cn)是一款为程序员设计的代码生成器&#xff0c;更是一款软件项目智能开发平台&#xff0c;它可以自动生成ASP.NET页面及后台代码&#xff0c;采用了面向服务的架构&#xff08;SOA&#xff09;。那么&#xff0c;要如何通过狼奔代…

h5在手机端实现简单复制

<a href"https://blog-static.cnblogs.com/files/ruanqin/clipboard.min.js">下载clipborrdjs</a>  下载地址&#xff1a;https://blog-static.cnblogs.com/files/ruanqin/clipboard.min.js html中&#xff1a; <div id"app"> <a hr…

MQTT topic匹配规则

MQTT topic匹配规则 原文连接: https://blog.csdn.net/JiangCheng817/article/details/81333893 内容&#xff1a; 主题层级分隔符 “/”: 表示层级关系 单层通配符 “”: 订阅消息时使用&#xff0c;匹配一层主题如 a/ 匹配诸如 a/b a/c 但是不能匹配 a/b/c,特别的单独的可…

产品经理岗位职责说明_技术负责人岗位职责,五大方面,超越岗位抓住未来才是技术大牛...

技术负责人一般指建设领域、生产制造领域、电子商务领域&#xff0c;负责全过程的技术决策、技术指导。技术负责人的岗位职责包含五个方面&#xff1a;技术职责&#xff1a;负责具体技术方案设计思路、关键参数等技术决策&#xff0c;负责对所有技术人员进行具体技术实施时的技…

Jane Eyre

Do you think I could stay here to become nothing to you? Do you think because I am poor , and obscrue, and plain that I am soulless, and heartless? I have as much soul as you and fully as much heart. And if God gifted me beauty and wealth, I should have …

Ubuntu 10.04 LTS 网站权限不够

wordpress不能自动升级config文件没法写找不到目录wordpress修改无法保存。。。。这些都是权限不够。解决办法:给apache一个访问www目录的权限&#xff0c;一般linux的网站目录是/srv/www/此时用下面的命令&#xff1a;chown www-data:www-data /srv/www/ -r

简单配置nginx反向代理,实现跨域请求

简单配置nginx去做反向代理&#xff0c;实现跨域请求 简单介绍nginx的nginx.conf最核心的配置&#xff0c;去做反向代理&#xff0c;实现跨域请求。 更多详细配置&#xff0c;参考nginx官方文档 先介绍几个nginx命令 打开nginx.conf文件/usr/local/etc/nginx/nginx.conf重新加载…

c# redis hashid如何设置过期时间_Redis中Key过期策略amp;淘汰机制

1. Redis中设置Key过期时间我们有两种方式设置过期时间1.1 设置多久后过期设置一个 key 10s 过期&#xff0c;可以这样127.0.0.1:6379> SET key value EX 10127.0.0.1:6379> SET key value PX 10000PX 后面是毫秒ms&#xff0c;EX是秒。设置完成后&#xff0c;10s内&…

在CISCO路由器上配置DHCP与DHCP中继

企业网络中DHCP环境的搭建 企业DHCP需求描述&#xff1a; 在大型企业中&#xff0c;一般都有很多个部门&#xff0c;各部门之间有时要求不能互通&#xff0c;这可以通过使用VLAN来解决&#xff0c;但是上千个人IP配置也是一件极大耗费人力的事。所以我们迫切需求一种全自动的&a…

MQTT消息长度限制

原文连接: https://stackoverflow.com/questions/34522053/what-is-the-maximum-message-length-for-a-mqtt-broker 内容&#xff1a; 单条消息默认限制大小256MB&#xff0c;可以通过配置修改 It’s not entirely clear what you’re asking here, so I’ll answer both pos…

jQuery EasyUI API 中文文档 - DataGrid 数据表格

扩展自 $.fn.panel.defaults &#xff0c;用 $.fn.datagrid.defaults 重写了 defaults 。依赖panelresizablelinkbuttonpagination用法1. <table id"tt"></table> 1. $(#tt).datagrid({ 2. url:datagrid_data.json, 3. columns:[[ 4. …

point-to-point(点对点) 网口

点对点连接是两个系统或进程之间的专用通信链路。想象一下直接连接两个系统的一条线路。两个系统独占此线路进行通信。点对点通信的对立面是广播&#xff0c;在广播通信中&#xff0c;一个系统可以向多个系统传输。 点对点通信在OSI协议栈的物理、数据链路层和网络层中定义。 点…

springboot中文文档_登顶 Github 的 Spring Boot 仓库!艿艿写的最肝系列

源码精品专栏中文详细注释的开源项目RPC 框架 Dubbo 源码解析网络应用框架 Netty 源码解析消息中间件 RocketMQ 源码解析数据库中间件 Sharding-JDBC 和 MyCAT 源码解析作业调度中间件 Elastic-Job 源码解析分布式事务中间件 TCC-Transaction 源码解析Eureka 和 Hystrix 源码解…

浏览器缓存网站静态文件

当用户第一次访问你的网站时&#xff0c;让用户的浏览器缓存网站的静态文件&#xff0c;如图片\CSS\JS等,然后接访问接下来的页面就会直接调用浏览器的缓存而不是重新从服务器下载&#xff0c;这样既节省带宽和流量又加快了用户打开网页的速度&#xff0c;一石三鸟&#xff0c;…

MQTT 心跳和keepalive配置

MQTT 心跳和keepalive配置 内容&#xff1a; 正常MQTT 服务器端会配置一个超时时间&#xff0c;一般为60s&#xff0c; 在这个时间段内一个连接如果没有数据传输的话&#xff0c;服务端会主动断开连接以释放资源&#xff0c; 有两种方式可以规避这个问题: 方式1: 最为简单&a…

android开发我的新浪微博客户端-登录页面功能篇(4.2)

上一篇中完成了如上图的UI部分的实现&#xff0c;现在继续来讲功能的实现&#xff0c;用户登录操作主要就是账号列表显示和选择账号登录两个功能其他的都是些简单的辅助功能&#xff0c;首先是点击id为iconSelectBtn的ImageButton时显示用户选择窗口&#xff0c;这个时候去数据…

大脚本运行常见问题总结

1. Allowed memory size of 8388608 bytes exhausted 出现原因&#xff1a;脚本运行超过最大运行时间 解决方法&#xff1a;1 ) 修改 php.ini 文件。将memory_limit 由默认值改成合适的大小&#xff0c;重启服务器。 2&#xff09;在脚本中加入 ini_set("memory_limit&qu…

MQTT Qos类型解释

MQTT Qos类型解释 原文连接: https://blog.csdn.net/yangguosb/article/details/78653228 内容&#xff1a; Qos0 发送者只发送一次消息&#xff0c;不进行重试&#xff0c;Broker不会返回确认消息。在Qos0情况下&#xff0c;Broker可能没有接受到消息&#xff0c;流程如…

对做技术的一点思考

做技术在中国有没有前途&#xff1f;这个问题是每个在国内做技术的人都会思考的问题。在我看来&#xff0c;我们之所以会产生样的困扰&#xff0c;主要原因在于我们所谓的研发都是二次开发&#xff0c;国内任何公司&#xff0c;研究单位&#xff08;除开严格保密的单位&#xf…

iis伪静态排除css_魔众系统伪静态规则怎么配

魔众系列系统目前已经有大量用户在使用&#xff0c;大家对于伪静态的配置一直有所疑惑&#xff0c;经过和技术小哥哥的协商&#xff0c;我们特意将三种不同的 HTTP 服务器配置文件分享给大家&#xff0c;方便大家参考。魔众系列系统目前已经有大量用户在使用&#xff0c;大家对…

R.drawable 转 bitmap

引用&#xff1a;http://zhidao.baidu.com/question/291703800.html Bitmap bmpBitmapFactory.decodeResource(r, R.drawable.icon); Bitmap newb Bitmap.createBitmap( 300, 300, Config.ARGB_8888 ); Canvas canvasTemp new Canvas( newb ); canvasTemp.drawBitmap(bmp, …

洛谷P3254 圆桌问题(最大流)

题意 $m$个不同单位代表参加会议&#xff0c;第$i$个单位有$r_i$个人 $n$张餐桌&#xff0c;第$i$张可容纳$c_i$个代表就餐 同一个单位的代表需要在不同的餐桌就餐 问是否可行&#xff0c;要求输出方案 Sol 比较zz的最大流 从$S$向$1-m$连流量为$r_i$的边 从$m 1$向$m n$连流…

设置commit 提交模板

设置commit 提交模板 建议提交 &#xff08;.template&#xff09;模板文件 放在用户目录(Doceuments)下 (~/Doceuments) 原文连接: https://blog.csdn.net/mafei852213034/article/details/51908049 内容&#xff1a; 1、在根目录建立模板文件 如 xxx_template文件&#…

listen函数的第二个参数_【图像处理】OpenCV系列十七 --- 几何图像变换函数详解(一)...

上一篇我们学习了仿射变换的warpAffine函数&#xff0c;知道了如何用这个函数对图像进行旋转、平移等操作&#xff0c;那么本节我们一起来学习一下与仿射变换相关的其他函数以及相关的几何图像变换。一、convertMaps()函数1、函数原型void convertMaps(InputArray map1, InputA…

flex java socket通信

引用:http://developer.51cto.com/art/201003/189791.htm Java socket通信如何进行相关问题的解答呢&#xff1f;还是需要我们不断的学习&#xff0c;在学习的过程中会遇到不少的问题。下面我们就从源代码中找到有关的问题解决方案。希望大家在以后的Javasocket通信使用中有所收…

编程珠玑:对DAO层的一点修改

由于以前的Domain对象都是不需要序列化的&#xff0c;所以为了操作数据库查询的方便&#xff0c;直接采用继承BaseDomain的方式来完成。这样在传递动态参数的时候&#xff0c;只需要把参数放到Map总&#xff0c;就可以很好的在ibatis配置文件(map.xx来直接获取值)中使用。 这样…

solr 下载 有dist目录的(6需要8)

http://archive.apache.org/dist/lucene/solr/ solr6 需要java8 转载于:https://www.cnblogs.com/hnqm/p/9367140.html

抛出一个nullpointerexception_Java 14 发布了,再也不怕 NullPointerException 了!

推荐阅读&#xff1a;Java程序员danni&#xff1a;就一个HashMap&#xff0c;居然能跟面试官扯上半个小时&#xff1f;​zhuanlan.zhihu.com2020年3月17日发布&#xff0c;Java正式发布了JDK 14 &#xff0c;目前已经可以开放下载。在JDK 14中&#xff0c;共有16个新特性&#…

linux平台软件动态分析工具valgrind系列工具及其可视化

linux平台软件动态分析工具valgrind系列工具 Memcheck–内存检查工具Callgrind–函数调用分析工具Cachegrind–缓存命中分析工具Helgrind–线程分析工具Massif–内存堆栈分析工具 一、Valgrind 概述 Valgrind是一套Linux下&#xff0c;开放源代码&#xff08;GPL V2&#xf…