python+openCV实现双目视差图及测距

举报
风吹稻花香 发表于 2022/05/23 22:16:11 2022/05/23
【摘要】 测距公式:  这篇博文也比较详细: 使用OpenCV/python进行双目测距 - 走看看 通过matlab标定得到相机参数放到stereoconfig.py import numpy as npimport cv2 #双目相机参数class stereoCameral(object): def __...

测距公式: 

这篇博文也比较详细:

使用OpenCV/python进行双目测距 - 走看看

通过matlab标定得到相机参数放到stereoconfig.py


  
  1. import numpy as np
  2. import cv2
  3. #双目相机参数
  4. class stereoCameral(object):
  5. def __init__(self):
  6. #左相机内参数
  7. self.cam_matrix_left = np.array([[249.82379, 0., 156.38459], [0., 249.07678, 122.46872], [0., 0., 1.]])
  8. #右相机内参数
  9. self.cam_matrix_right = np.array([[242.77875, 0., 153.22330], [0., 242.27426, 117.63536], [0., 0., 1.]])
  10. #左右相机畸变系数:[k1, k2, p1, p2, k3]
  11. self.distortion_l = np.array([[-0.02712, -0.03795, -0.00409, 0.00526, 0.00000]])
  12. self.distortion_r = np.array([[-0.03348, 0.08901, -0.00327, 0.00330, 0.00000]])
  13. #旋转矩阵
  14. om = np.array([-0.00320, -0.00163, -0.00069])
  15. self.R = cv2.Rodrigues(om)[0] # 使用Rodrigues变换将om变换为R
  16. #平移矩阵
  17. self.T = np.array([-90.24602, 3.17981, -19.44558])

视差图及三维坐标


  
  1. import cv2
  2. import numpy as np
  3. import stereoconfig
  4. def getRectifyTransform(height, width, config):
  5. #读取矩阵参数
  6. left_K = config.cam_matrix_left
  7. right_K = config.cam_matrix_right
  8. left_distortion = config.distortion_l
  9. right_distortion = config.distortion_r
  10. R = config.R
  11. T = config.T
  12. #计算校正变换
  13. if type(height) != "int" or type(width) != "int":
  14. height = int(height)
  15. width = int(width)
  16. R1, R2, P1, P2, Q, roi1, roi2 = cv2.stereoRectify(left_K, left_distortion, right_K, right_distortion,
  17. (width, height), R, T, alpha=0)
  18. map1x, map1y = cv2.initUndistortRectifyMap(left_K, left_distortion, R1, P1, (width, height), cv2.CV_32FC1)
  19. map2x, map2y = cv2.initUndistortRectifyMap(right_K, right_distortion, R2, P2, (width, height), cv2.CV_32FC1)
  20. return map1x, map1y, map2x, map2y, Q
  21. # 畸变校正和立体校正
  22. def rectifyImage(image1, image2, map1x, map1y, map2x, map2y):
  23. rectifyed_img1 = cv2.remap(image1, map1x, map1y, cv2.INTER_AREA)
  24. rectifyed_img2 = cv2.remap(image2, map2x, map2y, cv2.INTER_AREA)
  25. return rectifyed_img1, rectifyed_img2
  26. #视差计算
  27. def sgbm(imgL, imgR):
  28. #SGBM参数设置
  29. blockSize = 8
  30. img_channels = 3
  31. stereo = cv2.StereoSGBM_create(minDisparity = 1,
  32. numDisparities = 64,
  33. blockSize = blockSize,
  34. P1 = 8 * img_channels * blockSize * blockSize,
  35. P2 = 32 * img_channels * blockSize * blockSize,
  36. disp12MaxDiff = -1,
  37. preFilterCap = 1,
  38. uniquenessRatio = 10,
  39. speckleWindowSize = 100,
  40. speckleRange = 100,
  41. mode = cv2.STEREO_SGBM_MODE_HH)
  42. # 计算视差图
  43. disp = stereo.compute(imgL, imgR)
  44. disp = np.divide(disp.astype(np.float32), 16.)#除以16得到真实视差图
  45. return disp
  46. #计算三维坐标,并删除错误点
  47. def threeD(disp, Q):
  48. # 计算像素点的3D坐标(左相机坐标系下)
  49. points_3d = cv2.reprojectImageTo3D(disp, Q)
  50. points_3d = points_3d.reshape(points_3d.shape[0] * points_3d.shape[1], 3)
  51. X = points_3d[:, 0]
  52. Y = points_3d[:, 1]
  53. Z = points_3d[:, 2]
  54. #选择并删除错误的点
  55. remove_idx1 = np.where(Z <= 0)
  56. remove_idx2 = np.where(Z > 15000)
  57. remove_idx3 = np.where(X > 10000)
  58. remove_idx4 = np.where(X < -10000)
  59. remove_idx5 = np.where(Y > 10000)
  60. remove_idx6 = np.where(Y < -10000)
  61. remove_idx = np.hstack(
  62. (remove_idx1[0], remove_idx2[0], remove_idx3[0], remove_idx4[0], remove_idx5[0], remove_idx6[0]))
  63. points_3d = np.delete(points_3d, remove_idx, 0)
  64. #计算目标点(这里我选择的是目标区域的中位数,可根据实际情况选取)
  65. if points_3d.any():
  66. x = np.median(points_3d[:, 0])
  67. y = np.median(points_3d[:, 1])
  68. z = np.median(points_3d[:, 2])
  69. targetPoint = [x, y, z]
  70. else:
  71. targetPoint = [0, 0, -1]#无法识别目标区域
  72. return targetPoint
  73. imgL = cv2.imread("_left.jpg")
  74. imgR = cv2.imread("_right.jpg")
  75. height, width = imgL.shape[0:2]
  76. # 读取相机内参和外参
  77. config = stereoconfig.stereoCameral()
  78. map1x, map1y, map2x, map2y, Q = getRectifyTransform(height, width, config)
  79. iml_rectified, imr_rectified = rectifyImage(imgL, imgR, map1x, map1y, map2x, map2y)
  80. disp = sgbm(iml_rectified, imr_rectified)
  81. cv2.imshow("disp", disp)
  82. target_point = threeD(disp, Q)#计算目标点的3D坐标(左相机坐标系下)
  83. print(target_point)

结果:

文章来源: blog.csdn.net,作者:AI视觉网奇,版权归原作者所有,如需转载,请联系作者。

原文链接:blog.csdn.net/jacke121/article/details/124928816

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。