Python 利用棋盘格进行相机标定
时间: 2024-02-03 15:03:10 浏览: 123
相机标定是计算机视觉中的一个重要问题,它可以用于确定相机的内部(例如焦距、主点)和外部(例如旋转和平移向量)参数。在相机标定中,需要用到棋盘格图像来进行标定。本文将介绍如何使用Python和OpenCV对相机进行标定,其中棋盘格用于提取相机中的特征。
1. 棋盘格图像的生成
首先,需要生成棋盘格图像。可以使用Python的OpenCV库来生成棋盘格图像。下面的代码用于生成一个8x6的棋盘格,每个格子大小为25mm。
```python
import cv2
import numpy as np
# 棋盘格大小
board_size = (8, 6)
square_size = 25 # mm
# 生成棋盘格图像
board = np.zeros((board_size[1]*square_size, board_size[0]*square_size, 3), dtype=np.uint8)
board[1::2, ::2] = 255
board[::2, 1::2] = 255
cv2.imwrite('chessboard.png', board)
```
2. 相机标定
接下来,需要使用OpenCV中的`calibrateCamera`函数对相机进行标定。该函数需要输入多张棋盘格图像和对应的角点坐标,然后输出相机的内部和外部参数。
```python
import cv2
import numpy as np
# 棋盘格大小
board_size = (8, 6)
square_size = 25 # mm
# 生成棋盘格图像
board = np.zeros((board_size[1]*square_size, board_size[0]*square_size, 3), dtype=np.uint8)
board[1::2, ::2] = 255
board[::2, 1::2] = 255
# 生成棋盘格角点坐标
obj_points = np.zeros((board_size[0]*board_size[1], 3), np.float32)
obj_points[:, :2] = np.mgrid[0:board_size[0], 0:board_size[1]].T.reshape(-1, 2) * square_size
obj_points_list = []
img_points_list = []
# 读取多张棋盘格图像并提取角点坐标
for i in range(1, 21):
img = cv2.imread('chessboard{}.png'.format(i))
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret, corners = cv2.findChessboardCorners(gray, board_size, None)
if ret:
obj_points_list.append(obj_points)
img_points_list.append(corners)
# 相机标定
ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(obj_points_list, img_points_list, gray.shape[::-1], None, None)
print(mtx) # 内部参数矩阵
print(dist) # 畸变系数
```
在上面的代码中,`findChessboardCorners`函数用于提取棋盘格的角点坐标,然后将这些坐标作为输入传递给`calibrateCamera`函数来进行相机标定。最终,该函数会输出相机的内部参数矩阵和畸变系数。
3. 畸变校正
在进行相机标定后,可以使用OpenCV中的`undistort`函数来进行畸变校正。该函数需要输入一张图像和相机的内部参数矩阵和畸变系数,然后输出畸变校正后的图像。
```python
import cv2
import numpy as np
# 棋盘格大小
board_size = (8, 6)
square_size = 25 # mm
# 生成棋盘格图像
board = np.zeros((board_size[1]*square_size, board_size[0]*square_size, 3), dtype=np.uint8)
board[1::2, ::2] = 255
board[::2, 1::2] = 255
# 生成棋盘格角点坐标
obj_points = np.zeros((board_size[0]*board_size[1], 3), np.float32)
obj_points[:, :2] = np.mgrid[0:board_size[0], 0:board_size[1]].T.reshape(-1, 2) * square_size
obj_points_list = []
img_points_list = []
# 读取多张棋盘格图像并提取角点坐标
for i in range(1, 21):
img = cv2.imread('chessboard{}.png'.format(i))
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret, corners = cv2.findChessboardCorners(gray, board_size, None)
if ret:
obj_points_list.append(obj_points)
img_points_list.append(corners)
# 相机标定
ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(obj_points_list, img_points_list, gray.shape[::-1], None, None)
# 畸变校正
img = cv2.imread('test.png')
img_undistorted = cv2.undistort(img, mtx, dist)
cv2.imshow('original image', img)
cv2.imshow('undistorted image', img_undistorted)
cv2.waitKey(0)
```
在上面的代码中,`undistort`函数用于进行畸变校正,然后将校正后的图像显示出来。
通过以上三个步骤,就可以使用Python和OpenCV对相机进行标定,并进行畸变校正。
阅读全文