计算机视觉:相机模型与参数标定

一、相机投影模型

1、小孔成像

2、相机模型中的四个平面坐标系

3、像主点偏移

4、畸变现象与内参矩阵

5、外参矩阵

二、相机标定:张正友棋盘格标定法

1、张正友棋盘格标定法描述

2、计算外参和内参

2.1 计算单应性矩阵H

2.2 计算内参数矩阵

2.3 计算外参数矩阵

3、实验:MATLAB实现

3.1 实验数据

3.2 实验过程

3.3 实验结果

4、实验:OpenCV实现

4.1 实现代码

4.2 实验结果

5、实验分析与总结


一、相机投影模型

        计算机视觉都是对输入的图像(或视频)进行处理,而这写图像(或视频)都需要通过相机获得,用相机拍照(或者用相机录视频),所以是相机就是一个非常关键的工具。

        机器人在地面上行走时,需要用摄像头去扫描周围的环境,然后通过算法计算,判断出下一步应该怎么走,以确保能不摔倒并绕开障碍物。因此,了解相机(摄像头)是很有必要的。

1、小孔成像

        早在春秋战国时期,墨子在其著作《墨经》中提出了“光八条”,论述了光、物、影三者的关系。墨子设计的小孔成像实验形象地验证了光的直线传播特性以及物与影的几何投影关系,墨子的光八条概括了孔径相机的最基本的原理。

2、相机模型中的四个平面坐标系

为建立小孔成像投影模型如下约束限制:

  • 投影中心位于空间坐标原点O;
  • 光轴与空间坐标轴Z轴重合;
  • 焦平面与投影平面重合;
  • 三维空间中的点P(X,Y,Z)在投影平面上的对应像点为p(x,y)。

  • C点:表示相机的中心点,也是相机坐标系的中心点;
  • Z轴:表示相机的主轴;
  • p点:表示像主点,主轴与像平面相交的点;
  • 像平面:p点所在的平面表示相机的像平面,也就是图片坐标系所在的二维平面;
  • 焦距f:C点到p点的距离,表示相机的焦距;
平面坐标系维度含义
图像像素坐标系2D, (u,v)以像素为单位,是以图像的左上方为原点的图像坐标系。
图像物理坐标系2D, (x,y)以毫米为单位,用物理单位表示图像像素位置,定义坐标系OXY,原点O定义在相机与图像平面交点。
相机坐标系3D, (X,Y,Z)以毫米为单位,以相机的光心作为原点,Z轴与光轴重合,并垂直于成像平面,且取摄影方向为正方向,Xc、Yc轴与图像物理坐标系的x,y轴平行,且OcO为摄像机的焦距f。
世界坐标系3D, (U,V,W)根据具体情况而定,该坐标系描述环境中任何物体的位置,根据具体情况而定,满足右手法则。

 从上面的图中,我们利用相似三角形的原理可以知道:

\frac{y}{f}=\frac{Y}{Z},\frac{x}{f}=\frac{X}{Z}

所以可以得到:

x=\frac{fX}{Z},y=\frac{fY}{Z}

于是我们引入齐次坐标来表示上述相机、像素、世界坐标系之间的关系:

\begin{pmatrix} u\\ v\\ 1 \end{pmatrix}\sim \begin{pmatrix} fX\\ fY\\ Z \end{pmatrix}=\begin{bmatrix} f & 0 & 0 & 0\\ 0 & f & 0 & 0\\ 0& 0 & 1 & 0 \end{pmatrix}\begin{pmatrix} X\\ Y\\ Z\\ 1 \end{pmatrix}

进一步变换为:

使用齐次坐标,方便计算,具有可以看下面这篇内容。

为什么要引入齐次坐标,齐次坐标的意义 - 简书 (jianshu.com)

3、像主点偏移

        每个相机都不能算十全十美的,可能由于厂家生成的原因,或者个人使用的原因......相机光心都有可能存在很微小的误差,完完全全在原点可能性较小,会发生一定的偏移。

        我们用 u_0,v_0 分别是在x、y方向上的偏移量。于是,我们写出内参矩阵:

4、畸变现象与内参矩阵

       由于相机的透镜制造精度以及组装工艺的偏差会带来畸变现象,导致拍出来的图像失真。镜头的畸变分为两类,分别是径向畸变和切向畸变两类:

图像径向畸变:由于透镜质量原因,沿着透镜半径方向分布的畸变,光线在远离透镜中心的地方比靠近中心的地方更加弯曲。

  • 桶状畸变:

  •  枕形畸变

 图像切线畸变:切向畸变主要发生在相机和镜头不平行的情况下;因为有夹角,所以光透过镜头传到图像传感器上时,成像位置发生了变化。

        x,y是归一化的图像坐标,即坐标原点已经移动到主点,并且像素坐标除以焦距。p1、p2是径向畸变系数,r2=x2+y2。

        因此,内参矩阵中K应该加入畸变参数,实现畸变矫正:

畸变矫正

5、外参矩阵

        上述讨论的范畴全是在相机坐标下发生的事情,然而实际情况是,相机往往装在机械臂末端,移动小车前方,车辆四周,当我们需要知道成像平面内的物体在机器人或者车辆坐标系下的位置时,需要进行一个坐标转换,称为外参(Extrinsic parameters),它与相机制造、镜头畸变没有任何关系,只与相机在世界坐标系内的安装位置和角度有关。从纯数学的角度来说,刚体运动和坐标变换总是可以分解为一个旋转运动和一个平移运动。

因此世界坐标系下的点P与图像坐标的关系可以表达为:

二、相机标定:张正友棋盘格标定法

        相机标定就是确定相机的内部参数以及外部参数,通过一种理论数学模型和优化的手段来近似实际的物理成像关系。

   两类很重要的参数

  • 相机内部参数/内方位元素: 焦距、像主点坐标、畸 变参数 
  • 相机外部参数/外方位元素: 旋转、平移

1、张正友棋盘格标定法描述

        使用张正友棋盘格标定法,是将照片中的三维信息压缩为二维(Z=0)。在张正友棋盘格标定法中,用于标定的棋盘格是三维场景中的一个平面Π,其在成像平面的像是另一个平面π,知道了两个平面的对应点的坐标,就可以求解得到两个平面的单应矩阵H。其中,标定的棋盘格是特制的,其角点的坐标是已知的;图像中的角点,可以通过角点提取算法得到(例如Harris角点),这样就可以得到棋盘平面Π和图像平面π的单应矩阵H。

   方法步骤:

  • 打印一张棋盘格A4纸张(黑白间距已知),并 贴在一个平板上;
  • 针对棋盘格拍摄若干张图片(一般10-20张);
  • 检测每张图片中的棋盘图案的角点(Harris角点);
  • 根据角点位置信息及图像中的坐标,求解 Homographic矩阵;
  • 利用解析解估算方法计算出5个内部参数,以及6个外部参数;
  • 通过基于极大似然准则的优化解,提高A,R,t矩阵的精度。

   优点:

  • 只需一个平面;
  • 标定过程中无需知道棋盘格的方位;
  • 大量开源代码,如下链接。

Intel’s OpenCV libraryhttp://www.intel.com/research/mrl/research/opencv/Matlab version by Jean-Yves Bougethttp://www.vision.caltech.edu/bouguetj/calib_doc/index.htmlZhengyou Zhang’s web siteicon-default.png?t=M4ADhttp:// http://research.microsoft.com/~zhang/Calib/

2、计算外参和内参

2.1 计算单应性矩阵H

棋盘格平面到图像平面的单应性关系为:

s_0m=K\left [ R ,T\right ]X

其中s为尺度因子,K为摄像机内参数,R为旋转矩阵,T为平移向量。

s对于齐次坐标来说,不会改变齐次坐标值。张正友棋盘格标定法中,将世界坐标系构载在棋盘格平面上,令棋盘格平面为Z=0的平面。则可得:

其中K[r1, r2, r3, t]叫做单应性矩阵H,即

 

2.2 计算内参数矩阵

即每个单应性矩阵能提供两个方程,而内参数矩阵包含5个参数,要求解,至少需要3个单应性矩阵。为了得到三个不同的单应性矩阵,我们使用至少三幅棋盘格平面的图片进行标定。通过改变相机与标定板之间的相对位置来得到三个不同的图片。为了方便计算,定义如下:

可以看到,B是一个对称阵,所以B的有效元素为六个,让这六个元素写成向量b,即::

2.3 计算外参数矩阵

外部参数可通过Homography求解,由 H = [h1 h2 h3] = λK[r1 r2 t],可推出:

一般而言,求解出的R = [r1 r2 r3] 不会满足正交与 归一的标准 • 在实际操作中,R 可以通过SVD分解实现规范化( 详见原文)。

3、实验:MATLAB实现

3.1 实验数据

        借用了实验室的棋盘格标定板,然后再使用手机对棋盘进行拍摄,拍摄了共20张的棋盘数据,同时具有角度变换和距离变换等设置。

3.2 实验过程

使用MATLAB自带的工具箱进行标定。

Step1:点击APP

Step2:点击下滑,找到图像处理和计算机视觉中的CameraCalibrator并点击

 Step3:点击添加拍摄的棋盘格图像

Step4:添加照片,并点击运行

 

Step5:导出相机标定参数

Step6:在matlab工作空间里可以看到相机参数的属性

Step7:查看相机的内参矩阵,径向畸变和切向畸变

3.3 实验结果

4、实验:OpenCV实现

4.1 实现代码

import cv2
import numpy as np
import glob

np.set_printoptions(suppress=True)

# 棋盘格角点检测
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001)

# 棋盘格模板规格:内角点个数,内角点是和其他格子连着的点
w = 11  # 内角度宽为11
h = 8   # 内角度高为8

# 世界坐标系中的棋盘格点,去掉Z坐标,记为二维矩阵
objp = np.zeros((w * h, 3), np.float32)
objp[:, :2] = np.mgrid[0:w, 0:h].T.reshape(-1, 2)

# 储存棋盘格角点的世界坐标和图像坐标对
objpoints = []  # 在世界坐标系中的三维点
imgpoints = []  # 在图像平面的二维点

# 处理图像
images = glob.glob('*.jpg')
i = 0
for fname in images:
    img = cv2.imread(fname)
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

    # 找到棋盘格角点
    ret, corners = cv2.findChessboardCorners(gray, (w, h), None)

    # 如果找到足够点对,将其存储起来
    if ret == True:
        # 角点精确检测
        i += 1
        cv2.cornerSubPix(gray, corners, (11, 11), (-1, -1), criteria)
        objpoints.append(objp)
        imgpoints.append(corners)

        # 将角点在图像上显示
        cv2.drawChessboardCorners(img, (w, h), corners, ret)
        cv2.namedWindow("findCorners", 0)
        cv2.imshow("findCorners", img)
        cv2.imwrite('h' + str(i) + '.jpg', img)
        cv2.waitKey(10)

# 销毁窗口
cv2.destroyAllWindows()

'''
输入:世界坐标系里的位置、像素坐标、图像的像素尺寸大小、3*3矩阵、相机内参数矩阵、畸变矩阵
输出:标定结果、相机的内参数矩阵、畸变系数、旋转矩阵、平移向量
参数说明:mtx内参数矩阵、dist畸变系数、rvecs外参数的旋转向量、tvecs外参数的平移向量
'''
ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(objpoints, imgpoints, gray.shape[::-1], None, None)

# 打印结果
print(("ret:"), ret)
print(("内参矩阵:\n"), mtx)         # 内参数矩阵
print(("畸变参数:\n"), dist)        # 畸变系数
print(("外参:旋转向量:\n"), rvecs)  # 旋转向量
print(("外参:平移向量:\n"), tvecs)  # 平移向量

# 去畸变:使用cv.getOptimalNewCameraMatrix()优化内参数和畸变系数
img2 = cv2.imread('1.jpg')
h, w = img2.shape[:2]
newcameramtx, roi = cv2.getOptimalNewCameraMatrix(mtx, dist, (w, h), 0, (w, h))  # 自由比例参数
dst = cv2.undistort(img2, mtx, dist, None, newcameramtx)
cv2.imwrite('result.jpg', dst)


# 反投影误差:通过反投影误差,我们可以来评估结果的好坏。越接近0,说明结果越理想
total_error = 0
for i in range(len(objpoints)):
    imgpoints2, _ = cv2.projectPoints(objpoints[i], rvecs[i], tvecs[i], mtx, dist)
    error = cv2.norm(imgpoints[i], imgpoints2, cv2.NORM_L2) / len(imgpoints2)
    total_error += error
print(("total error: "), total_error / len(objpoints))

4.2 实验结果

角点检测结果图

 ① 内参矩阵

② 外参矩阵

5、实验分析与总结

        从最后实验得出的结果中,可以知道我手机的相机的各种内部参数和外部参数。通过MATLAB和OpenCV两种方式实现相机标定对比发现,两者的标定结果差距并不大,opencv标定的稳定性也是可以的。

        Matlab的优势在于可以显示重投影误差、3D效果图等,而且可以单张图片单独使用不同的窗口标定。Opencv的优势则是多次标定比较快捷,而且标定的结果可以直接用于后续的立体校正、立体匹配中。

  • 2
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

DreamWendy

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值