图像配准:从SIFT到深度学习
图像配准(Image Registration)是计算机视觉中的基本步骤。在本文中,我们首先介绍基于OpenCV的方法,然后介绍深度学习的方法。
什么是图像配准
图像配准就是找到一幅图像像素到另一幅图像像素间的空间映射关系。这些图像可以是不同时间(多时间配准),不同传感器在不同地方拍摄(多模式配准)。这些图像之间的空间关系可以是刚性(rigid)^1(平移和旋转),仿射(affine)^2(例如剪切),单应性^3(homographies)或复杂的大变形模型(complex large deformations models)。
图像配准具有广泛的应用,适用于同一个场景中有多张图像需要进行匹配或叠加。在医学图像领域以及卫星图像分析和光流(optical flow)方面非常普遍。
CT扫描和MRI配准
在本文中,我们将介绍图像配准的几种不同方法。
传统的基于特征的方法
自21世纪初以来,图像配准主要使用基于特征的方法。这些方法有三个步骤:关键点检测和特征描述,特征匹配,图像变换。简单的说,我们选择两个图像中的感兴趣点,将参考图像(reference image)与感测图像(sensed image)中的等价感兴趣点进行关联,然后变换感测图像使两个图像对齐。
基于特征的方法
关键点检测和特征描述
关键点就是感兴趣点,它表示图像中重要或独特的内容(边角,边缘等)。每个关键点由描述符表示,关键点基本特征的特征向量。描述符应该对图像变换(定位,缩放,亮度等)具有鲁棒性。许多算法使用关键点检测和特征描述:
这些算法都可以在OpenCV中轻松使用。在下面的例子中,我们使用了AKAZE的OpenCV实现。其他算法的代码大致相同,只需要修改算法的名称。
import numpy as npimport cv2 as cvimg = cv.imread('image.jpg')gray= cv.cvtColor(img, cv.COLOR_BGR2GRAY)akaze = cv.AKAZE_create()kp, descriptor = akaze.detectAndCompute(gray, None)img=cv.drawKeypoints(gray, kp, img)cv.imwrite('keypoints.jpg', img)as np
import cv2 as cv
img = cv.imread('image.jpg')
gray= cv.cvtColor(img, cv.COLOR_BGR2GRAY)
akaze = cv.AKAZE_create()
kp, descriptor = akaze.detectAndCompute(gray, None)
img=cv.drawKeypoints(gray, kp, img)
cv.imwrite('keypoints.jpg', img)
图像关键点
更过关于特征提取和描述的文档
特征匹配
一旦在一对图像中识别出关键点,我们就需要将两个图像中对应的关键点进行关联或“匹配”。其中一种方法是BFMatcher.knnMatch()
。这个方法计算每对关键点之间的描述符的距离,并返回每个关键点的k个最佳匹配中的最小距离。
然后我们设定比率来保持正确率。实际上,为了使匹配更可靠,匹配的关键点需要比最近的错误匹配更靠近。
import numpy as npimport cv2 as cvimport 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)as np
import cv2 as cv
import matplotlib.pyplot as plt
img1 = 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)
匹配的关键点
OpenCV中有更多关于特征匹配的实现方法
图像变换
在匹配至少四对关键点之后,我们就可以将一个图像转换为另一个图像,称为图像变换^12(image warping)。空间中相同平面的两个图像通过单应性变换^13(Homographies)进行关联。Homographies是具有8个自由参数的几何变换,由3x3矩阵表示图像的整体变换(与局部变换相反)。因此,为了获得变换后的感测图像,需要计算Homographies矩阵。
为了得到最佳的变换,我们需要使用RANSAC算法检测异常值并去除。它内置在OpenCV的findHomography方法中。同时也存在RANSAC算法的替代方案,例如LMEDS:Least-Median鲁棒方法。
# 选择匹配关键点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)# 计算 homographyH, 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)
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)
变换后的图像
OpenCV对这三个步骤进行了综合叙述
深度学习方法
目前大多数关于图像配准的研究涉及深度学习。在过去的几年中,深度学习使计算机视觉任务具有先进的性能,如图像分类,物体检测和分割。
特征提取
深度学习用于图像配准的第一种方式是用于特征提取。卷积神经网络设法获得越来越复杂的图像特征并进行学习。2014年以来,研究人员将这些网络应用于特征提取的步骤,而不是使用SIFT或类似算法。
SIFT和基于深度学习的非刚性配准方法描述符的结果
Homography学习
研究人员利用神经网络直接学习几何变换对齐两幅图像,而不仅仅局限于特征提取。
监督学习
在2016年,DeTone等人发表了 Deep Image Homography Estimation,提出了HomographyNe回归网络,这是一种VGG风格模型,可以学习两幅相关图像的单应性。该算法具有以端到端的方式同时学习单应性和CNN模型参数的优势,不需要前两个阶段的过程!
HomographyNet回归网络
网络产生八个数值作为输出。以监督的方式进行训练,并计算输出和真实单应性之间的欧几里德损失。
Supervised Deep Homography Estimation
与其他有监督方法一样,该单应性估计方法需要有标记数据。虽然很容易获得真实图像的单应性,但在实际数据上要昂贵得多。
无监督学习
基于这个想法,Nguyen等人提出了一种无监督的深度图像单应性估计方法。他们保留了相同结构的CNN,但是使用适合无监督方法的损失函数:不需要人工标签的光度损失(photometric loss)函数。相反,它计算参考图像和感测变换图像之间的相似性。
L1光度损失函数
他们的方法引入了两种新的网络结构:张量直接线性变换和空间变换层。我们可以简单地使用CNN模型输出的单应性参数获得变换后的感测图像,然后我们使用它们来计算光度损失。
Unsupervised Deep Homography Estimation
作者声称,与传统的基于特征的方法相比,这种无监督方法具有相当或更高的准确率和鲁棒性,并且具有更快的执行速度。此外,与有监督方法相比,它具有更好的适应性和性能。
其他方法
强化学习
强化学习方法作为医学应用的常用方法正在得到越来越多的关注。与预定义的优化算法相反,在这种方法中,我们使用训练好的代理进行配准。
强化学习方法的配准可视化
复杂的转换
在当前图像配准研究中占较大比例的是医学影像。通常,由于患者的局部变形(因呼吸,解剖学变化等),两个医学图像之间的变换不能简单地通过单应矩阵描述,这需要更复杂的变换模型,例如由位移矢量场表示微分同胚(diffeomorphisms)。
心脏MRI图像上的变形网格和位移矢量场示例
研究人员开始尝试使用神经网络来估计这些具有许多参数的大变形模型。
来自MNIST两个输入图像的DIRNet示意图
欢迎关注磐创博客资源汇总站:
http://docs.panchuang.net/
欢迎关注PyTorch官方中文教程站:
http://pytorch.panchuang.net/
图像配准:从SIFT到深度学习的更多相关文章
- 【计算机视觉】图像配准(Image Registration)
(Source:https://blog.sicara.com/image-registration-sift-deep-learning-3c794d794b7a) 图像配准方法概述 图像配准广泛 ...
- paper 53 :深度学习(转载)
转载来源:http://blog.csdn.net/fengbingchun/article/details/50087005 这篇文章主要是为了对深度学习(DeepLearning)有个初步了解,算 ...
- 【转】用深度学习做crowd density estimation
本博文主要是CVPR2016的<Single-Image Crowd Counting via Multi-Column Convolutional Neural Network>这篇文章 ...
- Teaching Machines to Understand Us 让机器理解我们 之二 深度学习的历史
Deep history 深度学习的历史 The roots of deep learning reach back further than LeCun’s time at Bell Labs. H ...
- 用深度学习(CNN RNN Attention)解决大规模文本分类问题 - 综述和实践
https://zhuanlan.zhihu.com/p/25928551 近来在同时做一个应用深度学习解决淘宝商品的类目预测问题的项目,恰好硕士毕业时论文题目便是文本分类问题,趁此机会总结下文本分类 ...
- [转] 用深度学习(CNN RNN Attention)解决大规模文本分类问题 - 综述和实践
转自知乎上看到的一篇很棒的文章:用深度学习(CNN RNN Attention)解决大规模文本分类问题 - 综述和实践 近来在同时做一个应用深度学习解决淘宝商品的类目预测问题的项目,恰好硕士毕业时论文 ...
- ApacheCN 深度学习译文集 2020.9
协议:CC BY-NC-SA 4.0 自豪地采用谷歌翻译 不要担心自己的形象,只关心如何实现目标.--<原则>,生活原则 2.3.c 在线阅读 ApacheCN 面试求职交流群 72418 ...
- Papers | 图像/视频增强 + 深度学习
目录 I. ARCNN 1. Motivation 2. Contribution 3. Artifacts Reduction Convolutional Neural Networks (ARCN ...
- 4.keras实现-->生成式深度学习之用变分自编码器VAE生成图像(mnist数据集和名人头像数据集)
变分自编码器(VAE,variatinal autoencoder) VS 生成式对抗网络(GAN,generative adversarial network) 两者不仅适用于图像,还可以 ...
随机推荐
- 初学Qt——tableview操作
先做简短记录改天有空再详细讲一些吧 使用QSqlQueryModel绑定了TableView,因为需要用到数据表中Id这一项,但又不想显示出来,找到方法是 在绑定之后对tableView 调用setC ...
- Object-C 银行卡,信用卡校验规则(Luhn算法)
最近的项目中涉及到绑定用户的银行卡,借记卡.经过查找银行卡的校验规是采用 Luhn算法进行验证. Luhn算法,也被称作“模10算法”.它是一种简单的校验公式,一般会被用于身份证号码,IMEI号码,美 ...
- 彻底理解使用JavaScript 将Json数据导出CSV文件
前言 将数据报表导出,是web数据报告展示常用的附带功能.通常这种功能都是用后端开发人员编写的.今天我们主要讲的是直接通过前端js将数据导出Excel的CSV格式的文件. 原理 首先在本地用Excel ...
- Serializable详解(1):代码验证Java序列化与反序列化
说明:本文为Serializable详解(1),最后两段内容在翻译上出现歧义(暂时未翻译),将在后续的Serializable(2)文中补充. 介绍:本文根据JDK英文文档翻译而成,本译文并非完全按照 ...
- 必备技能echarts
echart 设置图例图标形状 https://blog.csdn.net/qq_15390381/article/details/81736796legend: { data: ["总数& ...
- codeigniter框架的使用感受和注意事项
codeigniter是一个轻量级的php的web框架,今年2月22日,正式发布了4.0版本.简称CI框架 先使用了CI的3.15版,基本上是不用安装,把框架文件放到web目录下,让后通过简单的配置, ...
- C++ 函数模板/类模板
#include <iostream> #include <vector> using namespace std; template < class T > // ...
- 建议5:比较function语句和function表达式
在Javascript语言中,既有function语句,也有函数表达式,这是令人困惑的.因为它们看起来是相同的.一个function语句就是一个值为一个函数的var语句的简写形式. 下面语句: fun ...
- 数据库事务练习-Java(新手)
数据库事务: 一个数据库事务通常包含了一个序列的对数据库的读/写操作. 为数据库操作序列提供了一个从失败中恢复到正常状态的方法,同时提供了数据库即使在异常状态下仍能保持一致性的方法. p ...
- 洛古 P1312 Mayan游戏(dfs+剪枝)
题目链接 这道题和俄罗斯方块很像 很明显,我们可以看出这是一个dfs,但是,我们需要几条剪枝: 1.如果只剩下1个或2个同样颜色的方块,那么直接退出 2.相同的块不用交换 3.注意优先性,优先左边换右 ...