Camera Calibration

cold

2020/08/19 发布于 技术 分类

Surveyed on the topic of camera model and camera calibration. In terms of camera model, I first introduced the ideal pin-hole imaging model and then talked about the distortion model in real life. For camera calibration, I explained this part from theory to practice. More specifically, I started with matrix manipulation about calibration and ended with an opencv demo which showed how to calibrate our own camera with a checkboard. The presentation was made on 2020.7.16.

文字内容
1. 相机标定 张寒萌 2020/07/16
2. Outline • 相机模型 • 坐标系变换 • 畸变模型 • 相机标定 • 张正友标定法 • opencv实验 • 代码 • demo
3. 相机模型
4. 相机模型
5. 世界坐标系->相机坐标系
6. 相机坐标系->图像坐标系 • 射影变换。相似三角形。
7. 图像坐标系->像素坐标系
8. 图像坐标系->像素坐标系 v u v u γ Skew effect The angle between of two image axes is not equal to 90 degrees.
9. 坐标系变换 内参(4) 外参(6)
10. 畸变模型 • 径向畸变 一般来讲,成像仪中心的径向畸变为0,越向边缘移动,畸变越严重。
11. 畸变模型 • 切向畸变
12. 畸变模型 • 畸变描述 畸变向量:(k1, k2, p1, p2, k3) 对于一般的摄像机校正,通常使用泰勒级数中的前两项k1和k2就够了;对畸变很大的摄像 机,比如鱼眼透镜,可以使用第三径向畸变项k3
13. Outline • 相机模型 • 坐标系变换 • 畸变模型 • 相机标定 • 张正友标定法 • opencv实验 • 代码 • demo
14. 相机标定 • 目的:求出相机的内参外参和畸变参数 • 应用:生成校正后的图像;根据获得的图像重构三维场景 • 摄像机标定过程,简单的可以简单的描述为通过标定板,如下图,可以得到n 个对应的世界坐标三维点Xi和对应的图像坐标二维点xi,这些三维点到二维点 的转换都可以通过上面提到的相机内参K,相机外参R和t,以及畸变参数D, 经过一系列的矩阵变换得到。
15. 参数分析 • 假设有N个角点和K个棋盘图像,需要多少个视场和角点才能提供足够的约束来求解这些参数呢? • N个角点和K个棋盘图像可以提供2NK的约束,即2NK的方程。忽略每次的畸变,那么我们需要求 解4个内参数和6K个外参数。那么有解的前提是方程的总数应该大于等于未知参数的总数即 2NK>=6K+4,或者写成(N-3)K>=2。为了方便理解,下图是一个3×3大小的棋盘,红色圈标记出 了它含有的内角点: • 无论一个平面上检测到多少个角点,我们只能得到4个有用的角点信息,那么上述的公式中N就约 束为4,即公式变为(4-3)K>=2,即K>=2。即要求解10个参数最少需要两个视场。考虑到噪声和 数值稳定性要求,对大棋盘需求收集更多的图像。为了得到高质量结果,至少需要10幅7×8或者 更大棋盘的图像(而且只在移动棋盘在不同图像中足够大以从视场图像中得到更加丰富的信息)。
16. 相机标定 • 方法 • 线性标定方法(运算速度快;精度不高) • 非线性优化标定方法(精度高;模型复杂计算量大) • 两步标定法 • Tsai的经典两步法(参数求解简易;标定成本高) • 张正友标定法(简单,成本低)
17. 张正友标定法 Step1: 求解单应性矩阵 Step2: 求解内参和外参 Step3: 求解畸变系数
18. 求解单应性矩阵 • 打印一张棋盘方格图贴在一个平面上,从不同的角度拍摄至少3张模板图像, 检测出每幅图像中的特征点,由检测到的特征点可以算出每幅图像的单应性矩 阵H。 Zhang, Zhengyou. "A flexible new technique for camera calibration." Pattern Analysis and Machine Intelligence, IEEE Transactions on 22.11 (2000): 1330-1334.
19. 求解单应性矩阵 • 假设模板落在世界坐标系的Z=0的平面上。设K为摄像机的内参矩阵,ri是R的第i个向量,那 么对于模板平面上的每一个点,都有 Zhang, Zhengyou. "A flexible new technique for camera calibration." Pattern Analysis and Machine Intelligence, IEEE Transactions on 22.11 (2000): 1330-1334.
20. 求解单应性矩阵 Zhang, Zhengyou. "A flexible new technique for camera calibration." Pattern Analysis and Machine Intelligence, IEEE Transactions on 22.11 (2000): 1330-1334.
21. 求解内参和外参 Zhang, Zhengyou. "A flexible new technique for camera calibration." Pattern Analysis and Machine Intelligence, IEEE Transactions on 22.11 (2000): 1330-1334.
22. 求解内参和外参 Zhang, Zhengyou. "A flexible new technique for camera calibration." Pattern Analysis and Machine Intelligence, IEEE Transactions on 22.11 (2000): 1330-1334.
23. 求解内参和外参 Zhang, Zhengyou. "A flexible new technique for camera calibration." Pattern Analysis and Machine Intelligence, IEEE Transactions on 22.11 (2000): 1330-1334.
24. 求解内参和外参 • 外参数(旋转和平移)可以由单应性条件计算得到: • 上述公式中,λ, K, H,都是求解的得到的作为已知量,(r3=r1×r2, 这是因为r1,r2,r3两两正交)。 Zhang, Zhengyou. "A flexible new technique for camera calibration." Pattern Analysis and Machine Intelligence, IEEE Transactions on 22.11 (2000): 1330-1334.
25. 求解畸变参数 • OpenCV中使用的求解焦距和偏移的算法是基于张的方法,但求解畸变参数则是另外一个基于 Brown的方法。 • 在通过张正友的方法获得了相机内参矩阵后,求解畸变系数,简单理解就是解方程。利用成像 模型可计算获得“完美”的、符合成像模型的像平面坐标,而根据量测可以获得每一点真实对 应的像平面坐标。由于有5个未知数,因此至少需要3对点(6个方程),便可解出畸变参数。这 就是上面提到的合并后的式子。 • 由完美的“成像模型”可以求解出xcorrected,ycorrected(没有畸变时点应该在的位置),现在因 为有畸变,导致观测到的坐标为x、y。利用上面这个式子便可以求解。这里还有个参数r,这 个r在上面提到是某点到极坐标原点的位置。由于现在内参已知,所以极坐标的原点设为 (x0,y0)就可以知道。又有观测到的x、y,可以算出r。
26. 求解畸变参数
27. Outline • 相机模型 • 坐标系变换 • 畸变模型 • 相机标定 • 张正友标定法 • opencv实验 • 代码 • demo
28. 代码 • 定义objpoints和imgpoints列表,分别存3d和2d点集 • 打开摄像头 • 按‘c’键捕捉图像,判断是否能找到棋盘(1) 。 • 如果可以,进行亚像素角点检测(2);将棋盘的内角点加 入到imgpoints中,同时生成3d点加入到objpoints中;画 (1) 出棋盘内角并展示(3)。 (2) • 直到找到num张合法图像后退出。 (3) • 使用objpoints和imgpoints进行相机标定(4) (4)
29. 代码 (1)findChessboardCorners bool cv::findChessboardCorners( // Return true if corners were found cv::InputArray image, // Input chessboard image, 8UC1 or 8UC3 cv::Size patternSize, // corners per row, and per column cv::OutputArray corners, // Output array of detected corners int flags = cv::CALIB_CB_ADAPTIVE_THRESH cv::CALIB_CB_NORMALIZE_IMAGE ); • 作用:确定输入图像是否是棋盘模式,并确定角点的位置。如果所有角点都被检测到且它 们都被以一定顺序排布,函数返回非零值,否则在函数不能发现所有角点或者记录它们地 情况下,函数返回0。 • note: • 这个函数检测到地坐标只是一个大约的值,如果要精确地确定它们的位置,可以使用 函数cv::FindCornerSubPix。 • 这个函数不能检测到所有图像中的棋盘,所以最好打开摄像头,检测某帧是不是有棋 盘,有的话就存在列表中。
30. 代码 (2)cornerSubPix void cv::cornerSubPix( cv::InputArray image, // Input image cv::InputOutputArray corners, // Guesses in, and results out cv::Size'>cv::Size winSize, // Area is NXN; N=(winSize*2+1) cv::Size'>cv::Size zeroZone, // Size(-1,-1) to ignore cv::TermCriteria criteria // When to stop refinement ); • 作用:对检测到的角点作进一步的优化计算,可使角点的精度达到亚像素级别。 • Note:停止迭代的标准可选的值有cv::TermCriteria::MAX_ITER 、cv::TermCriteria::EPS (可以是两者其一,或两者均选),前者表示迭代次数达到了最大次数时停止,后者表示 角点位置变化的最小值已经达到最小时停止迭代。二者均使用cv::TermCriteria()构造函数 进行指定。
31. 代码 (3)drawChessboardCorners void cv::drawChessboardCorners( cv::InputOutputArray image, // Input/output chessboard image, 8UC3 cv::Size patternSize, // Corners per row, and per column cv::InputArray corners, // corners from findChessboardCorners() bool patternWasFound // Returned from findChessboardCorners() ); • 作用:将检测到的角点画到提供的图像上。如果没有发现所有的角点,那么角点将使用红 色圆圈绘制;如果发现了所有的交点,那么角点将用不同颜色绘制(每行使用单独的颜色 绘制), 并且把角点以一定顺序用线连接起来。
32. 代码 (4)calibrateCamera double cv::calibrateCamera( cv::InputArrayOfArrays'>cv::InputArrayOfArrays objectPoints, // K vecs (N pts each, object frame) cv::InputArrayOfArrays'>cv::InputArrayOfArrays imagePoints, // K vecs (N pts each, image frame) cv::Size imageSize, // Size of input images (pixels) cv::InputOutputArray'>cv::InputOutputArray cameraMatrix, // Resulting 3-by-3 camera matrix cv::InputOutputArray'>cv::InputOutputArray distCoeffs, // Vector of 4, 5, or 8 coefficients cv::OutputArrayOfArrays'>cv::OutputArrayOfArrays rvecs, // Vector of K rotation vectors cv::OutputArrayOfArrays'>cv::OutputArrayOfArrays tvecs, // Vector of K translation vectors int flags = 0, // Flags control calibration options cv::TermCriteria criteria = cv::TermCriteria(cv::TermCriteria::COUNT cv::TermCriteria::EPS, 30, // ...after this many iterations DBL_EPSILON // ...at this total reprojection error ) ); • 作用:相机标定,返回图像的内参/畸变参数/旋转向量/平移向量等。
33. 代码 (5) • 对于相机拍摄的单张图像,求出尺寸。设定 自由尺度参数alpha,生成新的相机矩阵和 ROI(5)。将该图像进行反畸变操作(6), 截取ROI,保存。 (6)
34. 代码 (5)calibrateCamera Mat cv::getOptimalNewCameraMatrix ( InputArray cameraMatrix, //Input camera matrix. InputArray distCoeffs, //Input vector of distortion coefficients Size imageSize, //Original image size. double alpha, // Free scaling parameter between 0 and 1 Size newImgSize = Size(), //Image size after rectification. By default, it is set to imageSize . Rect * validPixROI = 0, bool centerPrincipalPoint = false ); • 作用:在考虑畸变的情况下基于“自由伸缩参数”求取新的相机矩阵。 • Note: 输入参数alpha∈(0,1),调节alpha的值能够控制得到的新矩阵中的fx和fy的大小。alpha = 0.0时: 用此参数undistort后的图片完全没有黑色区域,即所有像素都是有效的;alpha = 1.0时: 用此参数 undistort后的图片保留所有区域,包括黑色区域 原图 alpha = 0 alpha = 1
35. 代码 (6)undistort void cv::undistort ( InputArray OutputArray InputArray InputArray InputArray ); src, //Input (distorted) image. dst, //Output (corrected) image that has the same size and type as src cameraMatrix, //input camera matrix distCoeffs, //Input vector of distortion coefficients newCameraMatrix = noArray() //Camera matrix of the distorted image. • 作用:针对单张图像进行去畸变操作,相当于initUndistortRectifyMap (with unity R ) 和 remap (with bilinear interpolation)两个函数的结合。
36. demo • 拍摄20张不同场景的照片, 计算出相机内参和畸变参数 Camera matrix = [[521.12 [ 0. [ 0. 0. 535.38 299.95] 190.16] 0. 1. ]] Distortion coefficient = [[ 0.2503 -0.1586 0.0252 0.0186 0.46294]]
37. demo • 对图像进行反畸变矫正 矫正前 矫正后