如何用Python通过影像获得相机的内参矩阵和外参矩阵
时间: 2024-05-06 16:02:14 浏览: 85
要通过影像获得相机的内参矩阵和外参矩阵,需要进行相机标定。
相机标定的步骤如下:
1. 准备标定板:选择一张标定板,比如棋盘格,打印出来并贴在平面上。
2. 拍摄标定板:使用相机拍摄多张不同角度、不同位置的标定板照片。
3. 提取角点:使用OpenCV提取标定板图像中的角点坐标。
4. 计算相机内参:使用提取的角点坐标来计算相机的内参矩阵。
5. 计算相机外参:根据相机内参和拍摄到的标定板图像,使用OpenCV中的solvePnP函数求解相机的外参矩阵。
以下是Python代码示例:
```python
import cv2
import numpy as np
# 准备标定板
pattern_size = (9, 6) # 棋盘格大小
square_size = 1 # 格子尺寸
obj_points = np.zeros((np.prod(pattern_size), 3), dtype=np.float32)
obj_points[:, :2] = np.indices(pattern_size).T.reshape(-1, 2)
obj_points *= square_size
# 拍摄标定板并提取角点
image_points = []
obj_points_list = []
count = 0
cap = cv2.VideoCapture(0) # 打开相机
while True:
ret, frame = cap.read()
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
found, corners = cv2.findChessboardCorners(gray, pattern_size)
if found:
term_criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001)
cv2.cornerSubPix(gray, corners, (5, 5), (-1, -1), term_criteria)
image_points.append(corners.reshape(-1, 2))
obj_points_list.append(obj_points)
cv2.drawChessboardCorners(frame, pattern_size, corners, found)
count += 1
cv2.imshow('frame', frame)
if cv2.waitKey(1) & 0xFF == ord('q') or count == 10:
break
cap.release()
cv2.destroyAllWindows()
# 计算相机内参
ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(obj_points_list, image_points, gray.shape[::-1], None, None)
# 计算相机外参
rvec, tvec = rvecs[0], tvecs[0]
_, rmat = cv2.Rodrigues(rvec)
extrinsic_mtx = np.hstack((rmat, tvec))
print('相机内参矩阵:\n', mtx)
print('相机外参矩阵:\n', extrinsic_mtx)
```
在运行这段代码之前,需要保证相机连接到电脑并且已经安装好了OpenCV库。当运行完这段代码后,程序会打开相机,显示相机拍摄的画面,并且在标定板上检测到角点时会将其标记出来。当检测到足够多的角点时,程序会自动计算相机内参矩阵和外参矩阵,并将其输出到控制台中。
阅读全文