深度图像上的表面法线

Posted

技术标签:

【中文标题】深度图像上的表面法线【英文标题】:Surface normal on depth image 【发布时间】:2015-06-23 03:12:01 【问题描述】:

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

【问题讨论】:

【参考方案1】:

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

如果相机矩阵是 K,这通常是这样的:

    f  0  cx
K=  0  f  cy
    0  0   1

然后,获取一个像素坐标 (x,y),然后使用以下方法定义从相机原点穿过像素(在相机世界坐标空间中)的射线:

              x
P = inv(K) *  y
              1

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

如果你对附近的像素(比如左右)做同样的操作,你会得到以毫米为单位的 Pl 和 Pr 然后只需找到 (Pl-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 向量使用相同的角度。

【讨论】:

我可以知道如何在给定相机的内在参数的情况下获取像素之间的距离:fx: 365.40, fy: 365.40, cx: 260.93, cy: 205.60 吗? 在上面添加了更多详细信息。 感谢您提供详细信息。我用坐标 (273,163) 计算了上面圈出的像素的 P,得到了P = [0.0330 -0.1166 1]T。这是什么意思?上面的深度值是以毫米为单位的距离相机的距离。 向量乘以距离,所以Z值有距离。之后,X,Y 将在对象处以毫米为单位 根据您的方法,法线始终指向 Z 方向。这是正确的吗?

以上是关于深度图像上的表面法线的主要内容,如果未能解决你的问题,请参考以下文章

给定表面法线,找到 3D 平面的旋转

光照模型

延迟着色、法线贴图和指向远离光线的自阴影表面

深度图像的获取原理

Unity 基于法线和深度实现完美描边,可独立控制物体描边

RealSense 无红外图像,四个 SR300 上的深度图像损坏