• 1 相机为什么要标定？
• 2 反解相机矩阵
• 3 反解畸变系数
• 4 去畸变原理与实战

# 2 反解相机矩阵

[ u ^ v ^ 1 ] = K [ W C    ⁣ ⁣ ⁣ R C  ⁣ p w 0 ] [ W  ⁣  ⁣ X W  ⁣  ⁣ ⁣  ⁣  Y W  ⁣  ⁣ Z 1 ] \left[ \begin{array}{c} \hat{u}\\ \hat{v}\\ 1\\\end{array} \right] =\boldsymbol{K}\left[ \begin{matrix} _{\boldsymbol{W}}^{\boldsymbol{C}}\;\!\!\!\boldsymbol{R}& ^{\boldsymbol{C}}\!\boldsymbol{p}_{w_0}\\\end{matrix} \right] \left[ \begin{array}{c} ^{\boldsymbol{W}\!}\!X\\ ^{\boldsymbol{W}\!}\!\!\:\!\:Y\\ ^{\boldsymbol{W}\!}\!Z\\ 1\\\end{array} \right]

[ u ^ v ^ 1 ] = K [ r 1 r 2 p ] [ W  ⁣  ⁣ X W  ⁣  ⁣ ⁣  ⁣  Y 1 ] \left[ \begin{array}{c} \hat{u}\\ \hat{v}\\ 1\\\end{array} \right] =\boldsymbol{K}\left[ \begin{matrix} \boldsymbol{r}_1& \boldsymbol{r}_2& \boldsymbol{p}\\\end{matrix} \right] \left[ \begin{array}{c} ^{\boldsymbol{W}\!}\!X\\ ^{\boldsymbol{W}\!}\!\!\:\!\:Y\\ 1\\\end{array} \right]

H = [ h 11 h 12 h 13 h 21 h 22 h 23 h 31 h 32 h 33 ] = [ h 1 h 2 h 3 ] \boldsymbol{H}=\left[ \begin{matrix} h_{11}& h_{12}& h_{13}\\ h_{21}& h_{22}& h_{23}\\ h_{31}& h_{32}& h_{33}\\\end{matrix} \right] =\left[ \begin{matrix} \boldsymbol{h}_1& \boldsymbol{h}_2& \boldsymbol{h}_3\\\end{matrix} \right]

{ h 1 T Q h 2 = 0 h 1 T Q h 1 = h 2 T Q h 2 = 1 \begin{cases} \boldsymbol{h}_{1}^{T}\boldsymbol{Qh}_2=0\\ \boldsymbol{h}_{1}^{T}\boldsymbol{Qh}_1=\boldsymbol{h}_{2}^{T}\boldsymbol{Qh}_2=1\\\end{cases}

h i T Q h j = [ h i 1 h i 2 h i 3 ] [ q 1 q 2 q 3 q 2 q 4 q 5 q 3 q 5 q 6 ] [ h j 1 h j 2 h j 3 ] = v i j T q \boldsymbol{h}_{i}^{T}\boldsymbol{Qh}_j=\left[ \begin{matrix} h_{i1}& h_{i2}& h_{i3}\\\end{matrix} \right] \left[ \begin{matrix} q_1& q_2& q_3\\ q_2& q_4& q_5\\ q_3& q_5& q_6\\\end{matrix} \right] \left[ \begin{array}{c} h_{j1}\\ h_{j2}\\ h_{j3}\\\end{array} \right] \\=\boldsymbol{v}_{ij}^{T}\boldsymbol{q}

[ v 12 T v 11 T − v 22 T ] q = 0 \left[ \begin{array}{c} \boldsymbol{v}_{12}^{T}\\ \boldsymbol{v}_{11}^{T}-\boldsymbol{v}_{22}^{T}\\\end{array} \right] \boldsymbol{q}=0

# 3 反解畸变系数

{ u = f u x + c u v = f v y + c v    { u ^ = f u x ^ + c u v ^ = f v y ^ + c v \begin{cases} u=f_ux+c_u\\ v=f_vy+c_v\\\end{cases}\,\, \begin{cases} \hat{u}=f_u\hat{x}+c_u\\ \hat{v}=f_v\hat{y}+c_v\\\end{cases}

{ x ^ = x ( 1 + κ 1 r 2 + κ 2 r 4 ) y ^ = y ( 1 + κ 1 r 2 + κ 2 r 4 ) \begin{cases} \hat{x}=x\left( 1+\kappa _1r^2+\kappa _2r^4 \right)\\ \hat{y}=y\left( 1+\kappa _1r^2+\kappa _2r^4 \right)\\\end{cases}

[ ( u − c u ) r 2 ( u − c u ) r 4 ( v − c v ) r 2 ( v − c v ) r 4 ] [ κ 1 κ 2 ] = [ u ^ − u v ^ − v ] \left[ \begin{matrix} \left( u-c_u \right) r^2& \left( u-c_u \right) r^4\\ \left( v-c_v \right) r^2& \left( v-c_v \right) r^4\\\end{matrix} \right] \left[ \begin{array}{c} \kappa _1\\ \kappa _2\\\end{array} \right] =\left[ \begin{array}{c} \hat{u}-u\\ \hat{v}-v\\\end{array} \right]

[ u ^ v ^ 1 ] = K [ W C    ⁣ ⁣ ⁣ R C  ⁣ p w 0 ] [ W  ⁣  ⁣ X W  ⁣  ⁣ ⁣  ⁣  Y W  ⁣  ⁣ Z 1 ] \left[ \begin{array}{c} \hat{u}\\ \hat{v}\\ 1\\\end{array} \right] =\boldsymbol{K}\left[ \begin{matrix} _{\boldsymbol{W}}^{\boldsymbol{C}}\;\!\!\!\boldsymbol{R}& ^{\boldsymbol{C}}\!\boldsymbol{p}_{w_0}\\\end{matrix} \right] \left[ \begin{array}{c} ^{\boldsymbol{W}\!}\!X\\ ^{\boldsymbol{W}\!}\!\!\:\!\:Y\\ ^{\boldsymbol{W}\!}\!Z\\ 1\\\end{array} \right]

D 2 M N × 2 κ = d 2 M N × 1 \boldsymbol{D}_{2MN\times 2}\boldsymbol{\kappa }=\boldsymbol{d}_{2MN\times 1}

κ = ( D T D ) − 1 D T d {\boldsymbol{\kappa }=\left( \boldsymbol{D}^T\boldsymbol{D} \right) ^{-1}\boldsymbol{D}^T\boldsymbol{d}}

# 4 去畸变原理与实战

• 准备张氏标定法的标准棋盘格，用相机对其进行不同角度拍摄，得到一组图像
• 忽略畸变，每张标定板可通过世界坐标与像素坐标的关系，求解二者间的单应性矩阵，用于反解相机内参矩阵；忽略切向畸变与内参矩阵误差，反解径向畸变参数
• 利用L-M(Levenberg Marquardt)等非线性迭代优化算法对上述参数进行优化，得到最终的内参矩阵与畸变参数。

/*
* @breif:采用张氏标定法标定相机并生成标定文件.txt
* @param[in]:folderPath->标定板图像集的文件夹路径;
* @param[in]:boardSize->标定板上每行、列的内角点数;
* @param[in]:realSizePerBox->实际测量的标定板棋盘格几何尺寸，与相机矩阵单位pix/mm对应，Unit:mm;
* @param[in]:savePath->标定文件.txt的保存路径;
* @retval:None
*/
void cameraCalibration(String folderPath, Size boardSize, Size realSizePerBox, String savePath)
{
std::vector<cv::String> fileNames;						// 存放标定图片文件名的序列
cv::glob(folderPath, fileNames);						// 将标定文件夹中的文件名读取到序列

Mat cameraMatrix = Mat(3, 3, CV_32FC1, Scalar::all(0)); // 像机内参矩阵
Mat distCoeffs = Mat(1, 5, CV_32FC1, Scalar::all(0));	// 像机畸变系数：k1,k2,p1,p2,k3
vector<Mat> tvecsMat;									// 相机外参->旋转向量
vector<Mat> rvecsMat;									// 相机外参->平移向量
int imgCnt = 0;											// 图像数量
vector<int> ptCnt;										// 图像中角点的数量
Size imgSize;											// 图像尺寸
vector<Point2f> imgPtBuffer;							// 缓存每幅图像上检测到的角点
vector<vector<Point2f>> imgPtSequence;					// 检测到的所有角点序列，Unit:pix
vector<vector<Point3f>> realImgPtSequence;				// 检测到的所有角点序列，Unit:mm
double totalErr = 0.0;									// 所有图像的重投影误差和

/*========================================= 像素平面角点坐标提取 =========================================================*/
for (size_t i = 0; i < fileNames.size(); ++i)
{
imgCnt++;
printf("read the number %d image\n", i+1);
Mat imgInput = imread(fileNames[i]);
ptCnt.push_back(boardSize.width * boardSize.height);	// 初始化每幅图像中的角点数量，假定每幅图像中都可看到完整标定板

if (imgCnt == 1)								//读入第一张图片时获取图像宽高信息
{
imgSize.width = imgInput.cols;
imgSize.height = imgInput.rows;
}

if (findChessboardCorners(imgInput, boardSize, imgPtBuffer) == 0)	// 提取ChessBoard类型角点
{
printf("can't find the corner point of image number %d, please check!\n", i);
return;
}
else
{
Mat imgGray;
cvtColor(imgInput, imgGray, CV_RGB2GRAY);	//图像灰度化
find4QuadCornerSubpix(imgGray, imgPtBuffer, Size(11, 11));		//对粗提取的角点进行亚像素精确化
imgPtSequence.push_back(imgPtBuffer);
}
}

/*========================================= 几何平面角点坐标提取 =========================================================*/
for (int i = 0; i < imgCnt; i++)
{
vector<Point3f> tempPtSetPerImg;
for (int j = 0; j < boardSize.height; j++)
{
for (int k = 0; k < boardSize.width; k++)
{
Point3f realPoint;
realPoint.x = j * realSizePerBox.width;
realPoint.y = k * realSizePerBox.height;
realPoint.z = 0;						// 张氏标定法假设标定板放在世界坐标系中z=0的平面上
tempPtSetPerImg.push_back(realPoint);
}
}
realImgPtSequence.push_back(tempPtSetPerImg);
}

/*======================================== 相机标定与重投影误差计算 ======================================================*/
calibrateCamera(realImgPtSequence, imgPtSequence, imgSize, cameraMatrix, distCoeffs, rvecsMat, tvecsMat);
totalErr = calReprojectErr(realImgPtSequence, imgPtSequence, rvecsMat, tvecsMat, cameraMatrix, distCoeffs, ptCnt);
}


0                              色彩空间与数字成像
1                              计算机几何基础
2                              图像增强、滤波、金字塔
3                              图像特征提取
4                              图像特征描述
5                              图像特征匹配
6                              立体视觉
7                              项目实战

• 《机器人原理与技术》
• 《计算机视觉教程》
• 《机器学习》
• 《嵌入式系统》
• 《数值优化方法》