如果你已经看完了:一起做双目测距-USB_CAMERA检测人脸距离系列(1)–OpenCV打开双目摄像头,那么你的摄像头将可以像电脑摄像头那样读取到图片数据了,接下来我们关注了解你所拥有的这对摄像头,进行双目相机的标定。
wait。。不是又要推公式吧???
不不不,我原来也是看了很多双目标定的原理文章,然后参考了很多代码最后自己用python代码实现了双目相机标定,然后就发现自己写了一坨sh*t,这一节没有数学公式好吗!!!直接上大杀器–Matlab标定工具箱,比自己写的标定程序精确的多(真香)。
wait。。我记得标定好像要有棋盘格吧。。
没错,所以你需要这个:
有点随意,大家见谅。。
然后就是用相机给他左右拍个几十张,进行标定咯。
怎么拍??用OpenCV把视频流里面的帧截下来就好了,这里还是提供一个python写的双目拍照的程序
# imageCapture.py
import cv2
import imutils
import time
from imutils.video import VideoStream
print("Camera Sensor Warming Up in 2 seconds!")
New_VideoStream = VideoStream(src=1,resolution=(1280,480),usePiCamera=False,framerate=60).start()
time.sleep(2.0)
pic_idx = 0
print("type c to capture picture and q to quit!")
while True:
New_frame = New_VideoStream.read()
key = cv2.waitKey(1) & 0xFF
# quit
if key == ord("q"):
break
# capture frame
if key == ord('c'):
New_frame_left = New_frame[:,640:1280]
New_frame_right = New_frame[:,0:640]
cv2.imwrite("CalibIMG/left/left{}.jpg".format(pic_idx),New_frame_left)
cv2.imwrite("CalibIMG/right/right{}.jpg".format(pic_idx),New_frame_right)
pic_idx +=1
print("Please capture the {}th image!".format(pic_idx))
cv2.imshow("frame",New_frame)
cv2.destroyAllWindows()
New_VideoStream.stop()
这段代码在上一节开启双目相机的基础上增加了一个save image的功能,首先初始化图像的索引为0,每采一张图就增加index,c表示capture采图,q表示quit。
好了,既然我们采到了左右相机的十几张图片,如下:
接下来就是把他们丢进matlab炼丹炉练一下相机内参和R,T矩阵出来:
点击左上角的Add Images
设置好左右相机图片路径之后设置棋盘格真实的格距,我的是29mm
点击确定
Matlab会自动筛选出质量不好的图片对,其次还需要在展示出来的界面删除Matlab自己错误检测的图片对,比如说:
一般是XY轴检测错误或者原点出错,找到这样的图片对,删除即可,随后点击右上角的Calibrate:
底下的是表示图片奇异性的柱状图,如果你的图片数量够多建议多剔除一些不好的图片对,最后保留的图片对不少于10对:
点击右上角导出参数:
导出到工作区之后可以看到相机内参以及左右相机的R,T矩阵了,举个例子:
左相机的内参就在这里:
类似可以查看其他相机参数,比如说R,T矩阵:
好了到此为止,我们知道了两个相机的内参及畸变系数,以及两个相机相对的R,T
接下来我们把这些参数写入程序中备用:
每个双目相机的参数都不同,根据标定出来的参数填写该类:
# Calib.py
import numpy as np
class USB_Camera(object):
def __init__(self):
self.cam_matrix_left = np.array([[1271.71,-0.1385,376.5282],[0.,1270.87,258.1373],[0.,0.,1.]])
self.distortion_l = np.array([[-0.5688,5.9214,-0.00038018,-0.00052731,-61.7538]])
self.cam_matrix_right = np.array([[1269.2524,-2.098026,367.9874],[0.,1267.1973,246.2712],[0.,0.,1.]])
self.distortion_r = np.array([[-0.5176,2.4704,-0.0011,0.0012,-16.1715]])
self.R = np.array([[1.0000,-0.0088,-0.0043],[0.0088,0.9999,0.0072],[0.0042,-0.0072,1.0000]])
self.T = np.array([[-68.5321],[-0.5832],[-4.0933]])
self.focal_length = 6.00
self.baseline = np.abs(self.T[0])
这样我们就完成了相机的标定了,本系列的源代码请移步:
本系列全部代码,请移步 https://github.com/hitsz-zuoqi/Binoculars-tutorial
如果你感觉有用,star for me 是对我最大的鼓励~