Python OpenCV中如何进行特征点检测与匹配
Python OpenCV中如何进行特征点检测与匹配
PythonOpenCV中如何进行特征点检测与匹配,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。
背景
提取图像的特征点是图像领域中的关键任务,不管在传统还是在深度学习的领域中,特征代表着图像的信息,对于分类、检测任务都是至关重要的;
特征点应用的一些场景:
图像搜索:以图搜图(电商、教育领域)
图像拼接:全景拍摄(关联图像拼接)
拼图游戏:游戏领域
一、Harris角点
哈里斯角点检测主要有以下三种情况:
光滑区域:无论向哪个方向移动,衡量系数不变;
边缘区域:垂直边缘移动时,衡量系数变化强烈;
角点区域:不管往哪个方向移动,衡量系数变化强烈;
函数原型:
cornerHarris(img,blockSize,ksize,k)
blockSize
:检测窗口大小;
k
:权重系数,一般取0.02~0.04之间;
代码案例:
img=cv2.imread('chess.png')gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)dst=cv2.cornerHarris(gray,2,3,0.04)img[dst>0.01*dst.max()]=(0,0,255)cv2.imshow('harris',img)cv2.waitKey(0)
二、Shi-Tomasi角点检测
说明:是Harris角点检测的改进,在Harris中需要知道k这个经验值,而在Shi-Tomasi不需要;
函数原型:
goodFeaturesToTrack(img,…)
maxCorners
:角点的最大数量,值为0表示所有;
qualityLevel
:角点的质量,一般在0.01~0.1之间(低于的过滤掉);
minDistance
:角点之间最小欧式距离,忽略小于此距离的点;
mask
:感兴趣区域;
useHarrisDetector
:是否使用Harris算法(默认为false)
代码案例:
img=cv2.imread('chess.png')gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)dst=cv2.goodFeaturesToTrack(gray,1000,0.01,10)dst=np.int0(dst)#实际上也是np.int64foriindst:x,y=i.ravel()#数组降维成一维数组(inplace的方式)cv2.circle(img,(x,y),3,(0,0,255),-1)cv2.imshow('harris',img)cv2.waitKey(0)
本质上和Harris角点检测相同,效果会好一些,角点数量会多一些;
三、SIFT关键点
中文简译:与缩放无关的特征转换;
说明:Harris角点检测具有旋转不变性,也就是旋转图像并不会影响检测效果;但其并不具备缩放不变性,缩放大小会影响角点检测的效果;SIFT具备缩放不变性的性质;
实现步骤:
创建SIFT对象 —— 进行检测(sift.detect) —— 绘制关键点(drawKeypoints)
代码案例:
img=cv2.imread('chess.png')gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)sift=cv2.xfeatures2d.SIFT_create()kp=sift.detect(gray,None)#第二个参数为mask区域cv2.drawKeypoints(gray,kp,img)cv2.imshow('sift',img)cv2.waitKey(0)
四、SIFT描述子
首先需要说明,关键点和描述子是两个概念;
关键点:位置、大小和方向;
关键点描述子:记录了关键点周围对其有贡献的像素点的一组向量值,其不受仿射变换,光照变换等影响;描述子的作用就是用于特征匹配;
同时计算关键点和描述子的函数(主要使用):
detectAndCompute(img,…)
代码案例:
img=cv2.imread('chess.png')gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)sift=cv2.xfeatures2d.SIFT_create()kp,dst=sift.detectAndCompute(gray,None)#第二个参数为mask区域
得到的dst即为描述子的信息;
五、SURF
中译:加速的鲁棒性特征检测;
说明:SIFT最大的缺点是速度慢,因此才会有SURF(速度快);
实现步骤与SIFT一致,代码如下:
surf=cv2.xfeatures2d.SURF_create()kp,dst=surf.detectAndCompute(gray,None)#第二个参数为mask区域cv2.drawKeypoints(gray,kp,img)
由于安装的opencv-contrib版本过高(有版权问题),已经不支持该功能了,在此就不作展示了;
六、ORB
说明:最大的优势就是做到实时检测,缺点就是缺失了很多信息(准确性下降);
主要是两个技术的结合:FAST(特征点实时检测)+ BRIEE(快速描述子建立,降低特征匹配时间)
使用步骤与之前的SIFT一致,代码如下:
img=cv2.imread('chess.png')gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)orb=cv2.ORB_create()kp,dst=orb.detectAndCompute(gray,None)#第二个参数为mask区域cv2.drawKeypoints(gray,kp,img)cv2.imshow('orb',img)cv2.waitKey(0)
可以看出,相比于SIFT以及SURF关键点变少了,但是其速度有了很大提升;
七、暴力特征匹配(BF)
匹配原理:类似于穷举匹配机制,使用第一组中每个特征的描述子与第二组中的进行匹配,计算相似度,返回最接近的匹配项;
实现步骤:
创建匹配器:BFMatcher(normType,crossCheck)
进行特征匹配:bf.match(des1,des2)
绘制匹配点:cv2.drawMatches(img1,kp1,img2,kp2)
代码案例:
img1=cv2.imread('opencv_search.png')img2=cv2.imread('opencv_orig.png')g1=cv2.cvtColor(img1,cv2.COLOR_BGR2GRAY)g2=cv2.cvtColor(img2,cv2.COLOR_BGR2GRAY)sift=cv2.SIFT_create()kp1,dst1=sift.detectAndCompute(g1,None)#第二个参数为mask区域kp2,dst2=sift.detectAndCompute(g2,None)#第二个参数为mask区域bf=cv2.BFMatcher_create(cv2.NORM_L1)match=bf.match(dst1,dst2)img3=cv2.drawMatches(img1,kp1,img2,kp2,match,None)cv2.imshow('result',img3)cv2.waitKey(0)
从上图可看出,匹配的效果还是不错的,只有一个特征点匹配错误;
八、FLANN特征匹配
优点:在进行批量特征匹配时,FLANN速度更快;
缺点:由于使用的时邻近近似值,所有精度较差;
实现步骤与暴力匹配法一致,代码如下:
img1=cv2.imread('opencv_search.png')img2=cv2.imread('opencv_orig.png')g1=cv2.cvtColor(img1,cv2.COLOR_BGR2GRAY)g2=cv2.cvtColor(img2,cv2.COLOR_BGR2GRAY)sift=cv2.SIFT_create()kp1,dst1=sift.detectAndCompute(g1,None)#第二个参数为mask区域kp2,dst2=sift.detectAndCompute(g2,None)#第二个参数为mask区域index_params=dict(algorithm=1,trees=5)search_params=dict(checks=50)flann=cv2.FlannBasedMatcher(index_params,search_params)matchs=flann.knnMatch(dst1,dst2,k=2)good=[]fori,(m,n)inenumerate(matchs):ifm.distance<0.7*n.distance:good.append(m)img3=cv2.drawMatchesKnn(img1,kp1,img2,kp2,[good],None)cv2.imshow('result',img3)cv2.waitKey(0)
上图可以看出,匹配的特征点数量相比暴力匹配明显变少了,但速度会快很多;
九、图像查找
实现原理:特征匹配 + 单应性矩阵;
单应性矩阵原理介绍:
上图中表示从两个不同角度对原图的拍摄,其中H为单应性矩阵,可通过该矩阵将图像进行转换;
下面使用两个函数实现图像查找的功能:
findHomography():获得单应性矩阵;
perspectivveTransform():仿射变换函数;
代码实现如下:
img1=cv2.imread('opencv_search.png')img2=cv2.imread('opencv_orig.png')g1=cv2.cvtColor(img1,cv2.COLOR_BGR2GRAY)g2=cv2.cvtColor(img2,cv2.COLOR_BGR2GRAY)sift=cv2.SIFT_create()kp1,dst1=sift.detectAndCompute(g1,None)#第二个参数为mask区域kp2,dst2=sift.detectAndCompute(g2,None)#第二个参数为mask区域index_params=dict(algorithm=1,trees=5)search_params=dict(checks=50)flann=cv2.FlannBasedMatcher(index_params,search_params)matchs=flann.knnMatch(dst1,dst2,k=2)good=[]fori,(m,n)inenumerate(matchs):ifm.distance<0.7*n.distance:good.append(m)iflen(good)>=4:#获得源和目标点的数组srcPts=np.float32([kp1[m.queryIdx].ptformingood]).reshape(-1,1,2)dstPts=np.float32([kp2[m.trainIdx].ptformingood]).reshape(-1,1,2)#获得单应性矩阵HH,_=cv2.findHomography(srcPts,dstPts,cv2.RANSAC,5.0)h,w=img1.shape[:2]pts=np.float32([[0,0],[0,h-1],[w-1,h-1],[w-1,0]]).reshape(-1,1,2)#进行放射变换dst=cv2.perspectiveTransform(pts,H)#绘制查找到的区域cv2.polylines(img2,[np.int32(dst)],True,(0,0,255))else:print('goodmustmorethen4.')exit()img3=cv2.drawMatchesKnn(img1,kp1,img2,kp2,[good],None)cv2.imshow('result',img3)cv2.waitKey(0)
Python主要用来做什么
Python主要应用于:1、Web开发;2、数据科学研究;3、网络爬虫;4、嵌入式应用开发;5、游戏开发;6、桌面应用开发。
关于PythonOpenCV中如何进行特征点检测与匹配问题的解答就分享到这里了,希望以上内容可以对大家有一定的帮助,如果你还有很多疑惑没有解开,可以关注恰卡编程网行业资讯频道了解更多相关知识。
推荐阅读
-
python多行注释符号怎么表示
python多行注释符号怎么表示这篇文章主要介绍“python多行...
-
python支持的操作系统是什么
python支持的操作系统是什么这篇文章主要介绍“python支持...
-
python如何判断列表为空
python如何判断列表为空这篇文章主要介绍“python如何判断...
-
Python如何利用D3Blocks绘制可动态交互的图表
-
2021年度编程语言揭晓
-
PPython:PHP 拥抱 Python 的利器
-
哪种Python IDE最适合你?这里有一份优缺点列表
-
Python分隔字符串函数用法split
aaa,bbb=str.split(‘&&’,2)第一个参数为分隔符第二个参数是要完成的最大拆分数...
-
php安全编程——python测试实例编写
-
神奇的Python模块:pdfkit,将Python抓取的网址内容保存pdf文件