forked from zbw/yiliao2026
73 lines
2.1 KiB
Python
73 lines
2.1 KiB
Python
import cv2
|
||
import numpy as np
|
||
import glob
|
||
|
||
# 图片储存的路径
|
||
img_path = "/home/sunrise/yiliao_ws/imagebag_outputs"
|
||
|
||
# 棋盘格参数
|
||
CHECKERBOARD = (8, 5) # 内角点数量(列×行)
|
||
square_size = 27 # 棋盘格方块实际尺寸(单位:毫米)
|
||
|
||
# 存储3D和2D点
|
||
objpoints = [] # 世界坐标系中的点
|
||
imgpoints = [] # 图像坐标系中的点
|
||
|
||
# 生成世界坐标系中的角点坐标(z=0)
|
||
objp = np.zeros((CHECKERBOARD[0]*CHECKERBOARD[1], 3), np.float32)
|
||
objp[:, :2] = np.mgrid[0:CHECKERBOARD[0], 0:CHECKERBOARD[1]].T.reshape(-1, 2) * square_size
|
||
|
||
|
||
# 读取所有棋盘格图片
|
||
images = glob.glob(f'{img_path}/*.png')
|
||
|
||
for fname in images:
|
||
img = cv2.imread(fname)
|
||
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
|
||
|
||
# 检测角点
|
||
ret, corners = cv2.findChessboardCorners(gray, CHECKERBOARD, None)
|
||
|
||
if ret:
|
||
objpoints.append(objp)
|
||
|
||
# 亚像素角点优化
|
||
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001)
|
||
corners2 = cv2.cornerSubPix(gray, corners, (11,11), (-1,-1), criteria)
|
||
imgpoints.append(corners2)
|
||
|
||
# 绘制角点(可选)
|
||
# cv2.drawChessboardCorners(img, CHECKERBOARD, corners2, ret)
|
||
# cv2.imshow('Detected Corners', img)
|
||
# cv2.waitKey(500)
|
||
|
||
# cv2.destroyAllWindows()
|
||
|
||
# 相机标定
|
||
ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(
|
||
objpoints, imgpoints, gray.shape[::-1], None, None
|
||
)
|
||
|
||
# 输出标定结果
|
||
print("相机内参矩阵:\n", mtx)
|
||
print("\n畸变系数:", dist.ravel())
|
||
|
||
# 计算重投影误差
|
||
mean_error = 0
|
||
for i in range(len(objpoints)):
|
||
imgpoints2, _ = cv2.projectPoints(objpoints[i], rvecs[i], tvecs[i], mtx, dist)
|
||
error = cv2.norm(imgpoints[i], imgpoints2, cv2.NORM_L2) / len(imgpoints2)
|
||
mean_error += error
|
||
print("\n平均重投影误差:", mean_error / len(objpoints))
|
||
|
||
# 保存参数
|
||
np.savez('cali.npz', mtx=mtx, dist=dist)
|
||
|
||
|
||
# 测试校正效果
|
||
img = cv2.imread(fname) # 替换为实际的图片路径
|
||
# ret, img = cap.read()
|
||
h, w = img.shape[:2]
|
||
newcameramtx, roi = cv2.getOptimalNewCameraMatrix(mtx, dist, (w,h), 1, (w,h))
|
||
|