点击上方“3D视觉工坊”,选择“星标”
干货第一时间送达
本文作者:白裳
https://zhuanlan.zhihu.com/p/74597564
本文已由原作者授权,不得擅自二次转载
单应性原理被广泛应用于图像配准,全景拼接,机器人定位SLAM,AR增强现实等领域。这篇文章从基础图像坐标知识系为起点,讲解图像变换与坐标系的关系,介绍单应性矩阵计算方法,并分析深度学习在单应性方向的进展。
本文为入门级文章,希望能够帮助读者快速了解相关内容。
目录 一 图像变换与平面坐标系的关系 二 平面坐标系与齐次坐标系 三 单应性变换 四 深度学习在单应性方向的进展-
旋转:
将图形围绕原点 逆时针方向旋转
角,用解析式表示为:
写成矩阵乘法形式:
-
平移:
但是现在遇到困难了,平移无法写成和上面旋转一样的矩阵乘法形式。所以引入齐次坐标 ,再写成矩阵形式:
其中 表示单位矩阵,而
表示平移向量。
那么就可以把把旋转和平移统一写在一个矩阵乘法公式中,即刚体变换:
而旋转矩阵 是正交矩阵(
)。
-
仿射变换
其中 可以是任意2x2矩阵(与
一定是正交矩阵不同)。
可以看到,相比刚体变换(旋转和平移),仿射变换除了改变目标位置,还改变目标的形状,但是会保持物体的“平直性”。
不同 和
矩阵对应的各种基本仿射变换:
-
投影变换(单应性变换)
简单说,投影变换彻底改变目标的形状。
总结一下:
-
刚体变换:平移+旋转,只改变物体位置,不改变物体形状
-
仿射变换:改变物体位置和形状,但是保持“平直性”
-
投影变换:彻底改变物体位置和形状
我们来看看完整投影变换矩阵各个参数的物理含义:
其中 代表仿射变换参数,
代表平移变换参数。
而 表示一种“变换后边缘交点“关系,如:
至于 则是一个与
相关的缩放因子。
一般情况下都会通过归一化使得 (原因见下文)。
问题来了,齐次坐标到底是什么?
齐次坐标系 与常见的三维空间坐标系
不同,只有两个自由度:
而 (其中
)对应坐标
和
的缩放尺度。当
时:
特别的当 时,对应无穷远:
-
单应性是什么?
此处不经证明的给出:同一个 [无镜头畸变] 的相机从不同位置拍摄 [同一平面物体] 的图像之间存在单应性,可以用 [投影变换] 表示 。
注意:单应性成立是有条件的!
简单说就是:
-
那么这个
单应性矩阵如何求解呢?
更一般的,每一组匹配点 有
由平面坐标与齐次坐标对应关系 ,上式可以表示为:
进一步变换为:
写成矩阵 形式:
也就是说一组匹配点 可以获得2组方程。
-
单应性矩阵8自由度
注意观察:单应性矩阵 与
其实完全一样(其中
),例如:
即点 无论经过
还是
映射,变化后都是
。
如果使 ,那么有:
所以单应性矩阵 虽然有9个未知数,但只有8个自由度。
在求 时一般添加约束
(也有用
约束),所以还有
共8个未知数。由于一组匹配点
对应2组方程,那么只需要
组不共线的匹配点即可求解
的唯一解。
OpenCV已经提供了相关API,代码和变换结果如下。
import cv2 import numpy as np im1 = cv2.imread('left.jpg') im2 = cv2.imread('right.jpg') src_points = np.array([[581, 297], [1053, 173], [1041, 895], [558, 827]]) dst_points = np.array([[571, 257], [963, 333], [965, 801], [557, 827]]) H, _ = cv2.findHomography(src_points, dst_points) h, w = im2.shape[:2] im2_warp = cv2.warpPerspective(im2, H, (w, h))
可以看到:
-
红框所在平面上内容基本对齐,但受到镜头畸变影响无法完全对齐;
-
平面外背景物体不符合单应性原理,偏离很大,完全无法对齐。
-
传统方法估计单应性矩阵
一般传统方法估计单应性变换矩阵,需要经过以下4个步骤:
-
提取每张图SIFT/SURF/FAST/ORB等特征点
-
提取每个特征点对应的描述子
-
通过匹配特征点描述子,找到两张图中匹配的特征点对(这里可能存在错误匹配)
-
使用RANSAC算法剔除错误匹配
-
求解方程组,计算Homograph单应性变换矩阵
示例代码如下:
#coding:utf-8 # This code only tested in OpenCV 3.4.2! import cv2 import numpy as np # 读取图片 im1 = cv2.imread('left.jpg') im2 = cv2.imread('right.jpg') # 计算SURF特征点和对应的描述子,kp存储特征点坐标,des存储对应描述子 surf = cv2.xfeatures2d.SURF_create() kp1, des1 = surf.detectAndCompute(im1, None) kp2, des2 = surf.detectAndCompute(im2, None) # 匹配特征点描述子 bf = cv2.BFMatcher() matches = bf.knnMatch(des1, des2, k=2) # 提取匹配较好的特征点 good = [] for m,n in matches: if m.distance < 0.7*n.distance: good.append(m) # 通过特征点坐标计算单应性矩阵H # (findHomography中使用了RANSAC算法剔初错误匹配) src_pts = np.float32([kp1[m.queryIdx].pt for m in good]).reshape(-1,1,2) dst_pts = np.float32([kp2[m.trainIdx].pt for m in good]).reshape(-1,1,2) H, mask = cv2.findHomography(src_pts, dst_pts, cv2.RANSAC, 5.0) matchesMask = mask.ravel().tolist() # 使用单应性矩阵计算变换结果并绘图 h, w, d = im1.shape pts = np.float32([[0,0], [0,h-1], [w-1,h-1], [w-1,0]]).reshape(-1,1,2) dst = cv2.perspectiveTransform(pts, H) img2 = cv2.polylines(im2, [np.int32(dst)], True, 255, 3, cv2.LINE_AA) draw_params = dict(matchColor = (0,255,0), # draw matches in green color singlePointColor = None, matchesMask = matchesMask, # draw only inliers flags = 2) im3 = cv2.drawMatches(im1, kp1, im2, kp2, good, None, **draw_params)
相关内容网上资料较多,这里不再重复造轮子。需要说明,一般情况计算出的匹配的特征点对 数量都有
,此时需要解超定方程组(类似于求解线性回归)。
-
HomographyNet(深度学习end2end估计单应性变换矩阵)
HomographyNet是发表在CVPR 2016的一种用深度学习计算单应性变换的网络,即输入两张图,直接输出单应性矩阵 。
在之前的分析中提到,只要有4组 匹配点即可计算
的唯一解。
相似的,只要有4组 也可以计算出
的唯一解:
其中 且
。
分析到这里,如果要计算 ,网络输出可以有以下2种情况:
-
Regression:网络直接输出
共8个数值
这样设置网络非常直观,使用L2损失训练,测试时直接输出8个float values,但是没有置信度confidence。即在使用网络时,无法知道当前输出单应性可靠程度。
2. Classification:网络输出 共8个值的量化值+confidence
这时将网络输出每个 和
量化成21个区间,用分类的方法判断落在哪一个区间。训练时使用Softmax损失。相比回归直接输出数值,量化必然会产生误差,但是能够输出分类置信度评判当前效果好坏,更便于实际应用。
另外HomographyNet训练时数据生成方式也非常有特色。
-
首先在随机
位置获取正方形图像块Patch A
-
然后对正方形4个点进行随机扰动,同时获得4组
-
再通过4组
计算
-
最后将图像通过
变换,在变换后图像
位置获取正方形图像块Patch B
那么图像块A和图像块B作为输入,4组 作为监督Label,进行训练
可以看到,在无法提取足够特征点的弱纹理区域,HomographyNet相比传统方法确实有一定的优势:
-
Spatial Transformer Networks(直接对CNN中的卷积特征进行变换)
其实早在2015年,就已经有对CNN中的特征进行变换的STN结构。
假设有特征层 ,经过卷积变为
,可以在他们之间插入STN结构。这样就可以直接学习到从特征
上的点
映射到特征
对应点
的仿射变换。
其中 对应STN中的仿射变换参数。STN直接在特征维度进行变换,且可以插入轻松任意两层卷积中。
-
DELF: DEep Local Features(深度学习提取特征点与描述子)
之前提到传统方法使用SIFT和Surf等特征点估计单应性。显然单应性最终估计准确度严重依赖于特征点和描述子性能。Google在ICCV 2017提出使用使用深度学习提取特征点。
tensorflow/models/delfgithub.com
考虑到篇幅,这里不再展开DELF,请有兴趣的读者自行了解相关内容。
本文仅做学术分享,如有侵权,请联系删文。
下载1
在「3D视觉工坊」公众号后台回复:3D视觉,即可下载 3D视觉相关资料干货,涉及相机标定、三维重建、立体视觉、SLAM、深度学习、点云后处理、多视图几何等方向。
下载2
在「3D视觉工坊」公众号后台回复:3D视觉github资源汇总,即可下载包括结构光、标定源码、缺陷检测源码、深度估计与深度补全源码、点云处理相关源码、立体匹配源码、单目、双目3D检测、基于点云的3D检测、6D姿态估计汇总等。
下载3
在「3D视觉工坊」公众号后台回复:相机标定,即可下载独家相机标定学习课件与视频网址;后台回复:立体匹配,即可下载独家立体匹配学习课件与视频网址。
重磅!3DCVer-学术论文写作投稿 交流群已成立
扫码添加小助手微信,可申请加入3D视觉工坊-学术论文写作与投稿 微信交流群,旨在交流顶会、顶刊、SCI、EI等写作与投稿事宜。
同时也可申请加入我们的细分方向交流群,目前主要有3D视觉、CV&深度学习、SLAM、三维重建、点云后处理、自动驾驶、CV入门、三维测量、VR/AR、3D人脸识别、医疗影像、缺陷检测、行人重识别、目标跟踪、视觉产品落地、视觉竞赛、车牌识别、硬件选型、学术交流、求职交流等微信群。
一定要备注:研究方向+学校/公司+昵称,例如:”3D视觉 + 上海交大 + 静静“。请按照格式备注,可快速被通过且邀请进群。原创投稿也请联系。
▲长按加微信群或投稿
▲长按关注公众号
3D视觉从入门到精通知识星球:针对3D视觉领域的知识点汇总、入门进阶学习路线、最新paper分享、疑问解答四个方面进行深耕,更有各类大厂的算法工程人员进行技术指导。与此同时,星球将联合知名企业发布3D视觉相关算法开发岗位以及项目对接信息,打造成集技术与就业为一体的铁杆粉丝聚集区,近2000星球成员为创造更好的AI世界共同进步,知识星球入口:
学习3D视觉核心技术,扫描查看介绍,3天内无条件退款
圈里有高质量教程资料、可答疑解惑、助你高效解决问题
觉得有用,麻烦给个赞和在看~