表面法线在深度图像上

时间:2015-06-23 03:12:02

标签: c++ opencv computer-vision

如何在不使用点云库(PCL)的情况下估计深度图像上的点 I(i,j)的表面法线(像素值,以mm为单位)?我已经浏览过(1)(2)(3),但我正在寻找使用C ++标准库或openCV对每个像素进行表面法线的简单估算。

enter image description here

1 个答案:

答案 0 :(得分:4)

您需要知道相机的内部参数,以便您也可以以相同的单位(mm)知道像素之间的距离。对于距相机一定距离(即中心像素的值),像素之间的距离显然是正确的

如果相机矩阵是K,通常类似于:

    f  0  cx
K=  0  f  cy
    0  0   1

然后,取一个像素坐标(x,y),然后通过像素(在相机世界坐标空间)中来自相机原点的光线定义:

              x
P = inv(K) *  y
              1

根据图像中的距离是Z轴上的投影,还是距离中心的欧氏距离,您需要对矢量P进行标准化,使得幅度是到所需像素的距离,或者确保P的z分量是这个距离。对于帧中心周围的像素,这应该接近相同。

如果对附近的像素(例如,左和右)执行相同的操作,则以mm为单位得到Pl和Pr 然后找到(P1-Pr)的范数,它是相邻像素之间距离的两倍,单位为mm。

然后,计算X和Y中的梯度

gx = (Pi+1,j - Pi-1,j) / (2*pixel_size)

然后,将两个渐变作为方向向量:

ax = atan(gx),  ay=atan(gy)


     | cos ax    0    sin ax |   |1|
dx = |    0      1       0   | * |0|
     | -sin ax   0    cos ax |   |0|

     |    1      0       0   |   |0|
dy = |    0   cos ay -sin ay | * |1|
     |    0   sin ay  cos ay |   |0|

N = cross(dx,dy);

您可能需要查看符号是否有意义,通过查看某个渐变并查看dx,dy指向预期方向。对于N向量,您可能需要使用负数为none / one / both角度和相同。