内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用
这是一个例子深度图像。
我想要做的是,在得到每个点的表面法线之后,我会在这些点上创建切平面。然后用这些切平面来确定这个点是否来自平坦区域,方法是取相邻点到切平面的距离之和。
你要做的基本思想是取图像的梯度,然后对梯度进行变换,得到法向量。在MATLAB中获取梯度很容易:
[m, g] = imgradient(d);
给我们的震级m
)和方向(g
)图像在每一点上的梯度(相对于水平和度数)。例如,如果我们显示图像的梯度大小,它如下所示:
现在,更难的部分是利用我们所得到的关于梯度的信息,并将其转化为法向量。为了正确地实现这一点,我们需要知道如何从图像坐标转换到世界坐标。对于像你这样的CAD生成的图像,这些信息包含在用于生成图像的投影转换中。对于像Kinect这样的真实世界的图像,必须查找图像捕获设备的规范。
我们需要的关键信息是:每个像素在真实世界的坐标中有多宽?对于非正交投影(就像真实世界的图像捕获设备所使用的那样),我们可以通过假设每个像素都表示真实世界的固定角度内的光来近似这一点。如果我们知道这个角度p
(然后用弧度来测量它),那么一个像素所覆盖的真实世界的距离仅仅是sin(p) .* d
,或者大约p .* d
何地d
是图像在每个像素处的深度。
如果我们有这个信息,我们可以构造法向量的三个分量:
width = p .* d; gradx = m .* cos(g) * width; grady = m .* sin(g) * width; normx = - gradx; normy = - grady; normz = 1; len = sqrt(normx .^ 2 + normy .^ 2 + normz .^ 2); x = normx ./ len; y = normy ./ len; z = normz ./ len;