本文介绍了如何估计/确定深度图像点处的表面法线和切平面?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

限时删除!!

我有一个深度图像,是使用 3D CAD 数据生成的.此深度图像也可以从深度成像传感器(例如 Microsoft Kinect 或任何其他立体相机)中获取.所以基本上它是成像视图中可见点的深度图.换句话说,它是一个物体从某个角度分割出来的点云.

I have a depth image, that I've generated using 3D CAD data. This depth image can also be taken from a depth imaging sensor such as Microsoft Kinect or any other stereo camera. So basically it is a depth map of points visible in the imaging view. In other words it is segmented point cloud of an object from a certain view.

我想确定(估计也可以)每个点的表面法线,然后找到该点的切平面.

I would like to determine (estimating will also do) the surface normals of each point, then find tangent plane of that point.

我该怎么做?我做了一些研究并找到了一些技术,但并没有很好地理解它们(我无法实现它).更重要的是我如何在 Matlab 或 OpenCV 中做到这一点?我无法使用 surfnorm 命令来做到这一点.AFAIK 它需要一个表面,而我的深度图像中有部分表面.

How can I do this? I've did some research and found some techniques but didn't understand them well (I could not implement it). More importantly how can I do this in Matlab or OpenCV? I couldn't manage to do this using surfnorm command. AFAIK it needs a single surface, and I have partial surfaces in my depth image.

这是一个示例深度图像.

This is an example depth image.

我想要做的是,在获得每个点的表面法线后,我将在这些点处创建切线平面.然后使用这些切平面通过计算相邻点到切平面的距离之和来确定该点是否来自平坦区域.

What I want to do is, after I get the surface normal at each point I will create tangent planes at those points. Then use those tangent planes to decide if that point is coming from a flat region or not by taking the sum of distances of neighbor points to the tangent plane.

推荐答案

因此,您的问题中有一些未定义的内容,但我会尽力概述答案.

So there are a couple of things that are undefined in your question, but I'll do my best to outline an answer.

你要做的基本思想是取图像的梯度,然后对梯度应用变换以获得法向量.在 matlab 中取梯度很容易:

The basic idea for what you want to do is to take the gradient of the image, and then apply a transformation to the gradient to get the normal vectors. Taking the gradient in matlab is easy:

[m, g] = imgradient(d);

为我们提供了图像在每个点的梯度(相对于水平线,以度为单位)的幅度 (m) 和方向 (g).例如,如果我们为您的图像显示渐变的大小,它看起来像这样:

gives us the magnitude (m) and the direction (g) of the gradient (relative to the horizontal and measured in degrees) of the image at every point. For instance, if we display the magnitude of the gradient for your image it looks like this:

现在,更难的部分是获取有关梯度的信息并将其转换为法向量.为了正确地做到这一点,我们需要知道如何从图像坐标转换为世界坐标.对于像您这样的 CAD 生成的图像,此信息包含在用于制作图像的投影变换中.对于像您从 Kinect 获得的真实图像,您必须查找图像捕获设备的规格.

Now, the harder part is to take this information we have about the gradient and turn it into a normal vector. In order to do this properly we need to know how to transform from image coordinates to world coordinates. For a CAD-generated image like yours, this information is contained in the projection transformation used to make the image. For a real-world image like one you'd get from a Kinect, you would have to look up the spec for the image-capture device.

我们需要的关键信息是:现实世界坐标中每个像素的宽度是多少?对于非正交投影(如真实世界图像捕获设备使用的投影),我们可以通过假设每个像素代表真实世界固定角度内的光来近似这一点.如果我们知道这个角度(称为 p 并以弧度测量),那么像素覆盖的真实世界距离就是 sin(p) .* d,或大约 p .* d 其中 d 是图像在每个像素的深度.

The key piece of information we need is this: just how wide is each pixel in real-world coordinates? For non-orthonormal projections (like those used by real-world image capture devices) we can approximate this by assuming each pixel represents light within a fixed angle of the real world. If we know this angle (call it p and measure it in radians), then the real-world distance covered by a pixel is just sin(p) .* d, or approximately p .* d where d is the depth of the image at each pixel.

现在如果我们有了这些信息,我们就可以构造法向量的 3 个分量:

Now if we have this info, we can construct the 3 components of the normal vectors:

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;

这篇关于如何估计/确定深度图像点处的表面法线和切平面?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

1403页,肝出来的..

09-06 15:06