下面是详细讲解“OpenCV实现相机标定板”的完整攻略:
准备工作
在使用OpenCV实现相机标定板前,需要准备以下工作:
相机标定
检测标定板特征点
使用OpenCV中的findChessboardCorners()
函数可以检测标定板上的特征点,并将其保存到变量imagePoints
中,需要注意的是,findChessboardCorners()
函数只适用于黑白相间的正方形标定板。
以下是示例代码:
import cv2
img = cv2.imread("image.jpg")
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 设置标定板尺寸
board_size = (6, 9)
# 检测标定板的角点
ret, corners = cv2.findChessboardCorners(gray, board_size, None)
if ret:
# 将检测到的角点保存到数组中
imagePoints.append(corners)
标定参数计算
接下来使用cv2.calibrateCamera()
函数计算相机内参、畸变系数等标定参数,并将其保存到相应的变量中。
import cv2
import numpy as np
# 标定板尺寸
board_size = (6, 9)
# 物体坐标点
objp = np.zeros((board_size[0]*board_size[1], 3), np.float32)
objp[:,:2] = np.mgrid[0:board_size[0],0:board_size[1]].T.reshape(-1,2)
# 将物体坐标点按标定板角点数组imagePoints的维度复制
objpoints = []
for i in range(len(imagePoints)):
objpoints.append(objp)
# 计算相机标定参数
ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(objpoints, imagePoints, gray.shape[::-1], None, None)
# 保存标定结果
np.savetxt("cam_mtx.txt", mtx)
np.savetxt("cam_dist.txt", dist)
验证标定结果
为了验证标定结果,可以使用cv2.undistort()
函数对标定板图片进行畸变矫正,如果标定结果准确,则标定板上的直线应该是直的。
import cv2
img = cv2.imread("image.jpg")
# 使用标定参数进行畸变矫正
dst = cv2.undistort(img, mtx, dist)
# 矫正后图片的路径
cv2.imwrite("undistorted.jpg", dst)
示例
下面给出两条使用OpenCV实现相机标定板的示例。
示例1:使用OpenCV进行相机标定和矫正
-
准备相机标定板图片,并确保标定板表面清洁。
-
使用上述攻略进行标定,将标定结果保存到文件中。
-
使用
cv2.VideoCapture()
函数打开相机。 -
使用
cv2.namedWindow()
函数创建窗口,并使用cv2.moveWindow()
函数指定窗口位置。 -
循环从相机读取图片,使用
cv2.undistort()
函数进行畸变矫正,将矫正后的图片显示在窗口中,并使用cv2.waitKey()
函数进行窗口更新。
以下是示例代码:
import cv2
import numpy as np
# 读取相机标定参数
mtx = np.loadtxt("cam_mtx.txt")
dist = np.loadtxt("cam_dist.txt")
# 打开相机
cap = cv2.VideoCapture(0)
# 创建窗口
cv2.namedWindow("undistorted", cv2.WINDOW_NORMAL)
cv2.moveWindow("undistorted", 0, 0)
while True:
# 读取一帧图片
ret, frame = cap.read()
if ret:
# 畸变矫正
dst = cv2.undistort(frame, mtx, dist)
# 显示矫正后的图片
cv2.imshow("undistorted", dst)
# 等待按键事件,更新窗口
cv2.waitKey(1)
# 释放资源
cap.release()
cv2.destroyAllWindows()
示例2:检测相机运动轨迹
-
准备相机标定板图片,并确保标定板表面清洁。
-
使用上述攻略进行标定,将标定结果保存到文件中。
-
打开相机。
-
循环从相机读取图片,使用
CV2.findChessboardCorners()
函数检测标定板特征点,并使用cv2.drawChessboardCorners()
函数在图片上绘制特征点,同时利用标定结果计算相机运动轨迹。
以下是示例代码:
import cv2
import numpy as np
# 读取相机标定参数
mtx = np.loadtxt("cam_mtx.txt")
dist = np.loadtxt("cam_dist.txt")
# 打开相机
cap = cv2.VideoCapture(0)
# 创建窗口
cv2.namedWindow("undistorted", cv2.WINDOW_NORMAL)
cv2.moveWindow("undistorted", 0, 0)
# 计算相机移动量
R = np.eye(3)
t = np.zeros((3, 1))
while True:
# 读取图片
ret, img = cap.read()
if ret:
# 畸变矫正
dst = cv2.undistort(img, mtx, dist)
# 检测标定板特征点
ret, corners = cv2.findChessboardCorners(dst, (6, 9), None)
if ret:
# 绘制特征点
cv2.drawChessboardCorners(dst, (6, 9), corners, ret)
# 计算相机运动轨迹
_, rvecs, tvecs, inliers = cv2.solvePnPRansac(objp, corners, mtx, dist)
R_new, _ = cv2.Rodrigues(rvecs)
t_new = tvecs.reshape(3, 1)
R = np.dot(R_new, R)
t = t + np.dot(R_new, t)
print("move distance: ", np.linalg.norm(t))
# 显示图片
cv2.imshow("undistorted", dst)
# 等待按键事件,更新窗口
cv2.waitKey(1)
# 释放资源
cap.release()
cv2.destroyAllWindows()
以上就是实现相机标定板的完整攻略,希望能对你有所帮助。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:OpenCV实现相机标定板 - Python技术站