【python】图片标定+双目测距+SGBM+yolov8目标检测(二、SGBM双目测距)

SGBM双目测距是一种用于计算双目立体视觉的深度图的算法。双目立体视觉是一种通过两个摄像头(称为左目和右目)获取的图像来模拟人类双眼视觉的技术。通过计算左右两个摄像头之间的视差(即对应像素之间的水平位移),可以推断出场景中物体的深度信息。

SGBM算法是基于全局优化的立体视觉算法,它能够在一定程度上考虑像素点的全局一致性。以下是SGBM算法的主要步骤:

  1. 预处理:首先,对左右两个摄像头的图像进行预处理,包括去噪、图像矫正等操作,以便提高立体匹配的准确性。

  2. 特征提取:从左右两个图像中提取特征点,常用的特征点提取算法包括SIFT、SURF等。这些特征点通常具有良好的重复性和唯一性,可以用于进行匹配。

  3. 匹配代价计算:对于每个特征点,在右图像中搜索其在左图像中的匹配点。通过计算匹配代价来评估左右图像中像素点的相似度。常用的匹配代价计算方法包括灰度差异、视差一致性等。

  4. 代价聚合:将匹配代价沿着视差方向进行聚合,以捕捉像素点的全局一致性。常用的聚合方法包括代价聚合和代价累积。

  5. 视差优化:采用全局优化方法对代价聚合结果进行平滑和优化,以获得更准确的视差图。常用的优化方法包括动态规划、最小割/最大流等。

  6. 深度估计:通过视差值计算得到深度图,将每个像素点的视差值转换为物体到相机的距离。常用的深度估计方法包括三角测量、深度映射等。

主代码

while True:
    # 开始计时
    t1 = time.time()
    # 是否读取到了帧,读取到了则为True
    ret, frame = capture.read()
    # 切割为左右两张图片
    frame1 = frame[0:720, 0:1280]
    frame2 = frame[0:720, 1280:2560]
    ############################################################################
    # 将BGR格式转换成灰度图片,用于畸变矫正
    imgL = cv2.cvtColor(frame1, cv2.COLOR_BGR2GRAY)
    imgR = cv2.cvtColor(frame2, cv2.COLOR_BGR2GRAY)

    # # 重映射,就是把一幅图像中某位置的像素放置到另一个图片指定位置的过程。
    # # 依据MATLAB测量数据重建无畸变图片,输入图片要求为灰度图
    img1_rectified = cv2.remap(imgL, left_map1, left_map2, cv2.INTER_LINEAR)
    img2_rectified = cv2.remap(imgR, right_map1, right_map2, cv2.INTER_LINEAR)

    # # 转换为opencv的BGR格式
    imageL = cv2.cvtColor(img1_rectified, cv2.COLOR_GRAY2BGR)
    imageR = cv2.cvtColor(img2_rectified, cv2.COLOR_GRAY2BGR)
    ############################################################################
    # ------------------------------------SGBM算法----------------------------------------------------------
    #   blockSize                   深度图成块,blocksize越低,其深度图就越零碎,0<blockSize<10
    #   img_channels                BGR图像的颜色通道,img_channels=3,不可更改
    #   numDisparities              SGBM感知的范围,越大生成的精度越好,速度越慢,需要被16整除,如numDisparities
    #                               取16、32、48、64等
    #   mode                        sgbm算法选择模式,以速度由快到慢为:STEREO_SGBM_MODE_SGBM_3WAY、
    #                               STEREO_SGBM_MODE_HH4、STEREO_SGBM_MODE_SGBM、STEREO_SGBM_MODE_HH。精度反之
    # ------------------------------------------------------------------------------------------------------
    num = cv2.getTrackbarPos("num", depthWinTitle)
    blockSize = cv2.getTrackbarPos("blockSize", depthWinTitle)
    img_channels = 3
    stereo = cv2.StereoSGBM_create(minDisparity=1,
                                   numDisparities=16 * num,
                                   blockSize=blockSize,
                                   P1=8 * img_channels * blockSize * blockSize,
                                   P2=32 * img_channels * blockSize * blockSize,
                                   disp12MaxDiff=-1,
                                   preFilterCap=1,
                                   uniquenessRatio=10,
                                   speckleWindowSize=100,
                                   speckleRange=100,
                                   mode=cv2.STEREO_SGBM_MODE_SGBM_3WAY)
    #-----------------------生成视差图-------------------------------------
    # 计算视差
    disparity = stereo.compute(imageL, imageR)

    # 归一化函数算法,生成深度图(灰度图)
    disp = cv2.normalize(disparity, disparity, alpha=0, beta=255, norm_type=cv2.NORM_MINMAX, dtype=cv2.CV_8U)
    # 生成深度图(颜色图)
    dis_color = disparity
    dis_color = cv2.normalize(dis_color, None, alpha=0, beta=255, norm_type=cv2.NORM_MINMAX, dtype=cv2.CV_8U)
    dis_color = cv2.applyColorMap(dis_color, 2)


    # 计算三维坐标数据值
    threeD = cv2.reprojectImageTo3D(disparity, Q, handleMissingValues=True)
    # 计算出的threeD,需要乘以16,才等于现实中的距离
    threeD = threeD * 16
    # 鼠标回调事件
    cv2.setMouseCallback("depth", onmouse_pick_points, threeD)

    #完成计时,计算帧率
    fps = (fps + (1. / (time.time() - t1))) / 2
    frame = cv2.putText(frame, "fps= %.2f" % (fps), (0, 40), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)

    res=stackImages(0.5,[[frame1,frame2],[dis_color,disp]])
    cv2.imshow("depth", dis_color)
    cv2.imshow("res", res)
    cv2.imshow(WIN_NAME, disp)  # 显示深度图的双目画面
    # 若键盘按下q则退出播放
    if cv2.waitKey(1) & 0xff == ord('q'):
        break

效果图:

视差图

深度图

点击深度图便可测量距离,(误差在1mm内)

  • 5
    点赞
  • 48
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值