图像配准基于传统特征的方法代码实现(SIFT、SURF、ORB、AKAZE)

自21世纪初以来,图像配准主要使用基于特征的方法。这些方法有三个步骤:关键点检测和特征描述,特征匹配,图像变换。简单的说,我们选择两个图像中的感兴趣点,将参考图像(reference image)与感测图像(sensed image)中的等价感兴趣点进行关联,然后变换感测图像使两个图像对齐。

关键点就是感兴趣点,它表示图像中重要或独特的内容(边角,边缘等)。每个关键点由描述符表示,关键点基本特征的特征向量。描述符应该对图像变换(定位,缩放,亮度等)具有鲁棒性。许多算法使用关键点检测和特征描述:

  • SIFT^4(Scale-invariant feature transform)是用于关键点检测的原始算法,但它不能免费用于商业用途。SIFT特征描述符对于均匀缩放,方向,亮度变化和对仿射失真不变的部分不会发生变化。
  • SURF^5(Speeded Up Robust Features)是一个受SIFT启发的探测器和描述符。它的优点是非常快。它同样是有专利的。
  • ORB^6(Oriented FAST and Rotated BRIEF)是一种快速的二进制描述符,它基于 FAST^7(Features from Accelerated Segment Test)关键点检测和 BRIEF^8(Binary robust independent elementary features)描述符的组合。它具有旋转不变性和对噪声的鲁棒性。它由OpenCV实验室开发,是SIFT有效的免费替代品。
  • AKAZE^9(Accelerated-KAZE)是KAZE^10快速版本。它为非线性尺度空间^11提供了快速的多尺度特征检测和描述方法,具有缩放和旋转不变性。
SIFT代码:

关键函数
创建一个SIFT对象:

cv2.xfeatures2d.SIFT_create(, nfeatures, nOctaveLayers, contrastThreshold, edgeThreshold, sigma)

nfeatures:默认为0,要保留的最佳特征的数量。 特征按其分数排名(在SIFT算法中按局部对比度排序)
nOctaveLayers:默认为3,金字塔每组(Octave)有多少层。 3是D. Lowe纸中使用的值。
contrastThreshold:默认为0.04,对比度阈值,用于滤除半均匀(低对比度)区域中的弱特征。 阈值越大,检测器产生的特征越少。
edgeThreshold:默认为10,用来过滤边缘特征的阈值。注意,它的意思与contrastThreshold不同,edgeThreshold越大,滤出的特征越少(保留更多特征)。
sigma:默认为1.6,高斯金字塔中的σ。 如果使用带有软镜头的弱相机拍摄图像,则可能需要减少数量。
检测特征点:

sift.detect(image,keypoints)  或  keypoint = sift.detect(image, None)

sift:配置好SIFT算法对象
image:输入图像,单通道
keypoint:输出参数,保存着特征点,每个特征点包含有以下信息:
                         Point2f pt:坐标 
                         float size:特征点的邻域直径 
                         float angle:特征点的方向,值为[0,360度),负值表示不使用 
                         float response; 
                         int octave:特征点所在的图像金字塔的组 
                         int class_id:用于聚类的id 

绘制特征点:

cv2.drawKeypoint(image, keypoints, outImage, color, flags)
或:outImage = cv2.drawKeypoint(image, keypoints, None, color, flags)

image:输入图像
keypoints:上面获取的特征点
outImage:输出图像
color:颜色,默认为随机颜色
flags:绘制点的模式,有以下四种模式

cv2.DRAW_MATCHES_FLAGS_DEFAULT:

默认值,只绘制特征点的坐标点,显示在图像上就是一个个小圆点,每个小圆点的圆心坐标都是特征点的坐标。

cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS:

绘制特征点的时候绘制的是带有方向的圆,这种方法同时显示图像的坐标,size,和方向,是最能显示特征的一种绘制方式。

cv2.DRAW_MATCHES_FLAGS_DRAW_OVER_OUTIMG:

只绘制特征点的坐标点,显示在图像上就是一个个小圆点,每个小圆点的圆心坐标都是特征点的坐标。

cv2.DRAW_MATCHES_FLAGS_NOT_DRAW_SINGLE_POINT:

 单点的特征点不被绘制 

OpenCV-Python——第26章:SIFT特征点提取算法_sift提取关键点的顺序-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/yukinoai/article/details/88912586

 SURF代码实现
import cv2
import numpy as npimg = cv2.imread('./image/cali.bmp')
img = cv2.resize(img,dsize=(600,400))
#转换为灰度图像
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
#创建一个SURF对象
surf = cv2.xfeatures2d.SURF_create(20000)
#surf对象会使用Hessian算法检测关键点,并且对每个关键点周围的区域计算特征向量。该函数返回关键点的信息和描述符
keypoints,descriptor = surf.detectAndCompute(gray,None)
print(type(keypoints),len(keypoints),keypoints[0])
print(descriptor.shape)
#在图像上绘制关键点
img = cv2.drawKeypoints(image=img,keypoints = keypoints,outImage=img,color=(255,0,255),flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
#显示图像
cv2.imshow('surf_keypoints',img)
cv2.waitKey(0)
cv2.destroyAllWindows()
 ORB代码实现:(特征匹配,图像对齐)

无人机航拍图像匹配——ORB算法实践(含代码)_orb实现-CSDN博客文章浏览阅读1.2k次。无人机航拍图像,用orb算法进行匹配_orb实现https://blog.csdn.net/zhangzhao147/article/details/131094471寻找图像中的关键点,创建相应的二进制特征向量,并在ORB描述符中将它们组合在一起。

#角点检测,角点数500
orb = cv2.ORB_create(500)
#描述子生成
keypoints1, descriptors1 = orb.detectAndCompute(image1, None)
keypoints2, descriptors2 = orb.detectAndCompute(image2, None)
# 暴力匹配
matcher = cv2.DescriptorMatcher_create(cv2.DESCRIPTOR_MATCHER_BRUTEFORCE_HAMMING)
# 特征点匹配
matches = matcher.match(descriptors1, descriptors2)#滤波去除不好的特征点ratio_threshold = 0.4
#ratio_threshold一般设置在0.4-0.8之间,如果对精度要求极高,可尽量小。当然,如果设置的太小,可能导致筛选后的匹配点数目稀少,如果少于4对,将会报错。
good_matches = []for match in matches:if hasattr(match, 'distance'):m = match.distance
#m代表匹配点之间的差异,当然越小越好,通过这个步骤可以剔除离群点。if hasattr(match, 'trainIdx'):n = matches[match.trainIdx].distanceif m < ratio_threshold * n:good_matches.append(match)else:good_matches.append(match)#计算转移矩阵
# 提取匹配的特征点的坐标
src_points = np.float32([keypoints1[m.queryIdx].pt for m in good_matches]).reshape(-1, 1, 2)
dst_points = np.float32([keypoints2[m.trainIdx].pt for m in good_matches]).reshape(-1, 1, 2)# 计算单应矩阵
H, _ = cv2.findHomography(src_points, dst_points, cv2.RANSAC, 3)
#H ,_= cv2.findHomography(src_points, dst_points)
# 输出单应矩阵H
print("Homography Matrix:")
print(H)# 计算每对匹配点的误差L2
errors = []
right_point=[]
thrshold=10
for match in good_matches:kp1 = keypoints1[match.queryIdx]kp2 = keypoints2[match.trainIdx]pt1 = np.array([kp1.pt[0], kp1.pt[1], 1])pt2 = np.array([kp2.pt[0], kp2.pt[1], 1])pt1_transformed = np.dot(H, pt1)error = np.linalg.norm(pt1_transformed - pt2) ** 2if np.linalg.norm(pt1_transformed - pt2)<thrshold :right_point.append(np.linalg.norm(pt1_transformed - pt2))errors.append(error)# 计算误差的和L1
L1 = sum(errors)# 计算均方误差MSE
MSE = np.sqrt(L1) / len(errors)
num_right=len(right_point)
num_all=len(errors)
precision=num_right/num_allprint("MSE:", MSE)
print("总匹配点数:",num_all )
print("正确匹配点数:",num_right )
print("precision:", precision)#匹配结果展示
result = cv2.drawMatches(image1, keypoints1, image2, keypoints2, good_matches, None,matchColor=(0, 255, 0), singlePointColor=(0, 0, 255), flags=cv2.DrawMatchesFlags_DEFAULT)
# result = cv2.drawMatches(color_image1, keypoints1, color_image2, keypoints2, good_matches, None,
#                          matchColor=(0, 255, 0), singlePointColor=(0, 0, 255), flags=cv2.DrawMatchesFlags_DEFAULT)# 调整线条宽度
line_thickness = 2
for match in good_matches:pt1 = (int(keypoints1[match.queryIdx].pt[0]), int(keypoints1[match.queryIdx].pt[1]))pt2 = (int(keypoints2[match.trainIdx].pt[0]), int(keypoints2[match.trainIdx].pt[1]))cv2.line(result, pt1, pt2, (0, 0, 255), thickness=line_thickness)# 创建匹配结果显示窗口
cv2.namedWindow('Matches', cv2.WINDOW_NORMAL)
cv2.resizeWindow('Matches', 800, 600)
# 显示匹配结果
cv2.imshow('Matches', result)
cv2.waitKey(0)
cv2.destroyAllWindows()


定位关键点ORB_create()函数解析_cv2.orb_create()-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/qq_18649781/article/details/88885208

AKAZE代码实现:
import numpy as np
import cv2 as cv
import matplotlib.pyplot as pltimg1 = cv.imread('image1.jpg', cv.IMREAD_GRAYSCALE)
img2 = cv.imread('image2.jpg', cv.IMREAD_GRAYSCALE)# 初始化 AKAZE 探测器
akaze = cv.AKAZE_create()
# 使用 SIFT 查找关键点和描述
kp1, des1 = akaze.detectAndCompute(img1, None)
kp2, des2 = akaze.detectAndCompute(img2, None)# BFMatcher 默认参数
bf = cv.BFMatcher()
matches = bf.knnMatch(des1, des2, k=2)# 旋转测试
good_matches = []
for m,n in matches:if m.distance < 0.75*n.distance:good_matches.append([m])# 画匹配点
img3 = cv.drawMatchesKnn(img1,kp1,img2,kp2,good_matches,None,flags=cv.DrawMatchesFlags_NOT_DRAW_SINGLE_POINTS)
cv.imwrite('matches.jpg', img3)# 选择匹配关键点
ref_matched_kpts = np.float32([kp1[m[0].queryIdx].pt for m in good_matches]).reshape(-1,1,2)
sensed_matched_kpts = np.float32([kp2[m[0].trainIdx].pt for m in good_matches]).reshape(-1,1,2)# 计算 homography
H, status = cv.findHomography(ref_matched_kpts, sensed_matched_kpts, cv.RANSAC,5.0)# 变换
warped_image = cv.warpPerspective(img1, H, (img1.shape[1]+img2.shape[1], img1.shape[0]))cv.imwrite('warped.jpg', warped_image)


图像配准:从SIFT到深度学习 - 知乎 (zhihu.com)icon-default.png?t=N7T8https://zhuanlan.zhihu.com/p/75784915

特征匹配 

sift、surf、orb 特征提取及最优特征点匹配-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/weixin_30466421/article/details/98593048?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522170497765116800215066141%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=170497765116800215066141&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduend~default-2-98593048-null-null.142^v99^pc_search_result_base8&utm_term=surf%E7%89%B9%E5%BE%81%E6%8F%90%E5%8F%96&spm=1018.2226.3001.4187 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/340979.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

完整的模型训练套路(一、二、三)

搭建神经网络 model import torch from torch import nn#搭建神经网络 class Tudui(nn.Module):def __init__(self):super(Tudui, self).__init__()self.model nn.Sequential(nn.Conv2d(3, 32, 5, 1, 2),nn.MaxPool2d(2),nn.Conv2d(32, 32, 5, 1, 2),nn.MaxPool2d(2),nn.Conv…

海外市场调研为什么要用独享静态代理IP?

独享静态IP在海外市场调研中扮演着至关重要的角色&#xff0c;提供了一系列无可比拟的优势。独享静态代理IP的稳定性和可靠性对于长期的市场调研至关重要&#xff0c;它保证了连接的持续性和数据的准确性。通过这些方面的综合优势&#xff0c;独享静态代理IP成为海外市场调研中…

【JavaWeb学习笔记】19 - 网购家居项目开发(上)

一、项目开发流程 程序框架图 项目具体分层方案 MVC 1、说明是MVC MVC全称: Mode模型、View视图、Controller控制器。 MVC最早出现在JavaEE三层中的Web层&#xff0c;它可以有效的指导WEB层的代码如何有效分离&#xff0c;单独工作。 View视图:只负责数据和界面的显示&…

张驰咨询:集成产品开发(IPD)的原理和实践技巧

IPD&#xff0c;是集成产品开发&#xff08;Integrated Product Development&#xff09;的缩写&#xff0c;它是集成了众多管理模型和理论、众多企业最佳管理实践的一整套体系&#xff0c;可以帮助企业快速响应市场变化、缩短产品上市时间、减少资源浪费、提高生产力&#xff…

RK3399平台入门到精通系列讲解(基础篇)__LITTLE_ENDIAN_BITFIELD 宏的使用

🚀返回总目录 文章目录 一、什么是字节序二、小端模式(Little-Endian)三、大端模式(Big-Endian)四、__LITTLE_ENDIAN_BITFIELD 使用案例一、什么是字节序 在计算机中,数据是以最原始的二进制 0 和 1 的方式被存储的。在大多数现代计算机体系架构中,计算机的最小可寻址数…

【MATLAB源码-第107期】基于matlab的OFDM系统在瑞利信道下功率分配仿真,使用注水算法。

操作环境&#xff1a; MATLAB 2022a 1、算法描述 在瑞利衰落信道下&#xff0c;OFDM&#xff08;正交频分复用&#xff09;系统的功率分配可以通过“注水算法”&#xff08;water-filling algorithm&#xff09;的方法来优化。这种算法的目的是在不同的子载波上分配不同的功…

Hive数据库:嵌入、本地、远程全攻略(上)

Hive分布式数据仓库工具 关系型数据库 建立在关系模型之上的数据库称为关系型数据库(关系模型是由埃德加科德于1970年提出的)&#xff0c;关系型数据库借助集合代数等数学概念处理数据库中的数据。数据查询语言SOL是基于关系型数据库的语言,能够对关系型数据库中的数据进行检…

CSS3中transform2D变形详解

CSS3变形 在CSS3中&#xff0c;动画效果包括3个部分&#xff1a; 变形(transform)过渡(transition)动画(animation) 在实际开发中&#xff0c;有时需要实现元素的各种变形效果&#xff0c;如平移&#xff0c;缩放&#xff0c;旋转&#xff0c;倾斜等。 在CSS3中&#xff0c…

Kafka的简介及架构

目录 消息队列 产生背景 消息队列介绍 常见的消息队列产品 应用场景 消息队列的消息模型 Kafka的基本介绍 简介 Kafka的架构 Kafka的使用 Kafka的shell命令 Kafka的Python API的操作 完成生产者代码 完成消费者代码 消息队列 产生背景 消息队列:指数据在一个容器…

PyCharm使用手册

配置文件和代码模板 文件注释模板&#xff1a; 注释项描述示例Project项目名称hello_pythonFile文件名称hello_python.pyAuthor作者Zhang SanDate创建时间2024-01-11 17:05:00PyVersionPython解释器版本Python3.7Description文件描述这是一个python语言入门文件 效果示例&am…

【阅读笔记】Chain of LoRA

一、论文信息 1 论文标题 Chain of LoRA: Efficient Fine-tuning of Language Models via Residual Learning 2 发表刊物 arXiv2023 3 作者团队 Department of Computer Science, Princeton University School of Computer Science and Engineering, Nanyang Technologic…

2023年人工智能的最新发展(下)

目录 1.MidJourney&#xff1a; 2.GAN: 3.Diffusion Model 4.DALLE、Disco Diffusion 5.Stable Diffusion 1.MidJourney&#xff1a; 2023年3月&#xff0c;一组中国小情侣的照片在网络上迅速走红。这组照片看起来普通&#xff0c;就像一对小情侣的合影&#xff0c;但实…