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

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

视差图及三维坐标

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

  1.  

python+openCV实现双目视差图及测距的更多相关文章

  1. OpenCV+OpenGL 双目立体视觉三维重建

    0.绪论 这篇文章主要为了研究双目立体视觉的最终目标--三维重建,系统的介绍了三维重建的整体步骤.双目立体视觉的整体流程包括:图像获取,摄像机标定,特征提取(稠密匹配中这一步可以省略),立体匹配,三维 ...

  2. 搭建基于python +opencv+Beautifulsoup+Neurolab机器学习平台

    搭建基于python +opencv+Beautifulsoup+Neurolab机器学习平台 By 子敬叔叔 最近在学习麦好的<机器学习实践指南案例应用解析第二版>,在安装学习环境的时候 ...

  3. Python+OpenCV图像处理(一)

    Python+OpenCV图像处理(一): 读取,写入和展示图片 调用摄像头拍照 调用摄像头录制视频 1. 读取.写入和展示图片 图像读入:cv2.imread() 使用函数cv2.imread() ...

  4. python opencv show图片,debug技巧

    debug的时候可以直接把图片画出来debug. imshow函数就是python opencv的展示图片的函数,第一个是你要起的图片名,第二个是图片本身.waitKey函数是用来展示图片多久的,默认 ...

  5. linux/ubuntu下最简单好用的python opencv安装教程 ( 解决 imshow, SIFT, SURF, CSRT使用问题)

    希望这篇文章能彻底帮你解决python opencv安装和使用中的常见问题. 懒人请直奔这一节, 一条命令安装 opencv 使用python-opencv常用的问题 在linux中使用python版 ...

  6. python+opencv实现车牌定位

    写在前面 HIT大三上学期视听觉信号处理课程中视觉部分的实验三,经过和学长们实验的对比发现每一级实验要求都不一样,因此这里标明了是2019年秋季学期的视觉实验三. 由于时间紧张,代码没有进行任何优化, ...

  7. python opencv识别蓝牌车牌号 之 取出车牌号 (1/3)

    概述 车牌识别是计算机视频图像识别技术在车辆牌照识别中的一种应用,通常来讲如果结合opencv进行车牌识别主要分为四个大步骤,分别为: 图像采集 车牌定位 分割车牌字符 字符识别 当然,如果结合了机器 ...

  8. Python+opencv打开修图的正确方式get

    先逼逼两句: 图像是 Web 应用中除文字外最普遍的媒体格式. 流行的 Web 静态图片有 JPEG.PNG.ICO.BMP 等.动态图片主要是 GIF 格式.为了节省图片传输流量,大型互联网公司还会 ...

  9. python抓取性感尤物美女图

    由于是只用标准库,装了python3运行本代码就能下载到多多的美女图... 写出代码前面部分的时候,我意识到自己的函数设计错了,强忍继续把代码写完. 测试发现速度一般,200K左右的下载速度,也没有很 ...

随机推荐

  1. 【JulyEdu-Python基础】第 3 课:容器以及容器的访问使用

    大纲 容器切片 list/tupledictset 切片 列表推导 生成器 迭代器 容器 list 列表 序列是Python中最基本的数据结构.序列中的每个元素都分配一个数字 - 它的位置,或索引,第 ...

  2. JAVA SQL注入漏洞挖掘

    java中sql注入主要发生在model层,黑盒测试sql注入的方法结合两点:1,异常注入后,界面有无明显的aql异常报出.2,查看数据库日志是否有脏数据注入. preparestatement方法是 ...

  3. SpringMVC必备知识点汇总

    1.参数接收 1.1 数组 1.2 文件上传 1.2.1 单个文件上传 1.2.2 多个文件上传 1.2.3 文件上传时,携带其他数据 2.参数校验 参数校验:https://www.cnblogs. ...

  4. String的非空判断:str!=""的为空判断出错问题

    if(str!=null && str!= ""){}这是错误的判断 String str1 = ""; String str2 = new S ...

  5. node.js中的url.parse方法使用说明

    node.js中的url.parse方法使用说明:https://blog.csdn.net/swimming_in_it_/article/details/77439975 版权声明:本文为博主原创 ...

  6. typescript中类型断言好理解也好用

    类型断言是个好用的玩意,虽然typescript很强大,但是有时还不如我们知道一个值的类型,导致在开发过程中总是报一些令人头痛的类型错误.使用断言,简单来说就是先做好一个假设,使得编译通过. 我一开始 ...

  7. Kinect开发-开发环境搭建

    0.安装Visual Studio.版本无所谓,但Kinect SDK for Windows只支持C/C#.接下来的开发语言将使用C#,用户界面框架使用WPF. 安装Kinect SDK for W ...

  8. 关闭mysql查询缓存query cache(用户测试性能)

    先对query cache进行查询 mysql> show global variables like '%cache%'; 查看query_cache_size.query_cache_typ ...

  9. dubbo看这一篇就够了

    为什么要有分布式 近年来微服务.分布式等名词非常的火,那么我们又为什么要进行系统拆分?如何进行拆分呢?阿里的dubbo作为分布式框架的代表,无疑是推动了整个行业技术的进步.以前中小型公司都是一个war ...

  10. 设置adb shell的环境变量

    1.设置adb系统变量 adb  D:\androidStudio\platform-tools;D:\androidStudio\tools 2.设置path系统变量 path D:\android ...