版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u012348774/article/details/83746706
以下均为简单笔记,如有错误,请多多指教。
- 寻找一部相机标定它的内参。你可能会用到标定板,或者自己打印一张标定用的棋盘格。
解: 本次试验标定对象是iPhone 6 前置摄像头(可能并不会特别准),标定板使用了棋盘格,标定程序使用的是opencv自带的工具camera_calibration。提前说明一下,一下操作仅仅是示意,其结果不一定准确。
步骤一:生成棋盘格,考虑到打印棋盘格较为复杂,本文选择直接在显示屏上显示棋盘格进而进行标定。以下分别是代码和全屏显示的棋盘格。使用直尺测量即可得到棋盘格子的大小,在本人的屏幕上的大小为0.0327m。
#include <iostream>
#include <opencv2/opencv.hpp>
int main()
{
int board_size = 120;
cv::Mat image = cv::Mat::ones(1080,1920,CV_8UC1)*255;
for( int y=0; y<image.rows; y++ )
{
for( int x=0; x<image.cols; x++ )
{
int xx = (x/120);
int yy = (y/120);
if( xx==0 || yy==0 || xx==15 || yy==8)
continue;
if( (xx+yy)%2==0 )
image.at<uchar>(y,x) = 0;
else
image.at<uchar>(y,x) = 255;
}
}
cv::imwrite("chess.png",image);
return 0;
}
步骤二:采集棋盘格数据,需要注意的是需要采集各个角度的数据,尽可能保证相机的整个画面都被完全覆盖。另外必须要防止相机出现较大角度的旋转,因为棋盘格并没有方向性。下图是本文采集数据的缩略图。
步骤三:使用标定程序,首先需要修改两个配置文件in_VID5.xml和VID5.xml,其中分别记录了一些必要的参数。
in_VID5.xml。
<?xml version="1.0"?>
<opencv_storage>
<Settings>
<!-- 棋盘格数目 -->
<BoardSize_Width> 13</BoardSize_Width> //此处
<BoardSize_Height>6</BoardSize_Height> //此处
<!-- 棋盘格大小-->
<Square_Size>0.0327</Square_Size> //此处
<!-- 棋盘格类型 -->
<Calibrate_Pattern>"CHESSBOARD"</Calibrate_Pattern>
<!-- 相机文件-->
<Input>"iVID5.xml"</Input>
<!-- 是否水平翻转 -->
<Input_FlipAroundHorizontalAxis>0</Input_FlipAroundHorizontalAxis>
<!-- 视频帧之间的时间间隔 -->
<Input_Delay>100</Input_Delay>
<!-- 文件数量 -->
<Calibrate_NrOfFrameToUse>27</Calibrate_NrOfFrameToUse>
<!-- 是否固定fx/fy -->
<Calibrate_FixAspectRatio> 1 </Calibrate_FixAspectRatio>
<!-- 是否标定切向畸变 -->
<Calibrate_AssumeZeroTangentialDistortion>1</Calibrate_AssumeZeroTangentialDistortion>
<!-- 是否标定主点 -->
<Calibrate_FixPrincipalPointAtTheCenter>0</Calibrate_FixPrincipalPointAtTheCenter>
<!-- 输出文件 -->
<Write_outputFileName>"out_camera_data.xml"</Write_outputFileName>
<Write_DetectedFeaturePoints>1</Write_DetectedFeaturePoints>
<Write_extrinsicParameters>1</Write_extrinsicParameters>
<!-- 展示结果 -->
<Show_UndistortedImage>1</Show_UndistortedImage>
<!-- 是否使用鱼眼模型 -->
<Calibrate_UseFisheyeModel>0</Calibrate_UseFisheyeModel>
<!-- k1,k2,k3,k4,k5是否需要表达,为0表示需要标定 -->
<Fix_K1>0</Fix_K1>
<Fix_K2>0</Fix_K2>
<Fix_K3>1</Fix_K3>
<Fix_K4>1</Fix_K4>
<Fix_K5>1</Fix_K5>
</Settings>
</opencv_storage>
VID5.xml
<?xml version="1.0"?>
<opencv_storage>
<images>
IMG_3756.JPG
IMG_3757.JPG
IMG_3758.JPG
IMG_3759.JPG
IMG_3760.JPG
IMG_3761.JPG
IMG_3762.JPG
IMG_3763.JPG
IMG_3764.JPG
IMG_3765.JPG
IMG_3766.JPG
IMG_3767.JPG
IMG_3768.JPG
IMG_3769.JPG
IMG_3770.JPG
IMG_3771.JPG
IMG_3772.JPG
IMG_3773.JPG
IMG_3774.JPG
IMG_3775.JPG
IMG_3776.JPG
IMG_3777.JPG
IMG_3778.JPG
IMG_3779.JPG
IMG_3780.JPG
IMG_3781.JPG
IMG_3782.JPG
</images>
</opencv_storage>
步骤四:运行标定程序。下图是自动提取棋盘角点的示意图。
等待程序完成运行后就完成了相机标定,其结果如下:
<image_width>3264</image_width>
<image_height>2448</image_height>
<board_width>13</board_width>
<board_height>6</board_height>
<square_size>3.2699998468160629e-002</square_size>
<!-- flags: +zero_tangent_dist +fix_k3 +fix_k4 +fix_k5 -->
<flags>6280</flags>
<fisheye_model>0</fisheye_model>
<camera_matrix type_id="opencv-matrix">
<rows>3</rows>
<cols>3</cols>
<dt>d</dt>
<data>
2.8213430553262237e+003 0. 1.6229846317743772e+003 0.
2.8221514531174835e+003 1.2255033995279327e+003 0. 0. 1.</data></camera_matrix>
<distortion_coefficients type_id="opencv-matrix">
<rows>5</rows>
<cols>1</cols>
<dt>d</dt>
<data>
1.0641876997619698e-001 -3.2296717555656707e-001 0. 0. 0.</data></distortion_coefficients>
<avg_reprojection_error>1.7169779069132207e+000</avg_reprojection_error>
2. 叙述相机内参的物理意义。如果一部相机的分辨率变为原来的两倍而其他地方不变,它的内参如何变化?
答:常见的相机的内参有焦距、主点、径向畸变和切向畸变。焦距描述的是投影中心到成像平面的距离,主点描述的是主光轴在成像平面上的角点,径向畸变是由镜片形状不规则引起的畸变,切向畸变则是由于镜片不完全与成像平面平行导致的。
考虑如果一部相机的分辨率变为原来的两倍,直接从公式就可以知道径向畸变和切向畸变并不会发生变化,而焦距和主点会变大一倍。