当前位置:   article > 正文

【python】图片标定+双目测距+SGBM+yolov8目标检测(二、SGBM双目测距)_立体匹配算法 yolov8

立体匹配算法 yolov8

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

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

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

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

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

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

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

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

主代码

  1. while True:
  2. # 开始计时
  3. t1 = time.time()
  4. # 是否读取到了帧,读取到了则为True
  5. ret, frame = capture.read()
  6. # 切割为左右两张图片
  7. frame1 = frame[0:720, 0:1280]
  8. frame2 = frame[0:720, 1280:2560]
  9. ############################################################################
  10. # 将BGR格式转换成灰度图片,用于畸变矫正
  11. imgL = cv2.cvtColor(frame1, cv2.COLOR_BGR2GRAY)
  12. imgR = cv2.cvtColor(frame2, cv2.COLOR_BGR2GRAY)
  13. # # 重映射,就是把一幅图像中某位置的像素放置到另一个图片指定位置的过程。
  14. # # 依据MATLAB测量数据重建无畸变图片,输入图片要求为灰度图
  15. img1_rectified = cv2.remap(imgL, left_map1, left_map2, cv2.INTER_LINEAR)
  16. img2_rectified = cv2.remap(imgR, right_map1, right_map2, cv2.INTER_LINEAR)
  17. # # 转换为opencv的BGR格式
  18. imageL = cv2.cvtColor(img1_rectified, cv2.COLOR_GRAY2BGR)
  19. imageR = cv2.cvtColor(img2_rectified, cv2.COLOR_GRAY2BGR)
  20. ############################################################################
  21. # ------------------------------------SGBM算法----------------------------------------------------------
  22. # blockSize 深度图成块,blocksize越低,其深度图就越零碎,0<blockSize<10
  23. # img_channels BGR图像的颜色通道,img_channels=3,不可更改
  24. # numDisparities SGBM感知的范围,越大生成的精度越好,速度越慢,需要被16整除,如numDisparities
  25. # 取16324864
  26. # mode sgbm算法选择模式,以速度由快到慢为:STEREO_SGBM_MODE_SGBM_3WAY、
  27. # STEREO_SGBM_MODE_HH4、STEREO_SGBM_MODE_SGBM、STEREO_SGBM_MODE_HH。精度反之
  28. # ------------------------------------------------------------------------------------------------------
  29. num = cv2.getTrackbarPos("num", depthWinTitle)
  30. blockSize = cv2.getTrackbarPos("blockSize", depthWinTitle)
  31. img_channels = 3
  32. stereo = cv2.StereoSGBM_create(minDisparity=1,
  33. numDisparities=16 * num,
  34. blockSize=blockSize,
  35. P1=8 * img_channels * blockSize * blockSize,
  36. P2=32 * img_channels * blockSize * blockSize,
  37. disp12MaxDiff=-1,
  38. preFilterCap=1,
  39. uniquenessRatio=10,
  40. speckleWindowSize=100,
  41. speckleRange=100,
  42. mode=cv2.STEREO_SGBM_MODE_SGBM_3WAY)
  43. #-----------------------生成视差图-------------------------------------
  44. # 计算视差
  45. disparity = stereo.compute(imageL, imageR)
  46. # 归一化函数算法,生成深度图(灰度图)
  47. disp = cv2.normalize(disparity, disparity, alpha=0, beta=255, norm_type=cv2.NORM_MINMAX, dtype=cv2.CV_8U)
  48. # 生成深度图(颜色图)
  49. dis_color = disparity
  50. dis_color = cv2.normalize(dis_color, None, alpha=0, beta=255, norm_type=cv2.NORM_MINMAX, dtype=cv2.CV_8U)
  51. dis_color = cv2.applyColorMap(dis_color, 2)
  52. # 计算三维坐标数据值
  53. threeD = cv2.reprojectImageTo3D(disparity, Q, handleMissingValues=True)
  54. # 计算出的threeD,需要乘以16,才等于现实中的距离
  55. threeD = threeD * 16
  56. # 鼠标回调事件
  57. cv2.setMouseCallback("depth", onmouse_pick_points, threeD)
  58. #完成计时,计算帧率
  59. fps = (fps + (1. / (time.time() - t1))) / 2
  60. frame = cv2.putText(frame, "fps= %.2f" % (fps), (0, 40), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)
  61. res=stackImages(0.5,[[frame1,frame2],[dis_color,disp]])
  62. cv2.imshow("depth", dis_color)
  63. cv2.imshow("res", res)
  64. cv2.imshow(WIN_NAME, disp) # 显示深度图的双目画面
  65. # 若键盘按下q则退出播放
  66. if cv2.waitKey(1) & 0xff == ord('q'):
  67. break

效果图:

视差图

深度图

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

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/AllinToyou/article/detail/510439
推荐阅读
相关标签
  

闽ICP备14008679号