三维重建【0-E】3D Gaussian Splatting:相机标定原理与步骤
前言
本节内容将详细阐述如何使用openCV库进行简单的相机标定,编程语言为Python。
相机标定代码讲解
1. 相关库导入
import numpy as np
import cv2
# glob模块的主要方法就是glob,该方法返回所有匹配的文件路径列表(list)
# 该方法需要一个参数用来制定匹配的路径字符串(字符串可以为绝对路径也可以为相对路径)
# 其返回文件名只包括当前目录里的文件名,不包括子文件夹里的文件
import glob
2. 棋盘格图像导入
# termination criteria 终止标准
# 前者表示迭代次数达到了最大次数时停止
# 后者表示角点位置变化的最小值已经达到最小时停止迭代
# 二者均使用cv::TermCriteria()构造函数进行指定
# 30表示30mm
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001)
# prepare object points, like (0, 0, 0), (1, 0, 0), (2, 0, 0), ......, (6, 5, 0)
objp = np.zeros((6*9, 3), np.float32)
objp[:, :2] = np.mgrid[0:9, 0:6].T.reshape(-1, 2)# Arrays to store object points and image points from all the images
objpoints = [] # 3d points in real world space
imgpoints = [] # 2d points in image plane
images = glob.glob('./chess/*.JPG') + glob.glob('./chess/*.jpg') + glob.glob('./chess/*.png')for fname in images:img = cv2.imread(fname)gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)# 依次可视化棋盘格图像
#     cv2.imshow('gray', gray)
#     while cv2.waitKey(100) != 27:   # loop if not get ESC
#         if cv2.getWindowProperty('gray', cv2.WND_PROP_VISIBLE) <= 0:
#             break
# cv2.destroyAllWindows()

3. 寻找角点
    # Find the chess board corners 寻找角点# 首先采用findChessboardCorners确认是否有角点存在ret, corners = cv2.findChessboardCorners(gray, (9, 6), None) # corners 返回角点的像素坐标系print('corners', corners)# If found, add object points, image points(after redfining them)# 如果找到角点,寻找角点更精确的位置,亚像素坐标if ret == True:objpoints.append(objp)  # 物点corners2 = cv2.cornerSubPix(gray, corners, (11, 11), (-1, -1), criteria)imgpoints.append(corners2)# Draw and display the cornersimg = cv2.drawChessboardCorners(img, (9, 6), corners2, ret)
#         cv2.imshow('img', img)
#         while cv2.waitKey(100) != 27: # loop if not get ESC
#             if cv2.getWindowProperty('img', cv2.WND_PROP_VISIBLE) <= 0:
#                 break
# cv2.destroyAllWindows()
示例图:

4. 获取内外参
# mrx 相机内参
# rvexs 旋转矩阵
# tceces 平移矩阵
ret, mrx, dist, rvecs, tceces = cv2.calibrateCamera(objpoints, imgpoints, (9, 6), None, None)
5. 利用获取到的参数反畸变
img = cv2.imread('./chess/1.jpg')
h, w = img.shape[:2]
newcameramtx, roi = cv2.getOptimalNewCameraMatrix(mrx, dist, (w, h), 1, (w, h))# 图像校正 反畸变
dst = cv2.undistort(img, mrx, dist, None, newcameramtx)
# crop the image
x, y, w, h = roi
dst = dst[y:y+h, x:x+w]
cv2.imwrite('calibresult.png', dst)
