计算机视觉python--相机参数标定

1 基于单平面棋盘格的相机标定方法

在图像测量过程以及机器视觉应用中,为确定空间物体表面某点的三维几何位置与其在图像中对应点之间的相互关系,必须建立相机成像的几何模型,这些几何模型参数就是相机参数。在大多数条件下这些参数必须通过实验与计算才能得到,这个求解参数的过程就称之为相机标定(或摄像机标定)。
较早的相机标定的方法需要计算相机投影矩阵M中的11个未知参数,需要严格个出三个两两互相垂直的平面来做标定,该实验条件较为严格,一般情况难以实现。此后张正友于1998年在论文:"A Flexible New Technique fro Camera Calibration"提出了基于单平面棋盘格的相机标定方法。该方法介于传统的标定方法和自标定方法之间,使用简单实用性强,有以下优点:

  1. 不需要额外的器材,一张打印的棋盘格即可。
  2. 标定简单,相机和标定板可以任意放置。
  3. 标定的精度高。

2 基本原理

2.1 相机标定

同步标定内部参数和外部参数,一般包括两种策略:

  • 光学标定: 利用已知的几何信息(如定长棋盘格)实现参数求解。
  • 自标定: 在静态场景中利用 structure from motion估算参数。

2.2 针孔相机模型

在这里插入图片描述
在这里插入图片描述

2.2.1 像主点偏移

在这里插入图片描述

2.2.2 外参矩阵

在这里插入图片描述
在这里插入图片描述

2.2.3 重点的两类参数

在这里插入图片描述

2.3 相机标定

同步标定内部参数和外部参数,一般包括两种策略:

  1. 光学标定: 利用已知的几何信息(如定长棋盘格)实 现参数求解。
  2. 自标定: 在静态场景中利用 structure from motion估算参数。

2.3.1 标定参数线性回归

在这里插入图片描述在这里插入图片描述在这里插入图片描述
在这里插入图片描述

优点
–所有的相机参数集中在一个矩阵中,便于求解
–通过矩阵可以直接描述世界坐标中的三维点,到二维 图像平面中点的映射关系

缺点
–无法直接得知具体的内参数和外参数(可以使用QR分解但还不是很成熟)
–求解出的11个未知量,比待标定参数(9个)更多。带 来了参数不独立/相关的问题
–对噪声/误差敏感

2.3.2 标定参数的非线性优化

在这里插入图片描述
在这里插入图片描述

2.3.3 相机标定总结

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3 张正友棋盘相机标定

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.1 具体步骤

在这里插入图片描述

4 实验准备及数据

在这里插入图片描述

5 实验代码

# -*- coding: utf-8 -*-
import cv2
import numpy as np
import glob

# 设置寻找亚像素角点的参数,采用的停止准则是最大循环次数30和最大误差容限0.001
criteria = (cv2.TERM_CRITERIA_MAX_ITER | cv2.TERM_CRITERIA_EPS, 30, 0.001)

# 获取标定板角点的位置
objp = np.zeros((6 * 6, 3), np.float32)
objp[:, :2] = np.mgrid[0:6, 0:6].T.reshape(-1, 2)  # 将世界坐标系建在标定板上,所有点的Z坐标全部为0,所以只需要赋值x和y

obj_points = []  # 存储3D点
img_points = []  # 存储2D点

images = glob.glob("d:/picture/005/*.jpg")
i=0;
for fname in images:
    img = cv2.imread(fname)
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    size = gray.shape[::-1]
    ret, corners = cv2.findChessboardCorners(gray, (6, 6), None)
    #print(corners)

    if ret:

        obj_points.append(objp)

        corners2 = cv2.cornerSubPix(gray, corners, (5, 5), (-1, -1), criteria)  # 在原角点的基础上寻找亚像素角点
        #print(corners2)
        if [corners2]:
            img_points.append(corners2)
        else:
            img_points.append(corners)

        cv2.drawChessboardCorners(img, (6,6), corners, ret)  # 记住,OpenCV的绘制函数一般无返回值
        i+=1;
        cv2.imwrite('conimg'+str(i)+'.jpg' , img)
        cv2.waitKey(1500)

print(len(img_points))
cv2.destroyAllWindows()

# 标定
ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(obj_points, img_points, size, None, None)

print("ret:", ret)
print("mtx:\n", mtx) # 内参数矩阵
print("dist:\n", dist)  # 畸变系数   distortion cofficients = (k_1,k_2,p_1,p_2,k_3)
print("rvecs:\n", rvecs)  # 旋转向量  # 外参数
print("tvecs:\n", tvecs ) # 平移向量  # 外参数

print("-----------------------------------------------------")

img = cv2.imread(images[2])
h, w = img.shape[:2]
newcameramtx, roi = cv2.getOptimalNewCameraMatrix(mtx,dist,(w,h),1,(w,h))#显示更大范围的图片(正常重映射之后会删掉一部分图像)
print (newcameramtx)
print("------------------使用undistort函数-------------------")
dst = cv2.undistort(img,mtx,dist,None,newcameramtx)
x,y,w,h = roi
dst1 = dst[y:y+h,x:x+w]
cv2.imwrite('calibresult3.jpg', dst1)
print ("方法一:dst的大小为:", dst1.shape)

6 实验结果与分析

6.1 角点检测结果及分析

在代码运行中保存每张图片的角点检测图片
在这里插入图片描述

6.2后置摄像头的内部参数

在这里插入图片描述
其中ret指重投影误差
mtx指内参数矩阵
dist指畸变系数

6.3后置摄像头的外部参数

外部参数(旋转向量)
在这里插入图片描述

外部参数(平移向量)
在这里插入图片描述

遇到的问题
从下往上拍的图片
在这里插入图片描述
可能因为光线问题 有反光且图片偏蓝 导致并没有运行出来

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值