相机标定
发布时间
阅读量:
阅读量
相机标定
通过棋盘格图案和可用的相机(包括笔记本电脑、台式机或其他设备自带的摄像头以及手机摄像头)完成相机标定过程,并对测量结果的有效性进行评估。
通过连续多次使用同一台手机的内置摄像头进行校准实验,在此过程中记录并分析了该设备的内部几何参数以及成像畸变情况
chessboard defected
ret: 1.3550609729186074
内参数矩阵:
[[4.70062953e+03 0.00000000e+00 1.38446011e+03]
[0.00000000e+00 4.72049000e+03 2.28597903e+03]
[0.00000000e+00 0.00000000e+00 1.00000000e+00]]
畸变系数:
[[-0.01967854 0.18333343 0.00173773 -0.00423632 -0.07690654]]
旋转向量: [array([[-0.09478964],
[ 0.14178481],
[-1.53941182]])]
平移向量: [array([[-2.01931616],
[ 4.44319147],
[12.99324445]])]
相机标定结束

通过相机标定函数
ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(objpoints, imgpoints, size, None, None)
该方案具有可行性
基于1的方法,在同一台相机上将棋盘格放置于离相机约1米的位置,并在同一场景下获取多帧图像序列。随后通过线性算法计算两者的相对姿态,并根据实验数据评估计算结果的合理性程度。
经过多次实验可得的数据:
开始相对位姿估计
旋转矩阵 [[-0.09479112]
[ 0.14178603]
[-1.53941197]]
平移变量 [[-2.01930241]
[ 4.4431929 ]
[12.99324188]]

调用pnp函数:
返回值, 旋转向量, 平移向量 = cv.solvePnP( 物体点坐标, 图像点坐标, 相机矩阵, 相机畸变系数[, 旋转向量[, 平移向量[, 是否使用外参猜测[, 参数标志位]]]])
• objectPoints,目标座标系下的三维点座标,3*N
• imagePoints,像平面点坐标
• cameraMatrix,相机内参数矩阵,如前所述
• distCoeffs ,畸变系数向量
• rvec,旋转矩阵计算结果,以Rodrigues向量形式表示
• tvec,平移向量计算结果
实验方案可行
相机标定与相对位姿估计代码如下
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2019/2/26 20:15
# @Author : Seven
# @File : CameraCalibration.py
# @Software: PyCharm
# function : 摄像机标定
import cv2
import numpy as np
import glob
# 设置寻找亚像素角点的参数,采用的停止准则是最大循环次数30和最大误差容限0.001
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001)
# 准备目标点,例如 (0,0,0), (1,0,0), (2,0,0) ....,(6,5,0)
objp = np.zeros((8 * 6, 3), np.float32)
# 将世界坐标系建在标定板上,所有点的Z坐标全部为0,所以只需要赋值x和y
objp[:, :2] = np.mgrid[0:8, 0:6].T.reshape(-1, 2)
# 用于存储所有图像中的对象点和图像点的数组。
objpoints = [] # 存储在现实世界空间的3d点
imgpoints = [] # 储存图像平面中的2d点。
images = glob.glob('img.jpg')
for fname in images:
img = cv2.imread(fname)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 获取XY坐标
size = gray.shape[::-1]
# 找到棋盘角点
ret, corners = cv2.findChessboardCorners(gray, (8, 6), None)
# 如果找到,添加3D点,2D点
if ret == True:
print('chessboard defected')
objpoints.append(objp)
# 增加角点的准确度
corners2 = cv2.cornerSubPix(gray, corners, (11, 11), (-1, -1), criteria)
imgpoints.append(corners2)
# 画出并显示角点
img = cv2.drawChessboardCorners(img, (8, 6), corners2, ret)
# 可以改变窗口大小
cv2.namedWindow('img', 0)
cv2.resizeWindow('img', 600, 600)
cv2.imshow('img', img)
cv2.waitKey(500)
# 相机标定
ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(objpoints, imgpoints, size, None, None)
# 保存相机参数
np.savez('C.npz', mtx=mtx, dist=dist, rvecs=rvecs, tvecs=tvecs)
print("ret:", ret)
print("内参数矩阵:\n", mtx)
print("畸变系数:\n", dist)
print("旋转向量:", rvecs) # 外参数
print("平移向量:", tvecs) # 外参数
print("相机标定结束")
print("................")
print("开始相对位姿估计")
#***************************分割线*****************************#
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001)
# 准备目标点,例如 (0,0,0), (1,0,0), (2,0,0) ....,(6,5,0)
objp = np.zeros((8 * 6, 3), np.float32)
# 将世界坐标系建在标定板上,所有点的Z坐标全部为0,所以只需要赋值x和y
objp[:, :2] = np.mgrid[0:8, 0:6].T.reshape(-1, 2)
# 用于存储所有图像中的对象点和图像点的数组。
objpoints = [] # 存储在现实世界空间的3d点
imgpoints = [] # 储存图像平面中的2d点。
images1 = glob.glob('1m.jpg')
for fname in images1:
img = cv2.imread(fname)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 获取XY坐标
size = gray.shape[::-1]
# 找到棋盘角点
ret, corners = cv2.findChessboardCorners(gray, (8, 6), None)
# 如果找到,添加3D点,2D点
if ret == True:
print('chessboard defected')
objpoints.append(objp)
# 增加角点的准确度
corners2 = cv2.cornerSubPix(gray, corners, (11, 11), (-1, -1), criteria)
imgpoints.append(corners2)
# 画出并显示角点
img = cv2.drawChessboardCorners(img, (8, 6), corners2, ret)
# 可以改变窗口大小
cv2.namedWindow('img', 0)
cv2.resizeWindow('img', 700, 700)
obj_1 = objpoints
img_1 = imgpoints
# print("世界坐标系", objpoints)
# print("像素坐标系", imgpoints)
cv2.imshow('img', img)
cv2.waitKey(500)
# 相对位姿变换
with np.load('C.npz') as X:
mtx, dist, _, _ = [X[i] for i in ('mtx', 'dist', 'rvecs', 'tvecs')]
retval, rvec, tvec = cv2.solvePnP(objp, corners, mtx, dist)
print("旋转矩阵", rvec)
print("平移变量", tvec)
视图如下:


全部评论 (0)
还没有任何评论哟~
