python利用opencv实现SIFT特征提取与匹配


Posted in Python onMarch 05, 2020

本文实例为大家分享了利用opencv实现SIFT特征提取与匹配的具体代码,供大家参考,具体内容如下

1、SIFT

1.1、sift的定义

SIFT,即尺度不变特征变换(Scale-invariant feature transform,SIFT),是用于图像处理领域的一种描述。这种描述具有尺度不变性,可在图像中检测出关键点,是一种局部特征描述子。

1.2、sift算法介绍

SIFT由David Lowe在1999年提出,在2004年加以完善 。SIFT在数字图像的特征描述方面当之无愧可称之为最红最火的一种,许多人对SIFT进行了改进,诞生了SIFT的一系列变种。SIFT已经申请了专利(所以现在opencv使用这个算法,需要低的版本)。

SIFT特征是基于物体上的一些局部外观的兴趣点而与影像的大小和旋转无关。对于光线、噪声、微视角改变的容忍度也相当高。基于这些特性,它们是高度显著而且相对容易撷取,在母数庞大的特征数据库中,很容易辨识物体而且鲜有误认。使用SIFT特征描述对于部分物体遮蔽的侦测率也相当高,甚至只需要3个以上的SIFT物体特征就足以计算出位置与方位。在现今的电脑硬件速度下和小型的特征数据库条件下,辨识速度可接近即时运算。SIFT特征的信息量大,适合在海量数据库中快速准确匹配。

SIFT算法具有如下一些特点:

1)SIFT特征是图像的局部特征,其对旋转、尺度缩放、亮度变化保持不变性,对视角变化、仿射变换、噪声也保持一定程度的稳定性;
2)区分性(Distinctiveness)好,信息量丰富,适用于在海量特征数据库中进行快速、准确的匹配;
3)多量性,即使少数的几个物体也可以产生大量的SIFT特征向量;
4)高速性,经优化的SIFT匹配算法甚至可以达到实时的要求;
5)可扩展性,可以很方便的与其他形式的特征向量进行联合。

1.3、特征检测

SIFT特征检测主要包括以下4个基本步骤:
1)尺度空间极值检测:搜索所有尺度上的图像位置。通过高斯微分函数来识别潜在的对于尺度和旋转不变的兴趣点。
2)关键点定位:在每个候选的位置上,通过一个拟合精细的模型来确定位置和尺度。关键点的选择依据于它们的稳定程度。
3)方向确定:基于图像局部的梯度方向,分配给每个关键点位置一个或多个方向。所有后面的对图像数据的操作都相对于关键点的方向、尺度和位置进行变换,从而提供对于这些变换的不变性。
4)关键点描述:在每个关键点周围的邻域内,在选定的尺度上测量图像局部的梯度。这些梯度被变换成一种表示,这种表示允许比较大的局部形状的变形和光照变化。

1.4、特征匹配

SIFT特征匹配主要包括2个阶段:

第一阶段:SIFT特征的生成,即从多幅图像中提取对尺度缩放、旋转、亮度变化无关的特征向量。
第二阶段:SIFT特征向量的匹配。

SIFT特征的生成一般包括以下几个步骤:

1)构建尺度空间,检测极值点,获得尺度不变性。
2)特征点过滤并进行精确定位。
3)为特征点分配方向值。
4)生成特征描述子。以特征点为中心取16×16的邻域作为采样窗口,将采样点与特征点的相对方向通过高斯加权后归入包含8个bin的方向直方图,最后获得4×4×8的128维特征描述子。当两幅图像的SIFT特征向量生成以后,下一步就可以采用关键点特征向量的欧式距离来作为两幅图像中关键点的相似性判定度量。取图1的某个关键点,通过遍历找到图像2中的距离最近的两个关键点。在这两个关键点中,如果最近距离除以次近距离小于某个阈值,则判定为一对匹配点。

2、python实现

2.1、准备工作

由于SIFT已经申请了专利,所以在高版本的opencv中,会出现错误,以前是opencv4.0.1,然后安装版本为opencv3.4.2.16
卸载以前的版本(低版本,可以试试直接运行代码):

pip uninstall opencv-python
pip uninstall opencv-contrib-python

用命令行(CMD),采用pip方式:

pip install opencv_python==3.4.2.16 
pip install opencv-contrib-python==3.4.2.16

python利用opencv实现SIFT特征提取与匹配

2.2、代码实现

#!/usr/bin/env python3
# -*- coding:utf-8 -*-
u'''
Created on 2019年6月14日
@author: wuluo
'''
__author__ = 'wuluo'
__version__ = '1.0.0'
__company__ = u'重庆交大'
__updated__ = '2019-06-14'
from matplotlib import pyplot as plt
from imagedt.decorator import time_cost
import cv2
print('cv version: ', cv2.__version__)

def bgr_rgb(img):
 (r, g, b) = cv2.split(img)
 return cv2.merge([b, g, r])

def orb_detect(image_a, image_b):
 # feature match
 orb = cv2.ORB_create()
 kp1, des1 = orb.detectAndCompute(image_a, None)
 kp2, des2 = orb.detectAndCompute(image_b, None)
 # create BFMatcher object
 bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True)
 # Match descriptors.
 matches = bf.match(des1, des2)
 # Sort them in the order of their distance.
 matches = sorted(matches, key=lambda x: x.distance)
 # Draw first 10 matches.
 img3 = cv2.drawMatches(image_a, kp1, image_b, kp2,
    matches[:100], None, flags=2)
 return bgr_rgb(img3)

@time_cost
def sift_detect(img1, img2, detector='surf'):
 if detector.startswith('si'):
 print("sift detector......")
 sift = cv2.xfeatures2d.SURF_create()
 else:
 print("surf detector......")
 sift = cv2.xfeatures2d.SURF_create()
 # find the keypoints and descriptors with SIFT
 kp1, des1 = sift.detectAndCompute(img1, None)
 kp2, des2 = sift.detectAndCompute(img2, None)
 # BFMatcher with default params
 bf = cv2.BFMatcher()
 matches = bf.knnMatch(des1, des2, k=2)
 # Apply ratio test
 good = [[m] for m, n in matches if m.distance < 0.5 * n.distance]
 # cv2.drawMatchesKnn expects list of lists as matches.
 img3 = cv2.drawMatchesKnn(img1, kp1, img2, kp2, good, None, flags=2)
 return bgr_rgb(img3)

if __name__ == "__main__":
 # load image
 image_a = cv2.imread('G:/2018and2019two/qianrushi/wuluo1.jpg')#绝对路径
 image_b = cv2.imread('G:/2018and2019two/qianrushi/wuluo2.jpg')
 # ORB
 # img = orb_detect(image_a, image_b)
 # SIFT or SURF
 img = sift_detect(image_a, image_b)
 plt.imshow(img)
 plt.show()

2.3、运行结果

采用同一张图片:

python利用opencv实现SIFT特征提取与匹配

两张有重叠部分的代码:

python利用opencv实现SIFT特征提取与匹配

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
布同自制Python函数帮助查询小工具
Mar 13 Python
深入分析在Python模块顶层运行的代码引起的一个Bug
Jul 04 Python
详解Python命令行解析工具Argparse
Apr 20 Python
python检测IP地址变化并触发事件
Dec 26 Python
Django框架之登录后自定义跳转页面的实现方法
Jul 18 Python
python字典的遍历3种方法详解
Aug 10 Python
wxPython之wx.DC绘制形状
Nov 19 Python
使用pyqt 实现重复打开多个相同界面
Dec 13 Python
关于windows下Tensorflow和pytorch安装教程
Feb 04 Python
Django nginx配置实现过程详解
Sep 10 Python
详解python中的异常和文件读写
Jan 03 Python
手把手教你实现PyTorch的MNIST数据集
Jun 28 Python
python画图常规设置方式
Mar 05 #Python
解决python -m pip install --upgrade pip 升级不成功问题
Mar 05 #Python
python入门之井字棋小游戏
Mar 05 #Python
解决Python图形界面中设置尺寸的问题
Mar 05 #Python
python实现简单井字棋小游戏
Mar 05 #Python
python GUI编程(Tkinter) 创建子窗口及在窗口上用图片绘图实例
Mar 04 #Python
Python: tkinter窗口屏幕居中,设置窗口最大,最小尺寸实例
Mar 04 #Python
You might like
php递归获取目录内文件(包含子目录)封装类分享
2013/12/25 PHP
php设置session值和cookies的学习示例
2014/03/21 PHP
php格式输出文件var_export函数实例
2014/11/15 PHP
composer.lock文件的作用
2016/02/03 PHP
Laravel框架基于中间件实现禁止未登录用户访问页面功能示例
2019/01/17 PHP
用javascript连接access数据库的方法
2006/11/17 Javascript
用jscript实现新建和保存一个word文档
2007/06/15 Javascript
js Date自定义函数 延迟脚本执行
2010/03/10 Javascript
Jquery调用webService远程访问出错的解决方法
2010/05/21 Javascript
javascript检测页面是否缩放的小例子
2013/05/16 Javascript
javascript比较两个日期的先后示例代码
2014/12/31 Javascript
html的DOM中document对象images集合用法实例
2015/01/21 Javascript
jQuery入门之层次选择器实例简析
2015/12/11 Javascript
JS中事件冒泡和事件捕获介绍
2016/12/13 Javascript
JS获取本周周一,周末及获取任意时间的周一周末功能示例
2017/02/09 Javascript
JQuery实现定时刷新功能代码
2017/05/09 jQuery
AngularJs 延时器、计时器实例代码
2017/09/16 Javascript
搭建element-ui的Vue前端工程操作实例
2018/02/23 Javascript
使用Vuex解决Vue中的身份验证问题
2018/09/28 Javascript
[04:38]完美世界携手游戏风云打造 卡尔工作室饰品系统篇
2013/04/25 DOTA
Python守护进程(daemon)代码实例
2015/03/06 Python
python Django模板的使用方法
2016/01/14 Python
Python多继承原理与用法示例
2018/08/23 Python
Python pandas.DataFrame 找出有空值的行
2019/09/09 Python
windows下Python安装、使用教程和Notepad++的使用教程
2019/10/06 Python
Python 列表的清空方式
2020/01/13 Python
python标准库os库的函数介绍
2020/02/12 Python
Original Penguin英国官方网站:美国著名休闲时装品牌
2016/10/30 全球购物
希尔顿酒店中国网站:Hilton中国
2017/03/11 全球购物
美国帽子俱乐部商店:Hat Club
2019/07/05 全球购物
Servlet都有哪些方法?主要作用是什么?
2014/03/04 面试题
《梅花魂》教学反思
2014/04/30 职场文书
农民工讨薪标语
2014/06/26 职场文书
个人道歉信大全
2019/04/11 职场文书
导游词之徐州云龙湖
2019/11/19 职场文书
Java框架入门之简单介绍SpringBoot框架
2021/06/18 Java/Android