深度图像配准(Registration)原理
机器视觉中,3D相机产生的深度图像(depth image)通常需要配准(registration),以生成配准深度图像(registed depth image)。实际上配准的目的就是想让深度图和彩色图重合在一起,即是将深度图像的图像坐标系转换到彩色图像的图像坐标系下。下面我们来介绍其推导的过程。
1. 原理
为了描述方便,首先做些简单的假设。如下图所示,3D相机的左侧相机(left camera)为红外相机(即深度相机,ir camera),右侧相机(right camera)为彩色相机(color camera)。现在主流的3D相机都是这样的布局,如xtion,kiinect,orbbict。

已知彩色图像的像素表示为\((u_{R}, v_{R}, z_{R})^{\top}\),\(u_{R}, v_{R}, z_{R}\)分别表示彩色图像的横坐标,纵坐标和相机坐标系下的深度值(z方向上的值,非两点的距离);同样地,深度图像的像素为\((u_{L}, v_{L}, z_{L})^{\top}\),\(u_{L}, v_{L}, z_{L}\)分别表示深度图像的横坐标,纵坐标和相机坐标系下的深度值(z方向上的值,非两点的距离)。注意为了方便表示,本文中下标的R,L分别表示Right,Left的意思。那么深度图配准到彩色图的过程就是找到如下公式中的变换矩阵\(W^{'}\):
\(\begin{bmatrix}
u_{R}\\
v_{R}\\
1
\end{bmatrix}
=W^{'}
\begin{bmatrix}
u_{L}\\
v_{L}\\
1
\end{bmatrix}\)
实际上,变换矩阵\(W^{'}\)并不是真正要求解的矩阵,而是需要重新构造新的变换矩阵,以满足矩阵可逆性。构造过程如下:
a. 构造左侧相机的左侧相机坐标系到图像坐标系的变换
由相机原理(可参考相机标定(2)---摄像机标定原理),可知相机坐标到图像坐标的变换为:
\(z_{L}
\begin{bmatrix}
u_{L}\\
v_{L}\\
1
\end{bmatrix}=\begin{bmatrix}
f/dx & 0 & u_{L}^{0}&0\\
0 & f/dy & v_{L}^{0}&0\\
0 & 0& 1&0
\end{bmatrix}
\begin{bmatrix}
x_{L}\\
y_{L}\\
z_{L}\\
1
\end{bmatrix}
\)
以上变换过程等价于如下的表达
\(z_{L}
\begin{bmatrix}
u_{L}\\
v_{L}\\
1\\
1/z_{L}
\end{bmatrix}=
\underset{LR}{\underbrace{
\begin{bmatrix}
f/dx & 0 & u_{L}^{0}&0\\
0 & f/dy & v_{L}^{0}&0\\
0 & 0& 1&0 \\
0 & 0& 0&1
\end{bmatrix}
}}
\begin{bmatrix}
x_{L}\\
y_{L}\\
z_{L}\\
1
\end{bmatrix}\)
于是图像坐标系到相机坐标系的变换为:
\(\begin{bmatrix}
x_{L}\\
y_{L}\\
z_{L}\\
1
\end{bmatrix}=z_{L}*LR^{-1}*\begin{bmatrix}
u_{L}\\
v_{L}\\
1\\
1/z_{L}
\end{bmatrix}\) (1)
其中\(LR\)为双目相机标定的左侧相机内参矩阵,LR表示为Left Rotation之意
b. 构造右侧相机的右侧相机坐标系到图像坐标系的变换
根据a,同理地,左侧相机坐标系到图像坐标系的变换为:
\(z_{R}
\begin{bmatrix}
u_{R}\\
v_{R}\\
1\\
1/z_{R}
\end{bmatrix}=
\underset{RR}{\underbrace{
\begin{bmatrix}
f/dx & 0 & u_{R}^{0}&0\\
0 & f/dy & v_{R}^{0}&0\\
0 & 0& 1&0 \\
0 & 0& 0&1
\end{bmatrix}
}}
\begin{bmatrix}
x_{R}\\
y_{R}\\
z_{R}\\
1
\end{bmatrix}\)
于是图像坐标系到相机坐标系的变换为:
\(\begin{bmatrix}
x_{R}\\
y_{R}\\
z_{R}\\
1
\end{bmatrix}=z_{R}*RR^{-1}*\begin{bmatrix}
u_{R}\\
v_{R}\\
1\\
1/z_{R}
\end{bmatrix}\) (2)
其中\(RR\)为双目相机标定的右侧相机内参矩阵,RR表示为Right Rotation之意
c. 左侧相机坐标系到右侧相机坐标系变换
\(\begin{bmatrix}
x_{R}\\
y_{R}\\
z_{R}\\
1
\end{bmatrix}=M*\begin{bmatrix}
x_{L}\\
y_{L}\\
z_{L}\\
1
\end{bmatrix}\) (3)
其中M为4x4的变换矩阵,可理解为两个相机光心的外参矩阵,平移+旋转矩阵。此矩阵为上面标定得到的外参数矩阵。
d. 左侧图像坐标转换到右侧图像坐标
将(1)和(2)代入(3)得到
\(z_{R}*RR^{-1}*\begin{bmatrix}
u_{R}\\
v_{R}\\
1\\
1/z_{R}
\end{bmatrix}=
z_{L}*M*LR^{-1}*\begin{bmatrix}
u_{L}\\
v_{L}\\
1\\
1/z_{L}
\end{bmatrix}\)
两侧同时左乘RR矩阵得到
\(\begin{bmatrix}
u_{R}\\
v_{R}\\
1\\
1/z_{R}
\end{bmatrix}=
\frac{z_{L}}{z_{R}}*\underset{W}{\underbrace{RR*M*LR^{-1}}}*\begin{bmatrix}
u_{L}\\
v_{L}\\
1\\
1/z_{L}
\end{bmatrix}\)
由于\(z_{L}\approx z_{R}\),因此上述公式可以简化为:
\(\begin{bmatrix}
u_{R}\\
v_{R}\\
1\\
1/z_{R}
\end{bmatrix}=
W * \begin{bmatrix}
u_{L}\\
v_{L}\\
1\\
1/z_{L}
\end{bmatrix}\qquad \qquad \qquad \qquad (4)\)
W为计算得到的4x4变换矩阵,我们表示为
\(W = \begin{bmatrix}
r_{11} & r_{12}& r_{13}& r_{14}\\
r_{21} & r_{22}& r_{23}& r_{24}\\
r_{31} & r_{32}& r_{33}& r_{34}\\
r_{41} & r_{42}& r_{43}& r_{44}
\end{bmatrix}\)
由此将公式(4)展开,可得到左侧图像坐标转换到右侧图像坐标解析解,即
\(u_{R} = r_{11}*u_{L}+ r_{12}*v_{L}+ r_{13}+ r_{14}*\frac{1}{z_{L}}\qquad \qquad \qquad \qquad (5)\\
v_{R} = r_{21}*u_{L}+ r_{22}*v_{L}+ r_{23}+ r_{24}*\frac{1}{z_{L}}\qquad \qquad \qquad \qquad (6)\)
至此推导完毕,由此可见每个像素点的配准和原始图像的位置以及深度有着直接紧密的联系。ROS有一个包用于配准的计算,却异常的慢,按照以上的公式没有理由这么慢,看来还是知道原理实现才行。
注意:左侧右侧相机只是逻辑上的意义,即左右相机摆放的位置是可以任意的,这里描述的左侧相机可以实际摆在右侧(左侧),右侧相机可以摆在左侧(右侧)。因为外餐矩阵M可以表达出他们实际的关系。因此我们只需要知道右侧相机是彩色相机,左侧是深度相机即可。
2. 实现代码
配准代码实现如下
void Depth2RGB(cv::Mat &src, cv::Mat &dst,const float *W)
{
double z;
uint16_t u, v,d;
uint16_t u_rgb, v_rgb;
cv::Mat newdepth(dst.rows, dst.cols, CV_16UC1, cv::Scalar());
for (v = ; v < src.rows; v++)
{
for (u = ; u < src.cols; u++)
{
d = src.at<uint16_t>(v, u);
z = (double)d;
u_rgb = (uint16_t)((W[] * (double)u + W[] * (double)v + W[] + W[] / z));//参照上述公式(5)
v_rgb = (uint16_t)((W[] * (double)u + W[] * (double)v + W[] + W[] / z));//参照上述公式(6)
if (u_rgb < && u_rgb >= newdepth.cols && v_rgb < && v_rgb >= newdepth.rows)
{
uint16_t *val = (uint16_t *)newdepth.ptr<uchar>(v_rgb)+u_rgb; *val = d;
}
}
}
dst = newdepth;
}
3. 阅读资料
深度图像配准(Registration)原理的更多相关文章
- 【计算机视觉】图像配准(Image Registration)
(Source:https://blog.sicara.com/image-registration-sift-deep-learning-3c794d794b7a) 图像配准方法概述 图像配准广泛 ...
- 图像配准:从SIFT到深度学习
图像配准(Image Registration)是计算机视觉中的基本步骤.在本文中,我们首先介绍基于OpenCV的方法,然后介绍深度学习的方法. 什么是图像配准 图像配准就是找到一幅图像像素到另一 ...
- PCL深度图像(1)
目前深度图像的获取方法有激光雷达深度成像法,计算机立体视觉成像,坐标测量机法,莫尔条纹法,结构光法等等,针对深度图像的研究重点主要集中在以下几个方面,深度图像的分割技术 ,深度图像的边缘检测技术 ,基 ...
- RGB-D(深度图像) & 图像深度
RGB-D(深度图像) 深度图像 = 普通的RGB三通道彩色图像 + Depth Map 在3D计算机图形中,Depth Map(深度图)是包含与视点的场景对象的表面的距离有关的信息的图像或图 ...
- 深度学习Anchor Boxes原理与实战技术
深度学习Anchor Boxes原理与实战技术 目标检测算法通常对输入图像中的大量区域进行采样,判断这些区域是否包含感兴趣的目标,并调整这些区域的边缘,以便更准确地预测目标的地面真实边界框.不同的模型 ...
- Atitti 图像处理 图像混合 图像叠加 blend 原理与实现
Atitti 图像处理 图像混合 图像叠加 blend 原理与实现 混合模式 编辑 本词条缺少信息栏,补充相关内容使词条更完整,还能快速升级,赶紧来编辑吧! 混合模式是图像处理技术中的一个技术名词,不 ...
- Atitit.计算机图形图像图片处理原理与概论attilax总结
Atitit.计算机图形图像图片处理原理与概论attilax总结 计算机图形1 图像处理.分析与机器视觉(第3版)1 数字图像处理(第六版)2 图像处理基础(第2版)2 发展沿革 1963年,伊凡·苏 ...
- 非刚性图像配准 matlab简单示例 demons算法
2011-05-25 17:21 非刚性图像配准 matlab简单示例 demons算法, % Clean clc; clear all; close all; % Compile the mex f ...
- Opencv探索之路(二十):制作一个简易手动图像配准工具
近日在做基于sift特征点的图像配准时遇到匹配失败的情况,失败的原因在于两幅图像分辨率相差有点大,而且这两幅图是不同时间段的同一场景的图片,所以基于sift点的匹配已经找不到匹配点了.然后老师叫我尝试 ...
随机推荐
- /dev/i2c-*不见了
/********************************************************************** * /dev/i2c-*不见了 * 说明: * 能在他的 ...
- Python之路,第一篇:Python入门与基础
第一篇:Python入门与基础 1,什么是python? Python 是一个高层次的结合了解释性.编译性.互动性和面向对象的脚本语言. 2,python的特征: (1)易于学习,易于利用: (2)开 ...
- Unity3D UGUI下拉菜单/Dropdown组件用法、总结
Unity3D中UGUI实现下拉菜单 本文提供全流程,中文翻译. Chinar 坚持将简单的生活方式,带给世人!(拥有更好的阅读体验 -- 高分辨率用户请根据需求调整网页缩放比例) Chinar -- ...
- 20155219 2016-2017-2 《Java程序设计》第7周学习总结
20155219 2016-2017-2 <Java程序设计>第7周学习总结 教材学习内容总结 认识时间与日期 时间的度量 1.格林威治时间(GMT):通过观察太阳而得,因为地球公转轨道为 ...
- 用requestAnimationFrame优化Web动画
requestAnimationFrame是什么? 在浏览器动画程序中,我们通常使用一个定时器来循环每隔几毫秒移动目标物体一次,来让它动起来.如今有一个好消息,浏览器开发商们决定:“嗨,为什么我们不在 ...
- switch语句和switch-case与if-else之间的转换
switch语句格式:switch(变量){case 常量1:语句1;break;case 常量2:语句2;break;......default:语句;break;}特点:1.根据变量的值,选择相应 ...
- THML分组元素
学习要点: 1.分组元素总汇 2.分组元素解析 一.分组元素总汇 元素名称 说明 ...
- java 调用process
java调用process 有两种实现方法,一是使用Runtime类,二是使用Process类. 我在最近的项目里用的是Runtime类,接下来写下总结. 有图有真相(在网上学来一句话) packag ...
- String的intern()方法详解
https://blog.csdn.net/soonfly/article/details/70147205 :图解 https://blog.csdn.net/wjzhang5514/articl ...
- CF使用TGP下载后,分卷文件损坏的解决方法
首先从游戏的列表删除游戏(安装失败出现分卷文件损坏的游戏) 然后进入游戏重新,继续找到该游戏(安装失败的游戏) 点击下载游戏!不会重新下载的,之后下载一些失败的文件,不会花费多少时间,慢慢等待即可 之 ...