【Opencv】Python3.7+Opencv3.x SIFT特征检测与匹配(采坑记录)

Python3.7+Opencv3.x SIFT特征检测与匹配

  • SIFT图像特征检测理解
  • SIFT算法步骤
  • 实验与结果
    • 安装配置记录
    • 代码
    • 运行结果

SIFT图像特征检测理解

得到特征关键点,并可以将关键点向量化.
实质是在不同的尺度空间上查找关键点(特征点),并计算出关键点的方向。

SIFT所查找到的关键点是一些十分突出,不会因光照,仿射变换和噪音等因素而变化的点,如角点、边缘点、暗区的亮点及亮区的暗点等。


SIFT
尺度不变特征转换(Scale-invariant feature transform或SIFT)是一种电脑视觉的算法用来侦测与描述影像中的局部性特征,它在空间尺度中寻找极值点,并提取出其位置、尺度、旋转不变量。
其应用范围包含物体辨识、机器人地图感知与导航、影像缝合、3D模型建立、手势辨识、影像追踪和动作比对。
【Opencv】Python3.7+Opencv3.x SIFT特征检测与匹配(采坑记录)_第1张图片
尺度空间
对现实中物体的描述一定要在一个十分重要的前提下进行,这个前提就是对自然界建模时的尺度。当用一个机器视觉系统分析未知场景时,计算机没有办法预先知道图像中物体的尺度,因此我们需要同时考虑图像在多尺度下的描述,获知感兴趣物体的最佳尺度。图像的尺度空间表达指的是图像的所有尺度下的描述。

SIFT算法步骤

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

实验与结果

安装配置记录

这个算法是受专利保护的。所以这个算法包含在 OpenCV 中的收费模块中。因此我们降低版本才可能用,本来我的Opencv是4.2.x版本,是用不了SIFT算法的。因此首先uninstall它,再pip install相应版本的opencv-python和opencv-contrib-python。【SIFT在这个包里】

步骤:
1.卸载现有的高版本:pip uninstall opencv-python
【Opencv】Python3.7+Opencv3.x SIFT特征检测与匹配(采坑记录)_第2张图片
2.安装3.4.2.16版本的,版本要一致哦。亲测可用!

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

【Opencv】Python3.7+Opencv3.x SIFT特征检测与匹配(采坑记录)_第3张图片
(o)/~

代码

sift_kp(image):进行sift关键点检测
get_good_match(des1, des2):对两张图进行最佳匹配
显示出所有较好的匹配和前N个较好的关键点匹配。

import cv2
import numpy as np


def sift_kp(image):
    gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    sift = cv2.xfeatures2d.SIFT_create()
    kp, des = sift.detectAndCompute(image, None)
    kp_image = cv2.drawKeypoints(gray_image, kp, None)
    return kp_image, kp, des


def get_good_match(des1, des2):
    bf = cv2.BFMatcher()
    matches = bf.knnMatch(des1, des2, k=2)  # des1为模板图,des2为匹配图
    matches = sorted(matches, key=lambda x: x[0].distance / x[1].distance)
    good = []
    for m, n in matches:
        if m.distance < 0.75 * n.distance:
            good.append(m)
    return good


img1 = cv2.imread(r'd:/t1.jpg')
img2 = cv2.imread(r'd:/t2.jpg')

kpimg1, kp1, des1 = sift_kp(img1)
kpimg2, kp2, des2 = sift_kp(img2)

cvshow('img1',np.hstack((img1,kpimg1)))
cvshow('img2',np.hstack((img2,kpimg2)))

goodMatch = get_good_match(des1, des2)
all_goodmatch_img= cv2.drawMatches(img1, kp1, img2, kp2, goodMatch, None, flags=2)
# goodmatch_img自己设置前多少个goodMatch[:10]
goodmatch_img = cv2.drawMatches(img1, kp1, img2, kp2, goodMatch[:10], None, flags=2)

cvshow('all_goodmatch_img', all_goodmatch_img)
cvshow('goodmatch_img', goodmatch_img)

运行结果

原图:

图1与其SIFT关键点检测:

图2与其SIFT关键点检测:

match(画出所有goodmatch):

match(只画出前N个goodmatch)效果较好:


附实验原图(自取,网上随便找的埃菲尔铁塔的图):
【Opencv】Python3.7+Opencv3.x SIFT特征检测与匹配(采坑记录)_第4张图片
【Opencv】Python3.7+Opencv3.x SIFT特征检测与匹配(采坑记录)_第5张图片
最后说一下,本来也想实验一下PCV版本,把python2改成3可用的形式,又下载vlfeat各种配置实验,依旧有生成不了关键点文件的问题,改了很久依旧有报错,心态崩了就重新回来用cv2了,不过希望大家都能在网速好的时候安装opencv-contrib-python包,真的断了好多次,今天异常顺利!快乐!撒花结束一下~
【Opencv】Python3.7+Opencv3.x SIFT特征检测与匹配(采坑记录)_第6张图片
---------------EchoZhang-------2020/04/02----------------------

你可能感兴趣的:(CV)