1.SIFT特征点和特征描述提取(注意opencv版本)

高斯金字塔:O组L层不同尺度的图像(每一组中各层尺寸相同,高斯函数的参数不同,不同组尺寸递减2倍)

特征点定位:极值点

特征点描述:根据不同bin下的方向给定一个主方向,对每个关键点,采用4*4*8共128维向量的描述子进项关键点表征,综合效果最佳:

pip uninstall opencv-python
pip install opencv-contrib-python==3.4.2.16 
1.特征点检测
def sift_kp(image):
gray_image = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
sift = cv2.xfeatures2d_SIFT.create()
kp,des = sift.detectAndCompute(gray_image,None)
kp_image = cv2.drawKeypoints(gray_image,kp,None) return kp_image,kp,des
2.SIFT特征点匹配
SIFT算法得到了图像中的特征点以及相应的特征描述,一般的可以使用K近邻(KNN)算法。K近邻算法求取在空间中距离最近的K个数据点,并将这些数据点归为一类。在进行特征点匹配时,一般使用KNN算法找到最近邻的两个数据点,如果最接近和次接近的比值大于一个既定的值,那么我们保留这个最接近的值,认为它和其匹配的点为good match
def get_good_match(des1,des2):
bf = cv2.BFMatcher()
matches = bf.knnMatch(des1, des2, k=2)
good = []
for m, n in matches:
if m.distance < 0.75 * n.distance:
good.append(m)
return good

 3.单应性矩阵Homography Matrix

通过上面的步骤,我们找到了若干两张图中的匹配点,如何将其中一张图通过旋转、变换等方式将其与另一张图对齐呢?这就用到了单应性矩阵了。Homography这个词由Homo和graphy,Homo意为同一,graphy意为图像,也就是同一个东西产生的图像。
单应性矩阵有八个参数,如果要解这八个参数的话,需要八个方程,由于每一个对应的像素点可以产生2个方程(x一个,y一个),那么总共只需要四个像素点就能解出这个单应性矩阵。
RANSAC算法选择其中最优的四个点

随机抽样一致算法(Random sample consensus:RANSAC)

H, status = cv2.findHomography(ptsA,ptsB,cv2.RANSAC,ransacReprojThreshold)
#其中H为求得的单应性矩阵矩阵
#status则返回一个列表来表征匹配成功的特征点。
#ptsA,ptsB为关键点
#cv2.RANSAC, ransacReprojThreshold这两个参数与RANSAC有关 4.图像匹配

其中:

  • 第一个参数为需要投影的图像(img2
  • 第二个参数为单应性矩阵(H
  • 第三个参数为所得图像的矩阵大小((img1.shape[1],img1.shape[0]) )
  • 最后的参数cv2.INTER_LINEAR + cv2.WARP_INVERSE_MAP,为插值时使用的插值方法INTER_LINEAR,cv2.WARP_INVERSE_MAP则将M设置为dst--->src的方向变换。
def siftImageAlignment(img1,img2):
_,kp1,des1 = sift_kp(img1)
_,kp2,des2 = sift_kp(img2)
goodMatch = get_good_match(des1,des2)
if len(goodMatch) > 4:
ptsA= np.float32([kp1[m.queryIdx].pt for m in goodMatch]).reshape(-1, 1, 2)
ptsB = np.float32([kp2[m.trainIdx].pt for m in goodMatch]).reshape(-1, 1, 2)
ransacReprojThreshold = 4
H, status =cv2.findHomography(ptsA,ptsB,cv2.RANSAC,ransacReprojThreshold);
imgOut = cv2.warpPerspective(img2, H, (img1.shape[1],img1.shape[0]),flags=cv2.INTER_LINEAR + cv2.WARP_INVERSE_MAP)
return imgOut,H,status

  

5.综合应用:

import numpy as np
import cv2
import Utility
img1 = cv2.imread('1.jpg')
img2 = cv2.imread('2.jpg')
result,_,_ = siftImageAlignment(img1,img2)
allImg = np.concatenate((img1,img2,result),axis=1)
cv2.namedWindow('Result',cv2.WINDOW_NORMAL)
cv2.imshow('Result',allImg)
cv2.waitKey(0)

6.SIFT速度太慢,利用surf检测

def surf_kp(image):
'''SIFT(surf)特征点检测(速度比sift快)'''
height, width = image.shape[:2]
size = (int(width * 0.2), int(height * 0.2))
shrink = cv2.resize(image, size, interpolation=cv2.INTER_AREA)
gray_image = cv2.cvtColor(shrink,cv2.COLOR_BGR2GRAY)
surf = cv2.xfeatures2d_SURF.create()
kp, des = surf.detectAndCompute(gray_image, None)
return kp,des

 为了再一次提升速度将图片进行了缩放,再进行匹配的时候要对4对坐标点进行相应的放大即可。

ORB速度更快,不过效果较差

python利用sift和surf进行图像配准的更多相关文章

  1. Opencv探索之路(二十):制作一个简易手动图像配准工具

    近日在做基于sift特征点的图像配准时遇到匹配失败的情况,失败的原因在于两幅图像分辨率相差有点大,而且这两幅图是不同时间段的同一场景的图片,所以基于sift点的匹配已经找不到匹配点了.然后老师叫我尝试 ...

  2. python用直方图规定化实现图像风格转换

    以下内容需要直方图均衡化.规定化知识 均衡化:https://blog.csdn.net/macunshi/article/details/79815870 规定化:https://blog.csdn ...

  3. 基于OpenCV全景拼接(Python)SIFT/SURF

    一.实验内容: 利用sift算法,实现全景拼接算法,将给定的两幅图片拼接为一幅. 二.实验环境: 主机配置: CPU :intel core i5-7300 2.50GHZ RAM :8.0GB 运行 ...

  4. Opencv Sift和Surf特征实现图像无缝拼接生成全景图像

    Sift和Surf算法实现两幅图像拼接的过程是一样的,主要分为4大部分: 1. 特征点提取和描述 2. 特征点配对,找到两幅图像中匹配点的位置 3. 通过配对点,生成变换矩阵,并对图像1应用变换矩阵生 ...

  5. 图像配准:从SIFT到深度学习

      图像配准(Image Registration)是计算机视觉中的基本步骤.在本文中,我们首先介绍基于OpenCV的方法,然后介绍深度学习的方法. 什么是图像配准 图像配准就是找到一幅图像像素到另一 ...

  6. Opencv中使用Surf特征实现图像配准及对透视变换矩阵H的平移修正

    图像配准需要将一张测试图片按照第二张基准图片的尺寸.角度等形态信息进行透视(仿射)变换匹配,本例通过Surf特征的定位和匹配实现图像配准. 配准流程: 1. 提取两幅图像的Surf特征 2. 对Sur ...

  7. 【计算机视觉】图像配准(Image Registration)

    (Source:https://blog.sicara.com/image-registration-sift-deep-learning-3c794d794b7a)  图像配准方法概述 图像配准广泛 ...

  8. CV 两幅图像配准

    http://www.cnblogs.com/Lemon-Li/p/3504717.html 图像配准算法一般可分为: 一.基于图像灰度统计特性配准算法:二.基于图像特征配准算法:三.基于图像理解的配 ...

  9. sift、surf、orb 特征提取及最优特征点匹配

    目录 sift sift特征简介 sift特征提取步骤 surf surf特征简介 surf特征提取步骤 orb orb特征简介 orb特征提取算法 代码实现 特征提取 特征匹配 附录 sift si ...

随机推荐

  1. 常用的python内建函数

    raw_input() 函数说明 函数签名:raw_input([prompt]) 使用形式如下: raw_input([prompt]) -> string 如果提供了参数prompt,就会在 ...

  2. Linux中ifcfg-eth0配置参数说明

    ifcfg-eth0在/etc/sysconfig/network-scripts下, 其配置如下: DEVICE=物理设备名IPADDR=IP地址NETMASK=掩码值NETWORK=网络地址BRO ...

  3. uni-app学习记录04-轮播图和滑屏图片

    <template> <view> <!-- 轮播图视图 swiper-item是每页的元素 --> <swiper :indicator-dots=&quo ...

  4. poj 3295

    题目意思就是计算表达式的值,如果所有情况下表达式为真就输出“tautology”,否则输出“not”. p, q, r, s, and t,每个人有两种情况,综合起来一共有32种情况,枚举所有情况最后 ...

  5. H3C 单路径网络中环路产生过程(3)

  6. 51nod 范德蒙矩阵

    思路: 根据矩阵乘法的定义,G中的第i行第j列的元素 ai,j ,对答案的贡献为 ai,j∗ T中第j行的所有元素之和. 因此我们可以将T中根据每行的和进行排序.第i行的和可以通过公式 (ai^n−1 ...

  7. git 常用操作命令(Common operation)

    win10清除已登录账号密码方法 打开控制面板(Control Panel): 选择用户账户(User Accounts): 选择管理你的凭据(Credential Manager): 管理windo ...

  8. Linux 内核端点

    USB 通讯的最基本形式是通过某些称为 端点 的. 一个 USB 端点只能在一个方向承载数 据, 或者从主机到设备(称为输出端点)或者从设备到主机(称为输入端点). 端点可看作一 个单向的管道. 一个 ...

  9. XSS攻击及防范

    1.什么是XSS攻击 跨站脚本攻击(Cross Site Scripting),攻击者往Web页面里插入恶意Script代码,当用户浏览该页之时,嵌入其中Web里面的Script代码会被执行,从而达到 ...

  10. Android5_浅谈Java的package机制

    当代码量越来越大,类越来越多.尤其会增加同名类的风险.所以对类进行管理就显得非常重要. 包(package)机制是java中管理类的重要手段. 包名的命名方式:业内默认的做法是使用公司的网络域名的倒写 ...