从方向传感器数据旋转图像

har*_*rsh 6 android opencv 3d-reconstruction

我想从移动相机的2张图像中计算深度信息.使用Sensor.TYPE_ROTATION_VECTOR我有两个图像的四元数以及从Img1到Img2的相对四元数.

IMG1

在此输入图像描述

q1 = 0.7545 - 0.1137i - 0.2715j - 0.5865k
Run Code Online (Sandbox Code Playgroud)

IMG2

在此输入图像描述

q2 = 0.7706 - 0.2252i - 0.3511j - 0.4817k
Run Code Online (Sandbox Code Playgroud)

相对季铵盐是:

qr = -0.9850 + 0.0072i + 0.1329j - 0.1097k
Run Code Online (Sandbox Code Playgroud)

也就是说,相对旋转矩阵是,

|0.9406   -0.2142    -0.2635 |
|0.2180    0.9758    -0.0150 |
|0.2604   -0.0433     0.9645 |
Run Code Online (Sandbox Code Playgroud)

这是矩阵getPerspectiveTransform给出的吗?

当我使用这个3x3旋转矩阵时warpPerspective,除了左上角的东西外,我得到一张几乎空白的图像.(可能图像旋转的轴是错误的).

在此输入图像描述

我究竟做错了什么?

注意:2张图片之间也有一个小的翻译(抱歉图片不好)

编辑1:根据这个链接,对于我的第二代Moto G,我得到了一个内在的相机矩阵,

K = |-3570   0         1632 |
    |  0   3554.39   1218.65|
    |  0     0           1  |
Run Code Online (Sandbox Code Playgroud)

BCo*_*nic 2

如果我理解正确的话,您有两张从智能手机摄像头拍摄的图像,您知道(至少大约)其内在矩阵,以及拍摄两张图像的姿势之间的相对 3D 旋转。您还说两个图像之间有一个小的平移,这很好,因为否则您将无法计算深度。

不幸的是,您没有足够的信息来直接估计深度。基本上,估计两个图像的深度需要:

1. 找到两幅图像之间的点对应关系

根据您想要执行的操作,可以对图像中的所有点(即以密集方式)执行此操作,也可以仅对少数点(即以稀疏方式)执行此操作。当然,后者的计算成本较低,因此更适合智能手机。

  • 密集匹配需要校正图像,以使计算易于处理,但是如果在智能手机上执行,这可能需要很长时间。图像校正可以通过校准方法(需要知道图像两个位姿之间的旋转+平移、相机内参矩阵和相机的畸变系数)或非校准方法(需要知道两个图像和基本矩阵之间的稀疏点匹配,可以从匹配中估计)。

  • 稀疏匹配需要匹配两个图像之间的显着特征(例如 SURF 或 SIFT,或更有效的特征)。这样做的优点是比密集匹配更高效并且更准确。

2. 对对应点进行三角测量来估计深度

三角测量需要知道内在参数(相机矩阵和畸变系数)和外在参数(拍摄图像形成的姿势之间的相对旋转和平移)。


在你的情况下,假设你的相对旋转和内在相机矩阵足够准确(我对此表示怀疑),你仍然缺乏平移和畸变系数。

但是,您仍然可以应用立体三角测量的经典方法,这需要精确校准相机并估计完整的相对姿势(即旋转+平移)。

相机的校准将使您能够估计准确的本征矩阵和相关的失真系数。建议这样做,因为您的相机与其他手机中的相机不完全相同(即使是相同的手机型号)。例如,请参阅本教程,它展示了方法,尽管代码示例是用 C++ 编写的(对于 android 来说,等效代码必须存在)。

一旦准确估计了内在参数,估计完整相对姿态(即旋转和平移)的一种方法是计算基本矩阵(使用两个图像之间找到的特征匹配),然后使用相机矩阵推断基本矩阵,最后将本质矩阵分解为相对旋转和平移。请参阅此链接,它给出了从基本矩阵推断基本矩阵的公式,以及此链接,它解释了如何从基本矩阵计算旋转和平移。


另外,要回答与 相关的其他问题warpPerspective,您需要使用K.R.inv(K)K.inv(R).inv(K),具体取决于您要变形的图像。这是因为R是 3D 旋转,与像素坐标完全无关。