程序员最近都爱上了这个网站  程序员们快来瞅瞅吧!  it98k网:it98k.com

本站消息

站长简介/公众号

关注本站官方公众号:程序员总部,领取三大福利!
福利一:python和前端辅导
福利二:进程序员交流微信群,专属于程序员的圈子
福利三:领取全套零基础视频教程(python,java,前端,php)

  价值13000svip视频教程,python大神匠心打造,零基础python开发工程师视频教程全套,基础+进阶+项目实战,包含课件和源码

  出租广告位,需要合作请联系站长

+关注
已关注

分类  

暂无分类

标签  

暂无标签

日期归档  

2021-10(8)

2021-11(20)

Matlab双目相机标定

发布于2022-09-20 21:33     阅读(570)     评论(0)     点赞(10)     收藏(1)


1 概述

现在有许多双目相机在出厂时就已经标定好了,用户拿到手后可以直接使用,例如Intel Realsense系列。但是有些相机出厂的时候并没有完成标定工作,因而这个时候就需要我们自己来标定。由于笔者曾改装过一个双目相机,最远可以测至50m,因此有一些心得体会想给大家分享一下。本文主要介绍双目相机标定的整个过程,以及导出标定数据的方法。

相机标定主要分为手动标定和自动标定,手动标定比较繁琐,这里主要介绍基于matlab工具箱的自动标定方式来对双目相机进行标定。具体的相关标定细节也可以参照这篇博客:matlab双目标定(详细过程),里面有详细介绍。

2 Matlab工具箱标定

首先需要准备一张棋盘,如下图所示。对于标定不同测距范围相机所用的棋盘方格宽度会有所不同。对于短焦双目相机(测距范围在20m以内),棋盘中方格的宽度达到20mm即可;对于长焦双目相机(测距范围在40m左右),棋盘中方格的宽度需要尽量大,否则会影响标定的精度,一般至少达到60mm。

笔者在标定长焦相机时方格长宽选择60mm。然后运行项目文件中photo.py脚本文件对棋盘进行多角度拍摄,每按下一次s键,会保存一组左右镜头的照片,照片保存的路径参数可以由用户自由设定,参数名为folder。

  1. # !/usr/bin/python
  2. # -*- coding: utf-8 -*-
  3. import cv2
  4. import time
  5. AUTO = False # 自动拍照,或手动按s键拍照
  6. INTERVAL = 2 # 自动拍照间隔
  7. cap = cv2.VideoCapture(0 + cv2.CAP_DSHOW) # windows下开启摄像头是采用如下语句(微软特有):cv2.VideoCapture( camera_number + cv2.CAP_DSHOW)
  8. cap.set(cv2.CAP_PROP_FRAME_WIDTH, 2560) # 设置双目的宽度
  9. cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 720) # 设置双目的高度
  10. # 显示缓存数
  11. # print(cap.get(cv2.CAP_PROP_BUFFERSIZE))
  12. # 设置缓存区的大小
  13. # cap.set(cv2.CAP_PROP_BUFFERSIZE, 1)
  14. print(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
  15. print(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
  16. #设置FPS
  17. # print('setfps', cap.set(cv2.CAP_PROP_FPS, 25))
  18. # print(cap.get(cv2.CAP_PROP_FPS))
  19. counter = 0
  20. utc = time.time()
  21. folder = "images/" # 拍照文件目录
  22. def shot(pos, frame):
  23. global counter
  24. path = folder + pos + "_" + str(counter) + ".jpg"
  25. cv2.imwrite(path, frame)
  26. print("snapshot saved into: " + path)
  27. while True:
  28. ret, frame = cap.read()
  29. if not ret:
  30. print("camera is not connected!")
  31. break
  32. left_frame = frame[0:720, 0:1280]
  33. right_frame = frame[0:720, 1280:2560]
  34. cv2.imshow("left", left_frame)
  35. cv2.imshow("right", right_frame)
  36. now = time.time()
  37. if AUTO and now - utc >= INTERVAL:
  38. shot("left", left_frame)
  39. shot("right", right_frame)
  40. counter += 1
  41. utc = now
  42. key = cv2.waitKey(1)
  43. if key == ord("q"):
  44. break
  45. elif key & 0xFF == ord("s"):
  46. shot("left", left_frame)
  47. shot("right", right_frame)
  48. counter += 1
  49. cap.release()

注意尽量拍摄多组照片,这样可以提高标定效果,标定效果的好坏直接影响到测距的精度。对于短焦相机通常拍摄40组照片即可;长焦相机通常会需要更多组照片,笔者在标定长焦相机时拍摄了60组。

照片拍摄好后,进入matlab标定工具箱,如下图所示。注意:不要选择matlab2020b版本,笔者测试过该版本无法正常使用标定工具箱,可以使用matlab2020a版本。

 其中Stero Camera Cailbrator为双目标定工具箱,Camera Cailbrator为单目相机标定工具箱,因此这里选择Stero Camera Cailbrator工具箱。进入工具箱以后,选择Add Images。然后选择左右相机照片的路径,Size of checkerboard square为棋盘中每一个方格的长度,单位为毫米,一定要准确测量方格的长度,如下图所示。

点击确定以后,Radial Distortion Compute选择3 Coefficients和Tangential Distortion,然后点击Calibrate进行校准。不过校准前需要剔除一些原点不一致的点,保证所有照片的原点一致。校准过程中可以可以Reprojection Errors曲线,降低误差,如下图所示。 

3 导出标定数据 

标定好后将标定数据导入到工作空间,点击Export Camera Parameters即可。此时我们已经拿到标定数据了,为了避免手工获取数据时出错,笔者写了一个脚本可以直接获取标定数据,并保存到表格文件中,之后直接复制粘贴即可。

  1. rowName = cell(1,10);
  2. rowName{1,1} = '平移矩阵';
  3. rowName{1,2} = '旋转矩阵';
  4. rowName{1,3} = '相机1内参矩阵';
  5. rowName{1,4} = '相机1径向畸变';
  6. rowName{1,5} = '相机1切向畸变';
  7. rowName{1,6} = '相机2内参矩阵';
  8. rowName{1,7} = '相机2径向畸变';
  9. rowName{1,8} = '相机2切向畸变';
  10. rowName{1,9} = '相机1畸变向量';
  11. rowName{1,10} = '相机2畸变向量';
  12. xlswrite('out.xlsx',rowName(1,1),1,'A1');
  13. xlswrite('out.xlsx',rowName(1,2),1,'A2');
  14. xlswrite('out.xlsx',rowName(1,3),1,'A5');
  15. xlswrite('out.xlsx',rowName(1,4),1,'A8');
  16. xlswrite('out.xlsx',rowName(1,5),1,'A9');
  17. xlswrite('out.xlsx',rowName(1,6),1,'A10');
  18. xlswrite('out.xlsx',rowName(1,7),1,'A13');
  19. xlswrite('out.xlsx',rowName(1,8),1,'A14');
  20. xlswrite('out.xlsx',rowName(1,9),1,'A15');
  21. xlswrite('out.xlsx',rowName(1,10),1,'A16');
  22. xlswrite('out.xlsx',stereoParams.TranslationOfCamera2,1,'B1'); % 平移矩阵
  23. xlswrite('out.xlsx',stereoParams.RotationOfCamera2.',1,'B2'); % 旋转矩阵
  24. xlswrite('out.xlsx',stereoParams.CameraParameters1.IntrinsicMatrix.',1,'B5'); % 相机1内参矩阵
  25. xlswrite('out.xlsx',stereoParams.CameraParameters1.RadialDistortion,1,'B8'); % 相机1径向畸变(1,2,5)
  26. xlswrite('out.xlsx',stereoParams.CameraParameters1.TangentialDistortion,1,'B9'); % 相机1切向畸变(3,4)
  27. xlswrite('out.xlsx',stereoParams.CameraParameters2.IntrinsicMatrix.',1,'B10'); % 相机2内参矩阵
  28. xlswrite('out.xlsx',stereoParams.CameraParameters2.RadialDistortion,1,'B13'); % 相机2径向畸变(1,2,5)
  29. xlswrite('out.xlsx',stereoParams.CameraParameters2.TangentialDistortion,1,'B14'); % 相机2切向畸变(3,4)
  30. xlswrite('out.xlsx',[stereoParams.CameraParameters1.RadialDistortion(1:2), stereoParams.CameraParameters1.TangentialDistortion,...
  31. stereoParams.CameraParameters1.RadialDistortion(3)],1,'B15'); % 相机1畸变向量
  32. xlswrite('out.xlsx',[stereoParams.CameraParameters2.RadialDistortion(1:2), stereoParams.CameraParameters2.TangentialDistortion,...
  33. stereoParams.CameraParameters2.RadialDistortion(3)],1,'B16'); % 相机2畸变向量

标定数据文件保存的路径即为当前程序的路径,要想保存到其他路径直接修改脚本中的路径即可,导出的参数如下图所示。

将表格中的数据复制到双目相机配置文件中,其中相机1内参复制到left_camera_matrix中,相机1畸变复制到left_distortion中,相机2内参复制到right_camera_matrix中,相机2畸变复制到right_distortion中,旋转矩阵复制到R中,转移矩阵复制到T中,如下图所示。

至此,双目标定部分就已经完成。注意:标定时照片的尺寸与测距时照片的尺寸一定要保持一致 

原文链接:https://blog.csdn.net/weixin_46133643/article/details/123897977



所属网站分类: 技术文章 > 博客

作者:pinggo

链接:https://www.pythonheidong.com/blog/article/1760221/b1a3e511dbcc464fbacf/

来源:python黑洞网

任何形式的转载都请注明出处,如有侵权 一经发现 必将追究其法律责任

10 0
收藏该文
已收藏

评论内容:(最多支持255个字符)