pas*_*bsb 13 camera opencv distance stereoscopy stereo-3d
有没有办法用立体相机计算到特定物体的距离?是否存在使用视差或角度来获得距离的等式或其他东西?
Ork*_*rka 36
注意:此处描述的所有内容都可以在相关校准和立体视觉章节的Learning OpenCV学习书中找到.您应该阅读这些章节以更好地理解以下步骤.
一种不要求您自己测量所有相机内在函数和外在函数的方法是使用openCVs校准函数.相机内在函数(镜头失真/歪斜等)可以用cv :: calibrateCamera计算,而extrinsics(左右相机之间的关系)可以用cv :: stereoCalibrate计算.这些函数在像素坐标中占据多个点,并尝试将它们映射到真实世界的对象坐标.CV有一个简洁的方法来获得这些点,打印出一个黑白棋盘并使用cv :: findChessboardCorners/cv :: cornerSubPix函数来提取它们.大约10-15个图像对的棋盘应该做.
校准函数计算的矩阵可以保存到光盘中,因此您不必在每次启动应用程序时重复此过程.你可以在这里获得一些整洁的矩阵,允许你创建一个整流图(cv :: stereoRectify/cv :: initUndistortRectifyMap),以后可以使用cv :: remap将其应用于你的图像.你还得到一个称为Q的整齐矩阵,它是一个差异到深度的矩阵.
纠正图像的原因是,一旦完成一对图像的处理(假设校准正确),一个图像中的每个像素/对象都可以在另一个图像的同一行上找到.
根据您在图像中寻找的功能类型,您可以通过以下几种方式进行操作.一种方法是使用CV立体声对应函数,例如立体块匹配或半全局块匹配.这将为您提供整个图像的视差图,可以使用Q矩阵(cv :: reprojectImageTo3D)将其转换为3D点.
这种情况的缺点是,除非图像中有很多纹理信息,否则CV在构建密集视差图方面并不是非常擅长(如果找不到给定像素的正确差异,您将获得间隙) ,所以另一种方法是找到你想要匹配的点.假设您在左侧图像中找到x = 40,y = 110的特征/对象,在右图像中找到x = 22(因为图像已被纠正,它们应具有相同的y值).差异计算为d = 40-22 = 18.
在我们的例子中构造一个cv :: Point3f(x,y,d)(40,110,18).以相同的方式查找其他有趣的点,然后将所有点发送到cv :: perspectiveTransform(使用Q矩阵作为变换矩阵,本质上此函数是cv :: reprojectImageTo3D但是对于稀疏视差图)并且输出将是点XYZ坐标系,左侧摄像头位于中心.
我还在努力,所以我不会发布完整的源代码.但我会给你一个概念性的解决方案.
您将需要以下数据作为输入(对于两个摄像头):
您可以自己测量最后一个,方法是将相机放在一张纸上并绘制两条线并测量这些线之间的角度.
摄像机不必以任何方式对齐,您只需要能够在两个摄像机中看到您的对象.
现在计算从每个相机到您的对象的矢量.你有来自每个相机的物体的(X,Y)像素坐标,你需要计算一个矢量(X,Y,Z).请注意,在简单的情况下,在相机中间可以看到对象,解决方案就是(camera.PointOfInterest - camera.Position).
一旦你有两个向量指向你的目标,这些向量定义的线应该在理想世界的一个点上交叉.在现实世界中,他们不会因为测量误差小和相机分辨率有限.因此,请使用以下链接计算两条线之间的距离矢量.
在该链接中:P0是您的第一个凸轮位置,Q0是您的第二个凸轮位置,u和v是从摄像机位置开始并指向目标的矢量.
你对实际距离不感兴趣,他们想要计算.你需要向量Wc - 我们可以假设对象在Wc的中间.在3D空间中拥有物体的位置后,您也可以获得任何距离.
我将很快发布完整的源代码.
| 归档时间: |
|
| 查看次数: |
26679 次 |
| 最近记录: |