如何在3d图像中获得3d模型的变换矩阵

时间:2017-03-05 13:07:43

标签: opencv graphics computer-vision linear-algebra

给定对象的3D网格文件和包含该对象的图像,有哪些技术可以获取图像中3d对象的方向/姿势参数?

我尝试搜索某些技术,但大多数似乎需要对象的纹理信息或至少一些其他信息。有没有办法只使用图像和3d网格文件(wavefront .obj)来获取姿势参数?

这是可以预期的2D图像的示例。 enter image description here

1 个答案:

答案 0 :(得分:1)

  1. 相机的FOV

    相机的视野是绝对最低的,甚至可以从这开始知道(当你不知道它会如何影响场景时,如何确定如何放置物体)。基本上你需要从世界 GCS (全局坐标系)映射到Camera / Screen空间并返回的变换矩阵。如果你不知道我写的是什么,那么在你学习数学之前,你不应该尝试任何这些。

    对于未知相机,您可以根据视图中的标记或etalones(已知大小和形状)进行一些校准。但更好的是使用真实的相机值(如x,y方向的FOV角度,焦距等......)

    目标是创建将世界 GCS x,y,z)映射到屏幕 LCS x,y)的功能。

    欲了解更多信息,请阅读:

  2. 剪影匹配

    为了比较渲染图像和真实图像的相似性,您需要采取某种措施。由于你需要匹配几何,我认为轮廓匹配是一种方式(忽略纹理,阴影和东西)。

    首先,你需要获得轮廓。使用图像分割并创建对象的ROI掩码。对于渲染图像来说,这很容易,因为您可以使用单一颜色渲染对象,而不会直接将任何光照转换为ROI蒙版。

    所以你需要构建计算轮廓之间差异的函数。您可以使用任何类型的度量,但我认为您应该从非重叠区域像素计数开始(很容易计算)。

    diff pixels

    基本上,您只计算一个ROI(感兴趣区域)蒙版中出现的像素。

  3. 估算位置

    当您获得网格时,您就知道它的大小,因此将其放置在GCS中,因此渲染图像与真实图像具有非常接近的边界框。如果您没有FOV参数,则需要重新缩放和平移每个渲染图像,使其与图像边界框匹配(因此,您只获得方向而不是粗略对象的位置)。相机具有视角,因此离相机越远,放置物体的距离就越小。

  4. 适合方向

    渲染几个固定方向,覆盖所有方向,具有一些步骤8^3方向。对于每个计算轮廓的差异并选择具有最小差异的方向。

    然后调整其周围的方向角以最小化差异。如果您不知道优化或拟合如何工作,请参阅:

    注意太少的初始方向可能导致错误的定位或错过解决方案。太高的数量会很慢。

  5. 现在简而言之,这是一些基础知识。由于你的网格不是很简单,你可能需要调整这个,比如使用轮廓而不是轮廓,并使用轮廓之间的距离而不是非重叠的像素计数,这真的很难计算...你应该从更简单的网格开始,如骰子,硬币等......当把握所有这些变成更复杂的形状时......

    [Edit1]代数方法

    如果您知道图像中的某些点与已知的3D点(在您的网格中)相对应,那么您可以使用所使用的相机的FOV计算放置对象的变换矩阵...

    如果变换矩阵是M(OpenGL样式):

    M = xx,yx,zx,ox
        xy,yy,zy,oy
        xz,yz,zz,oz
         0, 0, 0, 1
    

    然后您的网格中的任何点(x,y,z)都会转换为全局世界(x',y',z'),如下所示:

    (x',y',z') = M * (x,y,z)
    

    像素位置(x'',y'')由相机FOV透视投影完成,如下所示:

    y''=FOVy*(z'+focus)*y' + ys2;
    x''=FOVx*(z'+focus)*x' + xs2;
    

    相机位于(0,0,-focus),投影平面位于z=0,观看方向为+z,因此对于任何焦距focus和屏幕分辨率(xs,ys ):

    xs2=xs*0.5; 
    ys2=ys*0.5;
    FOVx=xs2/focus;
    FOVy=ys2/focus;
    

    当把所有这些放在一起时,你得到这个:

    xi'' = ( xx*xi + yx*yi + zx*zi + ox ) * ( xz*xi + yz*yi + zz*zi + ox + focus ) * FOVx
    yi'' = ( xy*xi + yy*yi + zy*zi + oy ) * ( xz*xi + yz*yi + zz*zi + oy + focus ) * FOVy
    

    其中(xi,yi,zi)是网格局部坐标中的i-th已知点3D位置,(xi'',yi'')是对应的已知2D像素位置。所以未知数是M值:

    { xx,xy,xz,yx,yy,yx,zx,zy,zz,ox,oy,oz }
    

    因此,我们每个已知点得到2个方程,总共12个未知数。所以你需要知道6分。求解方程组并构造矩阵M

    你也可以利用M是一个统一的正交/正交矩阵,因此矢量

    X = (xx,xy,xz)
    Y = (yx,yy,yz)
    Z = (zx,zy,zz)
    

    彼此垂直如此:

    (X.Y) = (Y.Z) = (Z.X) = 0.0
    

    通过将这些点引入您的系统,可以减少所需点的数量。你也可以利用交叉产品,所以如果你知道2个向量,可以计算出它的数据

    Z = (X x Y)*scale
    

    因此,不需要3个变量,只需要单个标度(正交矩阵为1)。如果我假设正交矩阵那么:

    |X| = |Y| = |Z| = 1
    

    所以我们得到了6个额外的方程(3 x点,3个交叉),没有任何额外的未知数,所以3点确实已经足够了。