opencv进行双目标定以及极线校正 python代码

opencv进行双目标定以及极线校正python代码

双目标定

参考博客 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)

效果图

校正前
左图
在这里插入图片描述
右图
在这里插入图片描述

在这里插入图片描述
校正后
在这里插入图片描述

根据提供的引用内容,Opencv双目标定是通过拍摄棋盘图像来完成的,而不是使用Opencv自带的标定图。使用自带的标定图进行标定是没有意义的,因为摄像头的摆放位置和别人的不一样,无法反映实际情况。 以下是Opencv圆点双目标定的步骤: 1. 准备棋盘格图像:使用相机拍摄一系列棋盘格图像,确保棋盘格在不同位置和角度下都能被摄像头完整地拍摄到。 2. 提取角点:使用Opencv的`findChessboardCorners()`函数来检测每张图像中的棋盘格角点。该函数会返回每个角点的像素坐标。 3. 标定相机:使用`calibrateCamera()`函数来标定相机。该函数会根据提供的棋盘格角点坐标和实际世界坐标,计算出相机的内参矩阵、畸变系数等参数。 4. 计算双目标定参数:使用`stereoCalibrate()`函数来计算双目摄像头的外参矩阵、基线长度等参数。该函数会使用左右相机的内参矩阵、畸变系数以及对应的棋盘格角点坐标。 5. 评估标定结果:使用`stereoRectify()`函数来评估标定结果,并计算出双目摄像头的校正映射矩阵。 6. 双目视差计算:使用`stereoSGBM()`函数或其他双目视差计算算法,根据校正映射矩阵和双目图像,计算出视差图像。 7. 三维重建:根据视差图像和双目摄像头的参数,可以进行三维重建,得到场景中物体的深度信息。 请注意,以上步骤仅为Opencv圆点双目标定的一种常见方法,具体实现可能会有所不同。建议参考Opencv的官方文档和示例代码进行更详细的了解和实践。
评论 84
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值