Advertisement

相机标定

阅读量:

相机标定

通过棋盘格图案和可用的相机(包括笔记本电脑、台式机或其他设备自带的摄像头以及手机摄像头)完成相机标定过程,并对测量结果的有效性进行评估。

通过连续多次使用同一台手机的内置摄像头进行校准实验,在此过程中记录并分析了该设备的内部几何参数以及成像畸变情况

复制代码
    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)

还没有任何评论哟~