opencv - 光流与深度关系的本质

标签 opencv opticalflow structure-from-motion

假设静态场景,单个相机在小距离内精确地横向移动,有两个帧和一个后续计算的光流(我使用 opencv 的 calcOpticalFlowFarneback):

这里的散点是检测到的特征,用具有深度值的伪彩色绘制(红色是小深度,靠近相机,蓝色更远)。现在,我通过简单地反转光流幅度来获得这些深度值,例如 d = 1/flow。看起来有点直观,以运动视差的方式 - 物体越亮,它离观察者越近。所以有一个立方体,将正面边缘和一点侧面边缘暴露给相机。

但随后我尝试将这些特征点从相机平面投影到现实生活中的坐标,以制作一种俯 View map (其中 X = (x * d)/fY = d(其中 d 是深度,x 是像素坐标,f 是焦距,X 和 Y 是实际坐标)。这是我得到的:

嗯,在我看来并不立方体。看起来图片向右倾斜。我花了一些时间思考为什么,1/flow 似乎不是一个准确的深度度量。使用不同的值,比如说,如果我使用 1/power(flow, 1/3),我会得到更好的图片:

但是,当然,1/3 的幂只是我头脑中的一个神奇数字。问题是,总体上深度光流之间的关系是什么,我应该如何估计给定场景的光流?我们只是在这里考虑相机翻译。我偶然发现了一些论文,但还没有找到一个通用方程式。一些,比如 that one , 提出 1/flow 的变体,我想这不会起作用。

更新

让我有点困扰的是,简单的几何形状也将我指向 1/flow 答案。就像,光流(在我的例子中)与视差相同,对吧?然后使用 this formula我得到 d = Bf/(x2 - x1),其中 B 是两个相机位置之间的距离,f 是焦距,x2-x1 恰好是光流。焦距是一个常数,对于任何两个给定的帧,B 都是常数,因此 1/flow 再次乘以一个常数。我是否误解了什么是光流?

最佳答案

对于静态场景,将相机精确地侧向移动已知量,与立体相机设置完全相同。由此,如果您的系统经过校准,您确实可以估计深度。

请注意,这种意义上的校准范围很广。为了获得真正准确的深度,您最终需要在 openCV 中的常规校准内容之上提供一个比例参数,否则 3D 会出现单一的统一模糊(这最后一步通常称为 going仅从“欧几里得”到“公制”重建)。

广泛校准之外的另一件事是镜头畸变补偿。最重要的是,您可能想要强制您的相机像针孔相机一样工作(现实世界中的相机通常不会这样做)。

话虽如此,光流与度量深度图明显不同。如果你先正确地校准和纠正你的系统,那么光流仍然不等同于视差估计。如果您的系统得到纠正,则进行完整的光流估计(例如 Farnebäck)是没有意义的,因为此后问题被限制在图像的水平线上。进行完整的光流估计(给出 2 d.o.f)可能会在所述校正后引入更多误差。

所有这些东西的一个很好的引用是经典的“Multiple View Geometry in Computer Vision

关于opencv - 光流与深度关系的本质,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27464899/

相关文章:

matlab - 调整光流框架的大小

python - cv2.calcOpticalFlowPyrLK 添加新点

r - 使用 R 的 Motion 的简单正交结构——确定度量约束

qt - 具有 2 种渲染模式的 QGLWidget

c++ - OpenCV 使用像素指针构建图像

python - 降低图像分辨率

python - Spatstat:给定二维点列表,如何将它们连接到多边形中,并进一步使其成为研究区域?

opencv - 基于运动的映射帧

python - 双 View SFM 的相机姿势不正确

c++ - 无法在 OpenCV 中运行 SFM 模块的程序