OpenCV双目视觉测距

本文介绍了如何利用OpenCV进行双目视觉测距,包括相机校准、图像捕获、特征匹配、基础矩阵和本质矩阵计算,以及最终的距离测定。通过SIFT特征提取和匹配,计算视差图并转换为深度图,从而估算两个相机间的距离。
摘要由CSDN通过智能技术生成

步骤:

1.校准相机:首先,您需要通过拍摄一些校准图像来校准两个相机。校准图像可以是具有已知尺寸的平面或棋盘格图案。使用cv2.calibrateCamera()函数进行相机校准。

2.捕获图像:使用两个相机捕获两个不同视角的图像。您可以使用cv2.VideoCapture()函数在Python中从相机捕获视频。

3.特征匹配:使用特征匹配算法(例如SIFT,SURF或ORB)在两个图像之间找到共同的特征点。

4.计算基础矩阵:使用这些特征点计算基础矩阵,该矩阵可以用于估计两个相机之间的几何关系。使用cv2.findFundamentalMat()函数来计算基础矩阵。

5.计算本质矩阵:使用相机内部参数和基础矩阵计算本质矩阵。使用cv2.stereoCalibrate()函数来计算本质矩阵。

6.计算位移矩阵:使用cv2.stereoRectify()函数来计算视差校正和投影矩阵,并从中提取位移矩阵。

7.计算距离:最后,使用位移矩阵和三角剖分算法来计算两个摄像头之间的距离。

请注意,这只是OpenCV测量两个相机之间距离的一种方法,还有其他方法可以使用,具体取决于您的具体应用场景和需求。

以下是使用OpenCV进行双目视觉测距的基本代码示例:

import numpy as np
import cv2

# 捕获视频
cap1 = cv2.VideoCapture(0)
cap2 = cv2.VideoCapture(1)

# 设置相机参数
# 这里需要根据您的实际相机进行设置,例如分辨率和校准参数等
# 可以使用cv2.calibrateCamera()函数进行相机校准
K = np.array([[fx, 0, cx], [0, fy, cy], [0, 0, 1]])
D = np.array([k1, k2, p1, p2, k3])

# 定义SIFT特征提取器和FLANN特征匹配器
sift = cv2.xfeatures2d.SIFT_create()
flann_params = dict(algorithm=1, trees=5)
flann = cv2.FlannBasedMatcher(flann_params, {})

# 循环读取图像并计算距离
while True:
    # 读取图像
    ret1, img1 = cap1.read()
    ret2, img2 = cap2.read()
    if not ret1 or not ret2:
        break

    # 提取SIFT特征点并匹配
    kp1, des1 = sift.detectAndCompute(img1, None)
    kp2, des2 = sift.detectAndCompute(img2, None)
    matches = flann.knnMatch(des1, des2, k=2)

    # 选择最佳匹配
    good_matches = []
    for m, n in matches:
        if m.distance < 0.7 * n.distance:
            good_matches.append(m)

    # 计算基础矩阵
    points1 = np.float32([kp1[m.queryIdx].pt for m in good_matches]).reshape(-1, 1, 2)
    points2 = np.float32([kp2[m.trainIdx].pt for m in good_matches]).reshape(-1, 1, 2)
    F, mask = cv2.findFundamentalMat(points1, points2, cv2.FM_RANSAC)

    # 计算本质矩阵
    E = K.T.dot(F).dot(K)
    R1, R2, t = cv2.decomposeEssentialMat(E)

    # 计算位移矩阵
    R = np.eye(3)
    P1 = np.hstack((K, np.zeros((3, 1))))
    P2 = np.hstack((R2, t))
    _, _, _, _, _, R, t, _, _ = cv2.stereoRectify(K, D, K, D, img1.shape[:2], R, t, flags=cv2.CALIB_ZERO_DISPARITY)
    Q = np.float32([[1, 0, 0, -cx], [0, 1, 0, -cy], [0, 0, 0, f], [0, 0, -1/t[0], 0]])
    


    # 计算视差图
    gray1 = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)
    gray2 = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)
    stereo = cv2.StereoBM_create(numDisparities=16, blockSize=15)
    disparity = stereo.compute(gray1, gray2)

    # 将视差图转换为深度图
    depth = cv2.reprojectImageTo3D(disparity, Q)
    depth = depth[:, :, 2]

    # 计算距离
    # 这里假设您的摄像头距离物体的距离为1米
    # 如果您的实际情况不同,请根据您的实际情况进行修改
    scale_factor = 1.0 / depth.max()
    distance = depth * scale_factor

    # 显示图像和距离
    cv2.imshow('img1', img1)
    cv2.imshow('img2', img2)
    cv2.imshow('disparity', disparity / 16.)
    cv2.imshow('depth', depth)
    cv2.imshow('distance', distance)
    if cv2.waitKey(1) == 27:
        break

    # 释放资源
    cap1.release()
    cap2.release()
    cv2.destroyAllWindows()

  • 2
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
实现效果:http://v.youku.com/v_show/id_XMTU2Mzk0NjU3Ng==.html 如何在你的电脑上运行这个程序? 1,它需要cvblobslib这一个opencv的扩展库来实现检测物体与给物体画框的功能,具体安装信息请见: http://dsynflo.blogspot.com/2010/02/cvblobskib-with-opencv-installation.html,当你配置好cvblobslib之后,你可以用这一的程序进行测试:http://dl.dropbox.com/u/110310945/Blobs%20test.rar 2,视频中两个摄像头之间的距离是6cm,你可以根据你摄像头的型号,来选择合适的距离来达到最好的效果。 3,在进行测距之前,首先需要对摄像头进行标定,那么如何标定呢? 在stdafx.h中把"#define CALIBRATION 0"改成 “#define CALIBRATION 1”表示进行标定,标定之后,你就可以在工程目录下的"CalibFile" 文件夹中得到标定信息的文件。如果标定效果还不错,你就可以吧"#define CALIBRATION " 改成0,以后就不需要再标定,直接使用上一次的标定信息。你还需要把"#define ANALYSIS_MODE 1"这行代码放到stdafx.h中。 4,视频中使用的是10*7的棋牌格,共摄录40帧来计算摄像头的各种参数,如果你像使用其他棋盘格,可以在 "StereoFunctions.cpp"文件中修改相应参数。 5,如果你无法打开摄像头,可以在 "StereoGrabber.cpp"文件中修改代码“cvCaptureFromCAM(index)”中index的值。 6,About computing distance: it interpolates the relationship between depth-value and real-distance to third degree polynomial. So i used excel file "interpolation" for interpolation to find k1 to k4, you should find your own value of these parameters. 7,你可以通过调整控制窗口中各个参数的滑块,从而来得到更好的视差图。 8,在目录下的”distance“文件夹中,有计算距离信息的matlab代码。 9,如果你想了解基本的理论,可以看一下这个文档:http://scholar.lib.vt.edu/theses/available/etd-12232009-222118/unrestricted/Short_NJ_T_2009.pdf 视频中环境:vs2008,opencv2.1
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

laocui1

你的鼓励是我创作的最大动了

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值