双目标定
参考博客 OpenCV相机标定全过程
[OpenCV实战]38 基于OpenCV的相机标定
opencv立体标定函数 stereoCalibrate()
主要使用的函数
findChessboardCorners() #棋盘格角点检测
cornerSubPix() #亚像素检测
calibrateCamera() #单目标定 求解摄像机的内在参数和外在参数
stereoCalibrate() #双目标定 求解两个摄像头的内外参数矩阵,以及两个摄像头的位置关系R,T
代码
import cv2
import os
import numpy as np
leftpath = 'images/left'
rightpath = 'images/right'
CHECKERBOARD = (11,12) #棋盘格内角点数
square_size = (30,30) #棋盘格大小,单位mm
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001)
imgpoints_l = [] #存放左图像坐标系下角点位置
imgpoints_r = [] #存放左图像坐标系下角点位置
objpoints = [] #存放世界坐标系下角点位置
objp = np.zeros((1, CHECKERBOARD[0]*CHECKERBOARD[1], 3), np.float32)
objp[0,:,:2] = np.mgrid[0:CHECKERBOARD[0], 0:CHECKERBOARD[1]].T.reshape(-1, 2)
objp[0,:,0] *= square_size[0]
objp[0,:,1] *= square_size[1]
for ii in os.listdir(leftpath):
img_l = cv2.imread(os.path.join(leftpath,ii))
gray_l = cv2.cvtColor(img_l,cv2.COLOR_BGR2GRAY)
img_r = cv2.imread(os.path.join(rightpath,ii))
gray_r = cv2.cvtColor(img_r,cv2.COLOR_BGR2GRAY)
ret_l, corners_l = cv2.findChessboardCorners(gray_l, CHECKERBOARD) #检测棋盘格内角点
ret_r, corners_r = cv2.findChessboardCorners(gray_r, CHECKERBOARD)
if ret_l and ret_r:
objpoints.append(objp)
corners2_l = cv2.cornerSubPix(gray_l,corners_l,(11,11),(-1,-1),criteria)
imgpoints_l.append(corners2_l)
corners2_r = cv2.cornerSubPix(gray_r,corners_r,(11,11),(-1,-1),criteria)
imgpoints_r.append(corners2_r)
#img = cv2.drawChessboardCorners(img, CHECKERBOARD, corners2,ret)
#cv2.imwrite('./ChessboardCornersimg.jpg', img)
ret, mtx_l, dist_l, rvecs_l, tvecs_l = cv2.calibrateCamera(objpoints, imgpoints_l, gray_l.shape[::-1],None,None) #先分别做单目标定
ret, mtx_r, dist_r, rvecs_r, tvecs_r = cv2.calibrateCamera(objpoints, imgpoints_r, gray_r.shape[::-1],None,None)
retval, cameraMatrix1, distCoeffs1, cameraMatrix2, distCoeffs2, R, T, E, F = \
cv2.stereoCalibrate(objpoints, imgpoints_l, imgpoints_r, mtx_l, dist_l, mtx_r, dist_r, gray_l.shape[::-1]) #再做双目标定
print("stereoCalibrate : \n")
print("Camera matrix left : \n")
print(cameraMatrix1)
print("distCoeffs left : \n")
print(distCoeffs1)
print("cameraMatrix left : \n")
print(cameraMatrix2)
print("distCoeffs left : \n")
print(distCoeffs2)
print("R : \n")
print(R)
print("T : \n")
print(T)
print("E : \n")
print(E)
print("F : \n")
print(F)
将打印的结果保存到标定文件中即可
极线校正
参考博客 机器视觉学习笔记(8)——基于OpenCV的Bouguet立体校正
小白视角之Bouguet双目立体校正原理
主要使用的函数
stereoRectify() #计算旋转矩阵和投影矩阵
initUndistortRectifyMap() #计算校正查找映射表
remap() #重映射
代码
import cv2
import numpy as np
def cat2images(limg, rimg):
HEIGHT = limg.shape[0]
WIDTH = limg.shape[1]
imgcat = np.zeros((HEIGHT, WIDTH*2+20,3))
imgcat[:,:WIDTH,:] = limg
imgcat[:,-WIDTH:,:] = rimg
for i in range(int(HEIGHT / 32)):
imgcat[i*32,:,:] = 255
return imgcat
left_image = cv2.imread("images/left/268.jpg")
right_image = cv2.imread("images/right/268.jpg")
imgcat_source = cat2images(left_image,right_image)
HEIGHT = left_image.shape[0]
WIDTH = left_image.shape[1]
cv2.imwrite('imgcat_source.jpg', imgcat_source )
camera_matrix0 = np.array([[1.30991855e+03, 0.00000000e+00, 5.90463086e+02],
[0.00000000e+00, 1.31136722e+03, 3.33464608e+02],
[0.00000000e+00, 0.00000000e+00, 1.00000000e+00]]
) .reshape((3,3)) #即上文标定得到的 cameraMatrix1
distortion0 = np.array([-4.88890701e-01, 3.27964225e-01, -2.72130825e-04, 1.28030208e-03, -1.85964828e-01]) #即上文标定得到的 distCoeffs1
camera_matrix1 = np.array([[1.30057467e+03, 0.00000000e+00, 6.28445749e+02],
[0.00000000e+00, 1.30026325e+03, 3.90475091e+02],
[0.00000000e+00, 0.00000000e+00, 1.00000000e+00]]
) .reshape((3,3)) #即上文标定得到的 cameraMatrix2
distortion1 = np.array([-4.95938411e-01, 2.70207629e-01, 1.81014753e-04, -4.58891345e-04, 4.41327829e-01]) #即上文标定得到的 distCoeffs2
R = np.array([[ 0.99989348, 0.01340678, -0.00576869],
[-0.01338004, 0.99989967, 0.00465071],
[ 0.00583046, -0.00457303, 0.99997255]]
) #即上文标定得到的 R
T = np.array([-244.28272039, 3.84124178, 2.0963191]) #即上文标定得到的T
(R_l, R_r, P_l, P_r, Q, validPixROI1, validPixROI2) = \
cv2.stereoRectify(camera_matrix0, distortion0, camera_matrix1, distortion1, np.array([WIDTH,HEIGHT]), R, T) #计算旋转矩阵和投影矩阵
(map1, map2) = \
cv2.initUndistortRectifyMap(camera_matrix0, distortion0, R_l, P_l, np.array([WIDTH,HEIGHT]), cv2.CV_32FC1) #计算校正查找映射表
rect_left_image = cv2.remap(left_image, map1, map2, cv2.INTER_CUBIC) #重映射
#左右图需要分别计算校正查找映射表以及重映射
(map1, map2) = \
cv2.initUndistortRectifyMap(camera_matrix1, distortion1, R_r, P_r, np.array([WIDTH,HEIGHT]), cv2.CV_32FC1)
rect_right_image = cv2.remap(right_image, map1, map2, cv2.INTER_CUBIC)
imgcat_out = cat2images(rect_left_image,rect_right_image)
cv2.imwrite('imgcat_out.jpg', imgcat_out)
效果图
校正前
左图
右图
文章来源:https://www.toymoban.com/news/detail-508548.html
校正后
文章来源地址https://www.toymoban.com/news/detail-508548.html
到了这里,关于opencv进行双目标定以及极线校正 python代码的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!