计算视觉——相机参数标定法
-
背景
在图像测量过程以及机器视觉应用中,为确定空间物体表面某点的三维几何位置与其在图像中对应点之间的相互关系,必须建立相机成像的几何模型,这些几何模型参数就是相机参数。在大多数条件下这些参数必须通过实验与计算才能得到,这个求解参数的过程就称之为相机标定(或摄像机标定)。
较早的相机标定的方法需要计算相机投影矩阵M中的11个未知参数,需要严格个出三个两两互相垂直的平面来做标定,该实验条件较为严格,一般情况难以实现。此后张正友于1998年在论文:"A Flexible New Technique fro Camera Calibration"提出了基于单平面棋盘格的相机标定方法。该方法介于传统的标定方法和自标定方法之间,使用简单实用性强,有以下优点:
1.不需要额外的器材,一张打印的棋盘格即可。
2.标定简单,相机和标定板可以任意放置。
3.标定的精度高。
-
原理
- 相机标定
同步标定内部参数和外部参数,一般包括两种策略:
光学标定: 利用已知的几何信息(如定长棋盘格)实现参数求解。
自标定: 在静态场景中利用 structure from motion估算参数。
2.相机模型
通过空间中已知坐标的(特征)点 (Xi,Yi,Zi)(Xi,Yi,Zi)(Xi,Yi,Zi),以及它们在图像中的对应坐标(ui,vi)(ui,vi)(ui,vi),直接估算 11 个待求解的内部和外部参数。
即下式
可得
- 线性回归标定参数
由相机模型公式变形可得:
即为如下矩阵
- 非线性优化标定参数
特征点投影方程如下:
给定{(ui,vi)},标定参数矩阵 M 的概率为:
给定{(ui,vi)},标定参数矩阵 M 的似然函数为:
3.张正友相机标定原理
3.1 简单介绍
”张正友标定法” 是指张正友教授1998年提出的单平面棋盘格的摄像机标定方法。文中提出的方法介于传统标定法和自标定法之间,但克服了传统标定法需要的高精度标定物的缺点。相对于自标定而言,提高了精度,便于操作。因此张正友标定法被广泛应用于计算机视觉方面。
在张氏标定法中,用于标定的棋盘格是三维场景中的一个平面Π,其在成像平面的像是另一个平面π,知道了两个平面的对应点的坐标,就可以求解得到两个平面的单应矩阵H。其中,标定的棋盘格是特制的,其角点的坐标是已知的;图像中的角点,可以通过角点提取算法得到(如Harris角点),这样就可以得到棋盘平面Π和图像平面π的单应矩阵H。
3.2 步骤介绍
- 计算单应性矩阵H
单应性:在计算机视觉中被定义为一个平面到另一个平面的投影映射。首先确定,图像平面与标定物棋盘格平面的单应性。
设三维世界坐标的点为
二维相机平面像素坐标为
所以标定用的棋盘格平面到图像平面的单应性关系为:
(其中,K为相机的内参矩阵,R为外部参数矩阵(旋转矩阵),T为平移向量。令
设棋盘格位于Z=0的平面,定义旋转矩阵R的第i列为 ri, 则有:
于是空间到图像的映射可改为:H=λK[r1 r2 t]
其中H 是描述Homographic矩阵,可通过最小二乘,从角点世界坐标到图像坐标的关系求解。
- 计算内参数矩阵
根据步骤1中的式子,令 H 为 H = [h1 h2 h3],则 [h1 h2 h3]=λK[r1 r2 t],再根据正交和归一化的约束可以得到等式:
即每个单应性矩阵能提供两个方程,而内参数矩阵包含5个参数,要求解,至少需要3个单应性矩阵。为了得到三个不同的单应性矩阵,我们使用至少三幅棋盘格平面的图片进行标定。
通过改变相机与标定板之间的相对位置来得到三个不同的图片。为了方便计算,我们定义:
B 中的未知量可表示为6D 向量 b
设H中的第i列为 hi,
根据b的定义,可以推导出公式,
最后推导出
通过上式,我们可知当观测平面 n ≥ 3 时,即至少3幅棋盘格图像,可以得到b的唯一解,求得相机内参数矩阵K。
- 计算外参数矩阵
外部参数可通过Homography求解,由 H = [h1 h2 h3] = λA[r1 r2 t],可推出
- 最大似然估计
上述的推导结果是基于理想情况下而言,但由于可能存在一些其他干扰,所以使用最大似然估计进行优化。假设拍摄了n张棋盘格图像,每张图像有m个角点。最终获得的最大似然估计公式为
-
三、实验过程
-
数据集
- 实验步骤
(1)取材:打印一张棋盘格,把它贴在一个平面上,作为标定物,通过调整标定物或摄像机 的方向,为标定物拍摄一些不同方向的照片。
(2)从照片中提取棋盘格角点。
(3)估算理想无畸变的情况下,五个内参和六个外参。
(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("life2/*.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)
- 实验结果
mtx为内参数矩阵,dist为畸变系数:
rvecs为旋转向量:
tvecs为平移向量:
- 总结
1. 我们可以标定出相机的畸变参数,内参矩阵,外参矩阵对相机进行参数调整,从而完成畸变校正。
畸变参数:计算机在径向和切向的畸变程度
内参矩阵:一个像素的物理尺寸dx和dy,焦距 f,图像物理坐标的扭曲因子r,图像原点相对于光心成像点的的纵横偏移量u和 v。
外参矩阵:世界坐标转换成相机坐标系的旋转和平移矩阵。
2. 把打印的棋盘纸张贴在平板上,拍出来的照片和显示图像及物理点和世界点存在的误差才会理想,找一个光线较暗不会造成拍摄反光的地方对图片进行拍摄,可以有效减小误差。
3.从实验结果可以看出,mtx为内参矩阵,dist为畸变系数,外参数为rvecs(旋转向量)和tvecs(平移向量)。
归一化焦距fx=575.46539307,fy=568.10003662,像主点(光心)的坐标Cx=324.2929208,Cy=259.90821087。所有图像投影坐标和亚像素角点坐标之间的总体的平均误差大概为0.16,误差较小,说明手机拍照性能较优。