计算距离(视差)OpenCV
Posted
技术标签:
【中文标题】计算距离(视差)OpenCV【英文标题】:Calculate distance (disparity) OpenCV 【发布时间】:2013-06-10 08:44:25 【问题描述】:-- 更新 2--
如果您使用单个摄像头计算距离,以下文章非常有用(尽管它使用的是 Python 而不是 C++):Find distance from camera to object/marker using Python and OpenCV
最佳链接是Stereo Webcam Depth Detection。这个开源项目的实现真的很清晰。
以下是原始问题。
对于我的项目,我使用两个摄像头(立体视觉)来跟踪物体并计算距离。我用 OpenCV 的示例代码对它们进行了校准,并生成了一个视差图。
我已经实现了一种基于颜色跟踪对象的方法(这会生成一个阈值图像)。
我的问题:如何使用视差图/矩阵计算到跟踪的彩色对象的距离?
您可以在下面找到获取每个像素的 x、y 和 z 坐标的代码 sn-p。问题:Point.z 是以厘米、像素、毫米为单位的吗?
我可以用这个代码得到到被跟踪物体的距离吗?
提前谢谢你!
cvReprojectImageTo3D(disparity, Image3D, _Q);
vector<CvPoint3D32f> PointArray;
CvPoint3D32f Point;
for (int y = 0; y < Image3D->rows; y++)
float *data = (float *)(Image3D->data.ptr + y * Image3D->step);
for (int x = 0; x < Image3D->cols * 3; x = x + 3)
Point.x = data[x];
Point.y = data[x+1];
Point.z = data[x+2];
PointArray.push_back(Point);
//Depth > 10
if(Point.z > 10)
printf("%f %f %f", Point.x, Point.y, Point.z);
cvReleaseMat(&Image3D);
--更新 1--
例如,我生成了这个阈值图像(左侧摄像头)。我几乎拥有相同的正确相机。
除上述阈值图像外,应用程序还会生成视差图。如何在视差图中获取手部像素的 Z 坐标?
我其实是想获取手部像素的所有 Z 坐标来计算平均 Z 值(距离)(使用视差图)。
【问题讨论】:
【参考方案1】:查看此链接:OpenCV: How-to calculate distance between camera and object using image?、Finding distance from camera to object of known size、http://answers.opencv.org/question/5188/measure-distance-from-detected-object-using-opencv/ 如果它不能解决您的问题,请写下更多细节 - 为什么它不起作用,等等。
【讨论】:
见--更新--在第一篇文章中。 @cyriel 我们可以用两个相机视图预测一个点的深度吗?【参考方案2】:将视差(以像素或图像宽度百分比)转换为实际距离的数学已经很好地记录(并且不是很困难),但我也会在这里记录。
下面是给定视差图像(以像素为单位)和输入图像宽度为 2K(跨 2048 像素)图像的示例:
会聚距离由相机镜头之间的旋转决定。在本例中,它将是 5 米。收敛距离5(米)表示5米外物体的视差为0。
CD = 5 (meters)
收敛距离的倒数是:1 / CD
IZ = 1/5 = 0.2M
相机传感器的尺寸(以米为单位)
SS = 0.035 (meters) //35mm camera sensor
传感器上像素的宽度,以米为单位
PW = SS/image resolution = 0.035 / 2048(image width) = 0.00001708984
相机的焦距,以米为单位
FL = 0.07 //70mm lens
轴间距离:左镜片中心到右镜片中心的距离
IA = 0.0025 //2.5mm
相机装备的物理参数组合
A = FL * IA / PW
Camera Adjusted disparity:(仅对于左视图,右视图将使用正 [disparity value])
AD = 2 * (-[disparity value] / A)
从这里您可以使用以下公式计算实际距离:
realDistance = 1 / (IZ – AD)
此公式仅适用于“前束”相机系统,平行相机装备将使用稍微不同的公式来避免无穷大值,但我暂时将其保留在此。如果您需要并行的东西,请告诉我。
【讨论】:
你能反转这个计算吗,即用已知的相机参数拍摄深度图像并获得视差图? 是的,这是一个可逆方程。【参考方案3】:if len(puntos) == 2: x1, y1, w1, h1 = puntos[0] x2, y2, w2, h2 = puntos[1] if x1 < x2: distancia_pixeles = abs(x2 - (x1+w1)) distancia_cm = (distancia_pixeles*29.7)/720 cv2.putText(imagen_A4, ":.2f cm".format(distancia_cm), (x1+w1+distancia_pixeles//2, y1-30), 2, 0.8, (0,0,255), 1,
cv2.LINE_AA) cv2.line(imagen_A4,(x1+w1,y1-20),(x2, y1-20),(0, 0, 255),2) cv2.line(imagen_A4,(x1+w1,y1-30),(x1+w1, y1-10),(0, 0, 255),2) cv2.line(imagen_A4,(x2,y1-30),(x2, y1-10),(0, 0, 255),2) 别的: distancia_pixeles = abs(x1 - (x2+w2)) 距离厘米 = (距离像素*29.7)/720 cv2.putText(imagen_A4, ":.2f cm".format(distancia_cm), (x2+w2+distancia_pixeles//2, y2-30), 2, 0.8, (0,0,255), 1, cv2.LINE_AA) cv2.line(imagen_A4,(x2+w2,y2-20),(x1, y2-20),(0, 0, 255),2) cv2.line(imagen_A4,(x2+w2,y2-30),(x2+w2, y2-10),(0, 0, 255),2) cv2.line(imagen_A4,(x1,y2-30),(x1, y2-10),(0, 0, 255),2)
cv2.imshow('imagen_A4',imagen_A4) cv2.imshow('frame',frame) k = cv2.waitKey(1) & 0xFF if k == 27: break cap.release() cv2.destroyAllWindows()
我认为这是测量两个物体之间距离的好方法
【讨论】:
欢迎使用SO,请正确使用文本格式。以上是关于计算距离(视差)OpenCV的主要内容,如果未能解决你的问题,请参考以下文章