张正友相机标定Opencv实现以及标定流程&&标定结果评价&&图像矫正流程解析(附标定程序和棋盘图)

张正友相机标定Opencv实现以及标定流程&&标定结果评价&&图像矫正流程解析(附标定程序和棋盘图)

原创 2016年10月27日 01:09:24
        <ul class="article_tags clearfix csdn-tracking-statistics" data-mod="popu_377">
            <li class="tit">标签:</li>



使用Opencv实现张正友法相机标定之前,有几个问题事先要确认一下,那就是相机为什么需要标定,标定需要的输入和输出分别是哪些?


相机标定的目的:获取摄像机的内参和外参矩阵(同时也会得到每一幅标定图像的选择和平移矩阵),内参和外参系数可以对之后相机拍摄的图像就进行矫正,得到畸变相对很小的图像。

相机标定的输入:标定图像上所有内角点的图像坐标,标定板图像上所有内角点的空间三维坐标(一般情况下假定图像位于Z=0平面上)。

相机标定的输出:摄像机的内参、外参系数。


这三个基础的问题就决定了使用Opencv实现张正友法标定相机的标定流程、标定结果评价以及使用标定结果矫正原始图像的完整流程:


1. 准备标定图片

2. 对每一张标定图片,提取角点信息

3. 对每一张标定图片,进一步提取亚像素角点信息

4. 在棋盘标定图上绘制找到的内角点(非必须,仅为了显示)

5. 相机标定

6. 对标定结果进行评价

7. 查看标定效果——利用标定结果对棋盘图进行矫正


1. 准备标定图片


标定图片需要使用标定板在不同位置、不同角度、不同姿态下拍摄,最少需要3张,以10~20张为宜。标定板需要是黑白相间的矩形构成的棋盘图,制作精度要求较高,如下图所示:





2.对每一张标定图片,提取角点信息


需要使用findChessboardCorners函数提取角点,这里的角点专指的是标定板上的内角点,这些角点与标定板的边缘不接触。

 findChessboardCorners函数原型:

  1. //! finds checkerboard pattern of the specified size in the image  
  2. CV_EXPORTS_W bool findChessboardCorners( InputArray image, Size patternSize,  
  3.                                          OutputArray corners,  
  4.                                          int flags=CALIB_CB_ADAPTIVE_THRESH+CALIB_CB_NORMALIZE_IMAGE );  
//! finds checkerboard pattern of the specified size in the image
CV_EXPORTS_W bool findChessboardCorners( InputArray image, Size patternSize,
                                         OutputArray corners,
                                         int flags=CALIB_CB_ADAPTIVE_THRESH+CALIB_CB_NORMALIZE_IMAGE );


第一个参数Image,传入拍摄的棋盘图Mat图像,必须是8位的灰度或者彩色图像;

第二个参数patternSize,每个棋盘图上内角点的行列数,一般情况下,行列数不要相同,便于后续标定程序识别标定板的方向;

第三个参数corners,用于存储检测到的内角点图像坐标位置,一般用元素是Point2f的向量来表示:vector<Point2f> image_points_buf;

第四个参数flage:用于定义棋盘图上内角点查找的不同处理方式,有默认值。



3. 对每一张标定图片,进一步提取亚像素角点信息


为了提高标定精度,需要在初步提取的角点信息上进一步提取亚像素信息,降低相机标定偏差,常用的方法是cornerSubPix,另一个方法是使用find4QuadCornerSubpix函数,这个方法是专门用来获取棋盘图上内角点的精确位置的,或许在相机标定的这个特殊场合下它的检测精度会比cornerSubPix更高?

cornerSubPix函数原型:

  1. //! adjusts the corner locations with sub-pixel accuracy to maximize the certain cornerness criteria  
  2. CV_EXPORTS_W void cornerSubPix( InputArray image, InputOutputArray corners,  
  3.                                 Size winSize, Size zeroZone,  
  4.                                 TermCriteria criteria );  
//! adjusts the corner locations with sub-pixel accuracy to maximize the certain cornerness criteria
CV_EXPORTS_W void cornerSubPix( InputArray image, InputOutputArray corners,
                                Size winSize, Size zeroZone,
                                TermCriteria criteria );

第一个参数image,输入的Mat矩阵,最好是8位灰度图像,检测效率更高;

第二个参数corners,初始的角点坐标向量,同时作为亚像素坐标位置的输出,所以需要是浮点型数据,一般用元素是Pointf2f/Point2d的向量来表示:vector<Point2f/Point2d> iamgePointsBuf;

第三个参数winSize,大小为搜索窗口的一半;

第四个参数zeroZone,死区的一半尺寸,死区为不对搜索区的中央位置做求和运算的区域。它是用来避免自相关矩阵出现某些可能的奇异性。当值为(-1,-1)时表示没有死区;

第五个参数criteria,定义求角点的迭代过程的终止条件,可以为迭代次数和角点精度两者的组合;

find4QuadCornerSubpix函数原型:

  1. //! finds subpixel-accurate positions of the chessboard corners  
  2. CV_EXPORTS bool find4QuadCornerSubpix(InputArray img, InputOutputArray corners, Size region_size);  
//! finds subpixel-accurate positions of the chessboard corners
CV_EXPORTS bool find4QuadCornerSubpix(InputArray img, InputOutputArray corners, Size region_size);

第一个参数img,输入的Mat矩阵,最好是8位灰度图像,检测效率更高;

第二个参数corners,初始的角点坐标向量,同时作为亚像素坐标位置的输出,所以需要是浮点型数据,一般用元素是Pointf2f/Point2d的向量来表示:vector<Point2f/Point2d> iamgePointsBuf;

第三个参数region_size,角点搜索窗口的尺寸;

在其中一个标定的棋盘图上分别运行cornerSubPix和find4QuadCornerSubpix寻找亚像素角点,两者定位到的亚像素角点坐标分别为:


   cornerSubPix:                                                 find4QuadCornerSubpix:

                       


虽然有一定差距,但偏差基本都控制在0.5个像素之内。



4. 在棋盘标定图上绘制找到的内角点(非必须,仅为了显示)



drawChessboardCorners函数用于绘制被成功标定的角点,函数原型:


  1. //! draws the checkerboard pattern (found or partly found) in the image  
  2. CV_EXPORTS_W void drawChessboardCorners( InputOutputArray image, Size patternSize,  
  3.                                          InputArray corners, bool patternWasFound );  
//! draws the checkerboard pattern (found or partly found) in the image
CV_EXPORTS_W void drawChessboardCorners( InputOutputArray image, Size patternSize,
                                         InputArray corners, bool patternWasFound );

第一个参数image,8位灰度或者彩色图像;

第二个参数patternSize,每张标定棋盘上内角点的行列数;

第三个参数corners,初始的角点坐标向量,同时作为亚像素坐标位置的输出,所以需要是浮点型数据,一般用元素是Pointf2f/Point2d的向量来表示:vector<Point2f/Point2d> iamgePointsBuf;

第四个参数patternWasFound,标志位,用来指示定义的棋盘内角点是否被完整的探测到,true表示别完整的探测到,函数会用直线依次连接所有的内角点,作为一个整体,false表示有未被探测到的内角点,这时候函数会以(红色)圆圈标记处检测到的内角点;

以下是drawChessboardCorners函数中第四个参数patternWasFound设置为true和false时内角点的绘制效果:

patternWasFound=ture时,依次连接各个内角点:




patternWasFound=false时,以(红色)圆圈标记处角点位置:




5. 相机标定



获取到棋盘标定图的内角点图像坐标之后,就可以使用calibrateCamera函数进行标定,计算相机内参和外参系数,

calibrateCamera函数原型:

  1. //! finds intrinsic and extrinsic camera parameters from several fews of a known calibration pattern.  
  2. CV_EXPORTS_W double calibrateCamera( InputArrayOfArrays objectPoints,  
  3.                                      InputArrayOfArrays imagePoints,  
  4.                                      Size imageSize,  
  5.                                      CV_OUT InputOutputArray cameraMatrix,  
  6.                                      CV_OUT InputOutputArray distCoeffs,  
  7.                                      OutputArrayOfArrays rvecs, OutputArrayOfArrays tvecs,  
  8.                                      int flags=0, TermCriteria criteria = TermCriteria(  
  9.                                          TermCriteria::COUNT+TermCriteria::EPS, 30, DBL_EPSILON) );  
//! finds intrinsic and extrinsic camera parameters from several fews of a known calibration pattern.
CV_EXPORTS_W double calibrateCamera( InputArrayOfArrays objectPoints,
                                     InputArrayOfArrays imagePoints,
                                     Size imageSize,
                                     CV_OUT InputOutputArray cameraMatrix,
                                     CV_OUT InputOutputArray distCoeffs,
                                     OutputArrayOfArrays rvecs, OutputArrayOfArrays tvecs,
                                     int flags=0, TermCriteria criteria = TermCriteria(
                                         TermCriteria::COUNT+TermCriteria::EPS, 30, DBL_EPSILON) );

第一个参数objectPoints,为世界坐标系中的三维点。在使用时,应该输入一个三维坐标点的向量的向量,即vector<vector<Point3f>> object_points。需要依据棋盘上单个黑白矩阵的大小,计算出(初始化)每一个内角点的世界坐标。

第二个参数imagePoints,为每一个内角点对应的图像坐标点。和objectPoints一样,应该输入vector<vector<Point2f>> image_points_seq形式的变量;

第三个参数imageSize,为图像的像素尺寸大小,在计算相机的内参和畸变矩阵时需要使用到该参数;

第四个参数cameraMatrix为相机的内参矩阵。输入一个Mat cameraMatrix即可,如Mat cameraMatrix=Mat(3,3,CV_32FC1,Scalar::all(0));

第五个参数distCoeffs为畸变矩阵。输入一个Mat distCoeffs=Mat(1,5,CV_32FC1,Scalar::all(0))即可;

第六个参数rvecs为旋转向量;应该输入一个Mat类型的vector,即vector<Mat>rvecs;

第七个参数tvecs为位移向量,和rvecs一样,应该为vector<Mat> tvecs;

第八个参数flags为标定时所采用的算法。有如下几个参数:

CV_CALIB_USE_INTRINSIC_GUESS:使用该参数时,在cameraMatrix矩阵中应该有fx,fy,u0,v0的估计值。否则的话,将初始化(u0,v0)图像的中心点,使用最小二乘估算出fx,fy。 
CV_CALIB_FIX_PRINCIPAL_POINT:在进行优化时会固定光轴点。当CV_CALIB_USE_INTRINSIC_GUESS参数被设置,光轴点将保持在中心或者某个输入的值。 
CV_CALIB_FIX_ASPECT_RATIO:固定fx/fy的比值,只将fy作为可变量,进行优化计算。当CV_CALIB_USE_INTRINSIC_GUESS没有被设置,fx和fy将会被忽略。只有fx/fy的比值在计算中会被用到。 
CV_CALIB_ZERO_TANGENT_DIST:设定切向畸变参数(p1,p2)为零。 
CV_CALIB_FIX_K1,…,CV_CALIB_FIX_K6:对应的径向畸变在优化中保持不变。 
CV_CALIB_RATIONAL_MODEL:计算k4,k5,k6三个畸变参数。如果没有设置,则只计算其它5个畸变参数。

第九个参数criteria是最优迭代终止条件设定。

在使用该函数进行标定运算之前,需要对棋盘上每一个内角点的空间坐标系的位置坐标进行初始化,标定的结果是生成相机的内参矩阵cameraMatrix、相机的5个畸变系数distCoeffs,另外每张图像都会生成属于自己的平移向量和旋转向量。



6. 对标定结果进行评价



对标定结果进行评价的方法是通过得到的摄像机内外参数,对空间的三维点进行重新投影计算,得到空间三维点在图像上新的投影点的坐标,计算投影坐标和亚像素角点坐标之间的偏差,偏差越小,标定结果越好。

对空间三维坐标点进行反向投影的函数是projectPoints,函数原型是:

  1. //! projects points from the model coordinate space to the image coordinates. Also computes derivatives of the image coordinates w.r.t the intrinsic and extrinsic camera parameters  
  2. CV_EXPORTS_W void projectPoints( InputArray objectPoints,  
  3.                                  InputArray rvec, InputArray tvec,  
  4.                                  InputArray cameraMatrix, InputArray distCoeffs,  
  5.                                  OutputArray imagePoints,  
  6.                                  OutputArray jacobian=noArray(),  
  7.                                  double aspectRatio=0 );  
//! projects points from the model coordinate space to the image coordinates. Also computes derivatives of the image coordinates w.r.t the intrinsic and extrinsic camera parameters
CV_EXPORTS_W void projectPoints( InputArray objectPoints,
                                 InputArray rvec, InputArray tvec,
                                 InputArray cameraMatrix, InputArray distCoeffs,
                                 OutputArray imagePoints,
                                 OutputArray jacobian=noArray(),
                                 double aspectRatio=0 );


第一个参数objectPoints,为相机坐标系中的三维点坐标;

第二个参数rvec为旋转向量,每一张图像都有自己的选择向量;

第三个参数tvec为位移向量,每一张图像都有自己的平移向量;

第四个参数cameraMatrix为求得的相机的内参数矩阵;

第五个参数distCoeffs为相机的畸变矩阵;

第六个参数iamgePoints为每一个内角点对应的图像上的坐标点;

第七个参数jacobian是雅可比行列式;

第八个参数aspectRatio是跟相机传感器的感光单元有关的可选参数,如果设置为非0,则函数默认感光单元的dx/dy是固定的,会依此对雅可比矩阵进行调整;

下边显示了某一张标定图片上的亚像素角点坐标和根据标定结果把空间三维坐标点映射回图像坐标点的对比:


find4QuadCornerSubpix查找到的亚像素点坐标:                           projectPoints映射的坐标:

                                                     


以下是每一幅图像上24个内角点的平均误差统计数据:




7. 查看标定效果——利用标定结果对棋盘图进行矫正



利用求得的相机的内参和外参数据,可以对图像进行畸变的矫正,这里有两种方法可以达到矫正的目的,分别说明一下。

方法一:使用initUndistortRectifyMap和remap两个函数配合实现。

initUndistortRectifyMap用来计算畸变映射,remap把求得的映射应用到图像上。

initUndistortRectifyMap的函数原型:

  1. //! initializes maps for cv::remap() to correct lens distortion and optionally rectify the image  
  2. CV_EXPORTS_W void initUndistortRectifyMap( InputArray cameraMatrix, InputArray distCoeffs,  
  3.                            InputArray R, InputArray newCameraMatrix,  
  4.                            Size size, int m1type, OutputArray map1, OutputArray map2 );  
//! initializes maps for cv::remap() to correct lens distortion and optionally rectify the image
CV_EXPORTS_W void initUndistortRectifyMap( InputArray cameraMatrix, InputArray distCoeffs,
                           InputArray R, InputArray newCameraMatrix,
                           Size size, int m1type, OutputArray map1, OutputArray map2 );

第一个参数cameraMatrix为之前求得的相机的内参矩阵;

第二个参数distCoeffs为之前求得的相机畸变矩阵;

第三个参数R,可选的输入,是第一和第二相机坐标之间的旋转矩阵;

第四个参数newCameraMatrix,输入的校正后的3X3摄像机矩阵;

第五个参数size,摄像机采集的无失真的图像尺寸;

第六个参数m1type,定义map1的数据类型,可以是CV_32FC1或者CV_16SC2;

第七个参数map1和第八个参数map2,输出的X/Y坐标重映射参数;


remap函数原型:

  1. //! warps the image using the precomputed maps. The maps are stored in either floating-point or integer fixed-point format  
  2. CV_EXPORTS_W void remap( InputArray src, OutputArray dst,  
  3.                          InputArray map1, InputArray map2,  
  4.                          int interpolation, int borderMode=BORDER_CONSTANT,  
  5.                          const Scalar& borderValue=Scalar());  
//! warps the image using the precomputed maps. The maps are stored in either floating-point or integer fixed-point format
CV_EXPORTS_W void remap( InputArray src, OutputArray dst,
                         InputArray map1, InputArray map2,
                         int interpolation, int borderMode=BORDER_CONSTANT,
                         const Scalar& borderValue=Scalar());

第一个参数src,输入参数,代表畸变的原始图像;

第二个参数dst,矫正后的输出图像,跟输入图像具有相同的类型和大小;

第三个参数map1和第四个参数map2,X坐标和Y坐标的映射;

第五个参数interpolation,定义图像的插值方式;

第六个参数borderMode,定义边界填充方式;


方法二:使用undistort函数实现

undistort函数原型:

  1. //! corrects lens distortion for the given camera matrix and distortion coefficients  
  2. CV_EXPORTS_W void undistort( InputArray src, OutputArray dst,  
  3.                              InputArray cameraMatrix,  
  4.                              InputArray distCoeffs,  
  5.                              InputArray newCameraMatrix=noArray() );  
//! corrects lens distortion for the given camera matrix and distortion coefficients
CV_EXPORTS_W void undistort( InputArray src, OutputArray dst,
                             InputArray cameraMatrix,
                             InputArray distCoeffs,
                             InputArray newCameraMatrix=noArray() );

第一个参数src,输入参数,代表畸变的原始图像;

第二个参数dst,矫正后的输出图像,跟输入图像具有相同的类型和大小;

第三个参数cameraMatrix为之前求得的相机的内参矩阵;

第四个参数distCoeffs为之前求得的相机畸变矩阵;

第五个参数newCameraMatrix,默认跟cameraMatrix保持一致;

方法一相比方法二执行效率更高一些,推荐使用。


以下是使用某一张标定图使用方法一和方法二进行矫正的效果图对比。

原始标定图像:



方法一,使用initUndistortRectifyMap和remap实现矫正效果:



方法二,使用undistort函数实现矫正效果:



两个方法从矫正效果上看,结果是一致的。


以下是完整的工程代码:


  1. #include “opencv2/core/core.hpp”  
  2. #include “opencv2/imgproc/imgproc.hpp”  
  3. #include “opencv2/calib3d/calib3d.hpp”  
  4. #include “opencv2/highgui/highgui.hpp”  
  5. #include <iostream>  
  6. #include <fstream>  
  7.   
  8. using namespace cv;  
  9. using namespace std;  
  10.   
  11. void main()   
  12. {  
  13.     ifstream fin(”calibdata.txt”); /* 标定所用图像文件的路径 */  
  14.     ofstream fout(”caliberation_result.txt”);  /* 保存标定结果的文件 */    
  15.     //读取每一幅图像,从中提取出角点,然后对角点进行亚像素精确化   
  16.     cout<<”开始提取角点………………”;  
  17.     int image_count=0;  /* 图像数量 */  
  18.     Size image_size;  /* 图像的尺寸 */  
  19.     Size board_size = Size(4,6);    /* 标定板上每行、列的角点数 */  
  20.     vector<Point2f> image_points_buf;  /* 缓存每幅图像上检测到的角点 */  
  21.     vector<vector<Point2f>> image_points_seq; /* 保存检测到的所有角点 */  
  22.     string filename;  
  23.     int count= -1 ;//用于存储角点个数。  
  24.     while (getline(fin,filename))  
  25.     {  
  26.         image_count++;        
  27.         // 用于观察检验输出  
  28.         cout<<”image_count = ”<<image_count<<endl;          
  29.         /* 输出检验*/  
  30.         cout<<”–>count = ”<<count;        
  31.         Mat imageInput=imread(filename);  
  32.         if (image_count == 1)  //读入第一张图片时获取图像宽高信息  
  33.         {  
  34.             image_size.width = imageInput.cols;  
  35.             image_size.height =imageInput.rows;           
  36.             cout<<”image_size.width = ”<<image_size.width<<endl;  
  37.             cout<<”image_size.height = ”<<image_size.height<<endl;  
  38.         }  
  39.   
  40.         /* 提取角点 */  
  41.         if (0 == findChessboardCorners(imageInput,board_size,image_points_buf))  
  42.         {             
  43.             cout<<”can not find chessboard corners!\n”//找不到角点  
  44.             exit(1);  
  45.         }   
  46.         else   
  47.         {  
  48.             Mat view_gray;  
  49.             cvtColor(imageInput,view_gray,CV_RGB2GRAY);  
  50.             /* 亚像素精确化 */  
  51.             find4QuadCornerSubpix(view_gray,image_points_buf,Size(5,5)); //对粗提取的角点进行精确化  
  52.             //cornerSubPix(view_gray,image_points_buf,Size(5,5),Size(-1,-1),TermCriteria(CV_TERMCRIT_EPS+CV_TERMCRIT_ITER,30,0.1));  
  53.             image_points_seq.push_back(image_points_buf);  //保存亚像素角点  
  54.             /* 在图像上显示角点位置 */  
  55.             drawChessboardCorners(view_gray,board_size,image_points_buf,false); //用于在图片中标记角点  
  56.             imshow(”Camera Calibration”,view_gray);//显示图片  
  57.             waitKey(500);//暂停0.5S         
  58.         }  
  59.     }  
  60.     int total = image_points_seq.size();  
  61.     cout<<”total = ”<<total<<endl;  
  62.     int CornerNum=board_size.width*board_size.height;  //每张图片上总的角点数  
  63.     for (int ii=0 ; ii<total ;ii++)  
  64.     {  
  65.         if (0 == ii%CornerNum)// 24 是每幅图片的角点个数。此判断语句是为了输出 图片号,便于控制台观看   
  66.         {     
  67.             int i = -1;  
  68.             i = ii/CornerNum;  
  69.             int j=i+1;  
  70.             cout<<”–> 第 ”<<j <<“图片的数据 –> : ”<<endl;  
  71.         }  
  72.         if (0 == ii%3)  // 此判断语句,格式化输出,便于控制台查看  
  73.         {  
  74.             cout<<endl;  
  75.         }  
  76.         else  
  77.         {  
  78.             cout.width(10);  
  79.         }  
  80.         //输出所有的角点  
  81.         cout<<” –>”<<image_points_seq[ii][0].x;  
  82.         cout<<” –>”<<image_points_seq[ii][0].y;  
  83.     }     
  84.     cout<<”角点提取完成!\n”;  
  85.   
  86.     //以下是摄像机标定  
  87.     cout<<”开始标定………………”;  
  88.     /*棋盘三维信息*/  
  89.     Size square_size = Size(10,10);  /* 实际测量得到的标定板上每个棋盘格的大小 */  
  90.     vector<vector<Point3f>> object_points; /* 保存标定板上角点的三维坐标 */  
  91.     /*内外参数*/  
  92.     Mat cameraMatrix=Mat(3,3,CV_32FC1,Scalar::all(0)); /* 摄像机内参数矩阵 */  
  93.     vector<int> point_counts;  // 每幅图像中角点的数量  
  94.     Mat distCoeffs=Mat(1,5,CV_32FC1,Scalar::all(0)); /* 摄像机的5个畸变系数:k1,k2,p1,p2,k3 */  
  95.     vector<Mat> tvecsMat;  /* 每幅图像的旋转向量 */  
  96.     vector<Mat> rvecsMat; /* 每幅图像的平移向量 */  
  97.     /* 初始化标定板上角点的三维坐标 */  
  98.     int i,j,t;  
  99.     for (t=0;t<image_count;t++)   
  100.     {  
  101.         vector<Point3f> tempPointSet;  
  102.         for (i=0;i<board_size.height;i++)   
  103.         {  
  104.             for (j=0;j<board_size.width;j++)   
  105.             {  
  106.                 Point3f realPoint;  
  107.                 /* 假设标定板放在世界坐标系中z=0的平面上 */  
  108.                 realPoint.x = i*square_size.width;  
  109.                 realPoint.y = j*square_size.height;  
  110.                 realPoint.z = 0;  
  111.                 tempPointSet.push_back(realPoint);  
  112.             }  
  113.         }  
  114.         object_points.push_back(tempPointSet);  
  115.     }  
  116.     /* 初始化每幅图像中的角点数量,假定每幅图像中都可以看到完整的标定板 */  
  117.     for (i=0;i<image_count;i++)  
  118.     {  
  119.         point_counts.push_back(board_size.width*board_size.height);  
  120.     }     
  121.     /* 开始标定 */  
  122.     calibrateCamera(object_points,image_points_seq,image_size,cameraMatrix,distCoeffs,rvecsMat,tvecsMat,0);  
  123.     cout<<”标定完成!\n”;  
  124.     //对标定结果进行评价  
  125.     cout<<”开始评价标定结果………………\n”;  
  126.     double total_err = 0.0; /* 所有图像的平均误差的总和 */  
  127.     double err = 0.0; /* 每幅图像的平均误差 */  
  128.     vector<Point2f> image_points2; /* 保存重新计算得到的投影点 */  
  129.     cout<<”\t每幅图像的标定误差:\n”;  
  130.     fout<<”每幅图像的标定误差:\n”;  
  131.     for (i=0;i<image_count;i++)  
  132.     {  
  133.         vector<Point3f> tempPointSet=object_points[i];  
  134.         /* 通过得到的摄像机内外参数,对空间的三维点进行重新投影计算,得到新的投影点 */  
  135.         projectPoints(tempPointSet,rvecsMat[i],tvecsMat[i],cameraMatrix,distCoeffs,image_points2);  
  136.         /* 计算新的投影点和旧的投影点之间的误差*/  
  137.         vector<Point2f> tempImagePoint = image_points_seq[i];  
  138.         Mat tempImagePointMat = Mat(1,tempImagePoint.size(),CV_32FC2);  
  139.         Mat image_points2Mat = Mat(1,image_points2.size(), CV_32FC2);  
  140.         for (int j = 0 ; j < tempImagePoint.size(); j++)  
  141.         {  
  142.             image_points2Mat.at<Vec2f>(0,j) = Vec2f(image_points2[j].x, image_points2[j].y);  
  143.             tempImagePointMat.at<Vec2f>(0,j) = Vec2f(tempImagePoint[j].x, tempImagePoint[j].y);  
  144.         }  
  145.         err = norm(image_points2Mat, tempImagePointMat, NORM_L2);  
  146.         total_err += err/=  point_counts[i];     
  147.         std::cout<<”第”<<i+1<<“幅图像的平均误差:”<<err<<“像素”<<endl;     
  148.         fout<<”第”<<i+1<<“幅图像的平均误差:”<<err<<“像素”<<endl;     
  149.     }     
  150.     std::cout<<”总体平均误差:”<<total_err/image_count<<“像素”<<endl;     
  151.     fout<<”总体平均误差:”<<total_err/image_count<<“像素”<<endl<<endl;     
  152.     std::cout<<”评价完成!”<<endl;    
  153.     //保存定标结果      
  154.     std::cout<<”开始保存定标结果………………”<<endl;         
  155.     Mat rotation_matrix = Mat(3,3,CV_32FC1, Scalar::all(0)); /* 保存每幅图像的旋转矩阵 */  
  156.     fout<<”相机内参数矩阵:”<<endl;     
  157.     fout<<cameraMatrix<<endl<<endl;     
  158.     fout<<”畸变系数:\n”;     
  159.     fout<<distCoeffs<<endl<<endl<<endl;     
  160.     for (int i=0; i<image_count; i++)   
  161.     {   
  162.         fout<<”第”<<i+1<<“幅图像的旋转向量:”<<endl;     
  163.         fout<<tvecsMat[i]<<endl;      
  164.         /* 将旋转向量转换为相对应的旋转矩阵 */     
  165.         Rodrigues(tvecsMat[i],rotation_matrix);     
  166.         fout<<”第”<<i+1<<“幅图像的旋转矩阵:”<<endl;     
  167.         fout<<rotation_matrix<<endl;     
  168.         fout<<”第”<<i+1<<“幅图像的平移向量:”<<endl;     
  169.         fout<<rvecsMat[i]<<endl<<endl;     
  170.     }     
  171.     std::cout<<”完成保存”<<endl;   
  172.     fout<<endl;  
  173.     /************************************************************************   
  174.     显示定标结果   
  175.     *************************************************************************/  
  176.     Mat mapx = Mat(image_size,CV_32FC1);  
  177.     Mat mapy = Mat(image_size,CV_32FC1);  
  178.     Mat R = Mat::eye(3,3,CV_32F);  
  179.     std::cout<<”保存矫正图像”<<endl;  
  180.     string imageFileName;  
  181.     std::stringstream StrStm;  
  182.     for (int i = 0 ; i != image_count ; i++)  
  183.     {  
  184.         std::cout<<”Frame #”<<i+1<<“…”<<endl;  
  185.         initUndistortRectifyMap(cameraMatrix,distCoeffs,R,cameraMatrix,image_size,CV_32FC1,mapx,mapy);        
  186.         StrStm.clear();  
  187.         imageFileName.clear();  
  188.         string filePath=”chess”;  
  189.         StrStm<<i+1;  
  190.         StrStm>>imageFileName;  
  191.         filePath+=imageFileName;  
  192.         filePath+=”.bmp”;  
  193.         Mat imageSource = imread(filePath);  
  194.         Mat newimage = imageSource.clone();  
  195.         //另一种不需要转换矩阵的方式  
  196.         //undistort(imageSource,newimage,cameraMatrix,distCoeffs);  
  197.         remap(imageSource,newimage,mapx, mapy, INTER_LINEAR);         
  198.         StrStm.clear();  
  199.         filePath.clear();  
  200.         StrStm<<i+1;  
  201.         StrStm>>imageFileName;  
  202.         imageFileName += ”_d.jpg”;  
  203.         imwrite(imageFileName,newimage);  
  204.     }  
  205.     std::cout<<”保存结束”<<endl;      
  206.     return ;  
  207. }  
#include "opencv2/core/core.hpp"




#include "opencv2/imgproc/imgproc.hpp" #include "opencv2/calib3d/calib3d.hpp" #include "opencv2/highgui/highgui.hpp" #include <iostream> #include <fstream> using namespace cv; using namespace std; void main() { ifstream fin("calibdata.txt"); /* 标定所用图像文件的路径 */ ofstream fout("caliberation_result.txt"); /* 保存标定结果的文件 */ //读取每一幅图像,从中提取出角点,然后对角点进行亚像素精确化 cout<<"开始提取角点………………"; int image_count=0; /* 图像数量 */ Size image_size; /* 图像的尺寸 */ Size board_size = Size(4,6); /* 标定板上每行、列的角点数 */ vector<Point2f> image_points_buf; /* 缓存每幅图像上检测到的角点 */ vector<vector<Point2f>> image_points_seq; /* 保存检测到的所有角点 */ string filename; int count= -1 ;//用于存储角点个数。 while (getline(fin,filename)) { image_count++; // 用于观察检验输出 cout<<"image_count = "<<image_count<<endl; /* 输出检验*/ cout<<"-->count = "<<count; Mat imageInput=imread(filename); if (image_count == 1) //读入第一张图片时获取图像宽高信息 { image_size.width = imageInput.cols; image_size.height =imageInput.rows; cout<<"image_size.width = "<<image_size.width<<endl; cout<<"image_size.height = "<<image_size.height<<endl; } /* 提取角点 */ if (0 == findChessboardCorners(imageInput,board_size,image_points_buf)) { cout<<"can not find chessboard corners!\n"; //找不到角点 exit(1); } else { Mat view_gray; cvtColor(imageInput,view_gray,CV_RGB2GRAY); /* 亚像素精确化 */ find4QuadCornerSubpix(view_gray,image_points_buf,Size(5,5)); //对粗提取的角点进行精确化 //cornerSubPix(view_gray,image_points_buf,Size(5,5),Size(-1,-1),TermCriteria(CV_TERMCRIT_EPS+CV_TERMCRIT_ITER,30,0.1)); image_points_seq.push_back(image_points_buf); //保存亚像素角点 /* 在图像上显示角点位置 */ drawChessboardCorners(view_gray,board_size,image_points_buf,false); //用于在图片中标记角点 imshow("Camera Calibration",view_gray);//显示图片 waitKey(500);//暂停0.5S } } int total = image_points_seq.size(); cout<<"total = "<<total<<endl; int CornerNum=board_size.width*board_size.height; //每张图片上总的角点数 for (int ii=0 ; ii<total ;ii++) { if (0 == ii%CornerNum)// 24 是每幅图片的角点个数。此判断语句是为了输出 图片号,便于控制台观看 { int i = -1; i = ii/CornerNum; int j=i+1; cout<<"--> 第 "<<j <<"图片的数据 --> : "<<endl; } if (0 == ii%3) // 此判断语句,格式化输出,便于控制台查看 { cout<<endl; } else { cout.width(10); } //输出所有的角点 cout<<" -->"<<image_points_seq[ii][0].x; cout<<" -->"<<image_points_seq[ii][0].y; } cout<<"角点提取完成!\n"; //以下是摄像机标定 cout<<"开始标定………………"; /*棋盘三维信息*/ Size square_size = Size(10,10); /* 实际测量得到的标定板上每个棋盘格的大小 */ vector<vector<Point3f>> object_points; /* 保存标定板上角点的三维坐标 */ /*内外参数*/ Mat cameraMatrix=Mat(3,3,CV_32FC1,Scalar::all(0)); /* 摄像机内参数矩阵 */ vector<int> point_counts; // 每幅图像中角点的数量 Mat distCoeffs=Mat(1,5,CV_32FC1,Scalar::all(0)); /* 摄像机的5个畸变系数:k1,k2,p1,p2,k3 */ vector<Mat> tvecsMat; /* 每幅图像的旋转向量 */ vector<Mat> rvecsMat; /* 每幅图像的平移向量 */ /* 初始化标定板上角点的三维坐标 */ int i,j,t; for (t=0;t<image_count;t++) { vector<Point3f> tempPointSet; for (i=0;i<board_size.height;i++) { for (j=0;j<board_size.width;j++) { Point3f realPoint; /* 假设标定板放在世界坐标系中z=0的平面上 */ realPoint.x = i*square_size.width; realPoint.y = j*square_size.height; realPoint.z = 0; tempPointSet.push_back(realPoint); } } object_points.push_back(tempPointSet); } /* 初始化每幅图像中的角点数量,假定每幅图像中都可以看到完整的标定板 */ for (i=0;i<image_count;i++) { point_counts.push_back(board_size.width*board_size.height); } /* 开始标定 */ calibrateCamera(object_points,image_points_seq,image_size,cameraMatrix,distCoeffs,rvecsMat,tvecsMat,0); cout<<"标定完成!\n"; //对标定结果进行评价 cout<<"开始评价标定结果………………\n"; double total_err = 0.0; /* 所有图像的平均误差的总和 */ double err = 0.0; /* 每幅图像的平均误差 */ vector<Point2f> image_points2; /* 保存重新计算得到的投影点 */ cout<<"\t每幅图像的标定误差:\n"; fout<<"每幅图像的标定误差:\n"; for (i=0;i<image_count;i++) { vector<Point3f> tempPointSet=object_points[i]; /* 通过得到的摄像机内外参数,对空间的三维点进行重新投影计算,得到新的投影点 */ projectPoints(tempPointSet,rvecsMat[i],tvecsMat[i],cameraMatrix,distCoeffs,image_points2); /* 计算新的投影点和旧的投影点之间的误差*/ vector<Point2f> tempImagePoint = image_points_seq[i]; Mat tempImagePointMat = Mat(1,tempImagePoint.size(),CV_32FC2); Mat image_points2Mat = Mat(1,image_points2.size(), CV_32FC2); for (int j = 0 ; j < tempImagePoint.size(); j++) { image_points2Mat.at<Vec2f>(0,j) = Vec2f(image_points2[j].x, image_points2[j].y); tempImagePointMat.at<Vec2f>(0,j) = Vec2f(tempImagePoint[j].x, tempImagePoint[j].y); } err = norm(image_points2Mat, tempImagePointMat, NORM_L2); total_err += err/= point_counts[i]; std::cout<<"第"<<i+1<<"幅图像的平均误差:"<<err<<"像素"<<endl; fout<<"第"<<i+1<<"幅图像的平均误差:"<<err<<"像素"<<endl; } std::cout<<"总体平均误差:"<<total_err/image_count<<"像素"<<endl; fout<<"总体平均误差:"<<total_err/image_count<<"像素"<<endl<<endl; std::cout<<"评价完成!"<<endl; //保存定标结果 std::cout<<"开始保存定标结果………………"<<endl; Mat rotation_matrix = Mat(3,3,CV_32FC1, Scalar::all(0)); /* 保存每幅图像的旋转矩阵 */ fout<<"相机内参数矩阵:"<<endl; fout<<cameraMatrix<<endl<<endl; fout<<"畸变系数:\n"; fout<<distCoeffs<<endl<<endl<<endl; for (int i=0; i<image_count; i++) { fout<<"第"<<i+1<<"幅图像的旋转向量:"<<endl; fout<<tvecsMat[i]<<endl; /* 将旋转向量转换为相对应的旋转矩阵 */ Rodrigues(tvecsMat[i],rotation_matrix); fout<<"第"<<i+1<<"幅图像的旋转矩阵:"<<endl; fout<<rotation_matrix<<endl; fout<<"第"<<i+1<<"幅图像的平移向量:"<<endl; fout<<rvecsMat[i]<<endl<<endl; } std::cout<<"完成保存"<<endl; fout<<endl; /************************************************************************ 显示定标结果 *************************************************************************/ Mat mapx = Mat(image_size,CV_32FC1); Mat mapy = Mat(image_size,CV_32FC1); Mat R = Mat::eye(3,3,CV_32F); std::cout<<"保存矫正图像"<<endl; string imageFileName; std::stringstream StrStm; for (int i = 0 ; i != image_count ; i++) { std::cout<<"Frame #"<<i+1<<"..."<<endl; initUndistortRectifyMap(cameraMatrix,distCoeffs,R,cameraMatrix,image_size,CV_32FC1,mapx,mapy); StrStm.clear(); imageFileName.clear(); string filePath="chess"; StrStm<<i+1; StrStm>>imageFileName; filePath+=imageFileName; filePath+=".bmp"; Mat imageSource = imread(filePath); Mat newimage = imageSource.clone(); //另一种不需要转换矩阵的方式 //undistort(imageSource,newimage,cameraMatrix,distCoeffs); remap(imageSource,newimage,mapx, mapy, INTER_LINEAR); StrStm.clear(); filePath.clear(); StrStm<<i+1; StrStm>>imageFileName; imageFileName += "_d.jpg"; imwrite(imageFileName,newimage); } std::cout<<"保存结束"<<endl; return ; }


标定图例1:



标定图例2:



标定结果1:



标定结果2:



矫正效果1:



矫正效果2:



以上程序已经是完整程序,需要棋盘标定图或者整个项目包的可以到这里下载:张正友相机标定Opencv实现(完整程序+棋盘图)


                </div>
</article>
  <div class="readall_box csdn-tracking-statistics readall_box_nobg" data-mod="popu_376" style="display: none;">
      <div class="read_more_mask"></div>
      <a class="btn btn-large btn-gray-fred read_more_btn" target="_self">阅读全文</a>
  </div>
  <div class="article_copyright">
    版权声明:本文为博主原创文章,转载请注明出处。      </div>
  <ul class="article_collect clearfix csdn-tracking-statistics" data-mod="popu_378">
      <li class="tit">本文已收录于以下专栏:</li>


  • OpenCV从入门到转行


  •                   <form action="http://blog.csdn.net/dcrmg/comment/submit?id=52939318" method="post" onsubmit="return subform(this);" id="commentform">
                          <textarea class="comment_content" name="comment_content" id="comment_content" placeholder="发表你的评论" style="height: 40px;"></textarea>
                          <div class="bot_bar clearfix" style="opacity: 0;">
                              <div id="ubbtools" class="add_code">
                                  <a href="#insertcode" code="code" target="_self"><i class="icon iconfont icon-daima"></i></a>
                              </div>
    
                              <input type="hidden" id="comment_replyId" name="comment_replyId">
                              <input type="hidden" id="comment_userId" name="comment_userId" value="">
                              <input type="hidden" id="commentId" name="commentId" value="">
                              <input type="submit" class="btn btn-redborder" value="发表评论">
                              <span id="tip_comment" class="tip">
                              <div style="display: none;" class="csdn-tracking-statistics" data-mod="popu_384"><a href="#" target="_blank" class="comment_area_btn">发表评论</a></div>
    
                              <div id="lang_list" code="code">
                                  <a href="#html" style="width:95px;" class="long_name" target="_self">HTML/XML</a>
                                  <a href="#objc" style="width:95px;" class="long_name" target="_self">objective-c</a>
                                  <a href="#delphi" style="width:58px;" class="zhong_name" target="_self">Delphi</a>
                                  <a href="#ruby" class="zhong_name" target="_self">Ruby</a>
                                  <a href="#php" target="_self">PHP</a>
                                  <a href="#csharp" class="duan_name" target="_self">C#</a>
                                  <a style=" border-right: none;" href="#cpp" class="duan_name" target="_self">C++</a>
                                  <a style=" border-bottom:none;width:95px;" href="#javascript" class="long_name" target="_self">JavaScript</a>
                                  <a style=" border-bottom:none;width:95px;" href="#vb" class="long_name" target="_self">Visual Basic</a>
                                  <a style=" border-bottom:none;" href="#python" class="zhong_name" target="_self">Python</a>
                                  <a style=" border-bottom:none;" href="#java" class="zhong_name" target="_self">Java</a>
                                  <a style="border-bottom:none;" href="#css" class="duan_name" target="_self">CSS</a>
                                  <a style="border-bottom:none;" href="#sql" class="duan_name" target="_self">SQL</a>
                                  <a style="border:none; " href="#plain" class="duan_name" target="_self">其它</a>
                                  <span class="arrb"></span>
                              </div>
                          </span></div>
                      </form>
                  </div>
                              </div>
          </div>
      </div>
      <div class="comment_li_outbox">
          <div id="comment_list"> <div class="comment_li_box clearfix">         <dl class="comment_list clearfix" id="comment_item_7281480">           <dt>               <a href="/ynot_oahz"><img src="http://avatar.csdn.net/5/D/5/3_ynot_oahz.jpg" alt="ynot_oahz"></a></dt>           <dd>             <ul class="com_r clearfix">               <li class="top clearfix">                 <h4><a href="/ynot_oahz">ynot_oahz</a></h4>                 <span class="time">2017-10-24 20:04</span>                 <span class="floor_num" floor="3">3楼</span>               </li>               <li class="mid clearfix">                 <div class="comment_p">谢谢分享,学习了~~</div>               </li>               <li class="bot clearfix">                   <div>                     <a href="#reply" class="com_reply btn btn-noborder reply_btn" title="回复" commentid="7281480" floor="3">回复</a>                   </div>                </li>              </ul>            </dd>          </dl><div class="child_comment" data-listshow="false">   <div class="autoHeight clearfix">   </div></div>       </div> <div class="comment_li_box clearfix">         <dl class="comment_list clearfix" id="comment_item_7162831">           <dt>               <a href="/atyzy"><img src="http://avatar.csdn.net/6/D/6/3_atyzy.jpg" alt="atyzy"></a></dt>           <dd>             <ul class="com_r clearfix">               <li class="top clearfix">                 <h4><a href="/atyzy">atyzy</a></h4>                 <span class="time">2017-09-04 20:54</span>                 <span class="floor_num" floor="2">2楼</span>               </li>               <li class="mid clearfix">                 <div class="comment_p">写的很详细,估计能跑下来,谢谢分享,改天试一下。</div>               </li>               <li class="bot clearfix">                   <div>                     <a href="#reply" class="com_reply btn btn-noborder reply_btn" title="回复" commentid="7162831" floor="2">回复</a>                   </div>                </li>              </ul>            </dd>          </dl><div class="child_comment" data-listshow="false">   <div class="autoHeight clearfix">   </div></div>       </div> <div class="comment_li_box clearfix">         <dl class="comment_list clearfix" id="comment_item_7095692">           <dt>               <a href="/qq_30234963"><img src="http://avatar.csdn.net/1/4/5/3_qq_30234963.jpg" alt="qq_30234963"></a></dt>           <dd>             <ul class="com_r clearfix">               <li class="top clearfix">                 <h4><a href="/qq_30234963">qq_30234963</a></h4>                 <span class="time">2017-08-15 10:14</span>                 <span class="floor_num" floor="1">1楼</span>               </li>               <li class="mid clearfix">                 <div class="comment_p">这个矫正后畸变更大了啊。。。<br>把图片放到画图里,右边的楼,用直线连一下就看出来了。。。<br>感觉程序很完美,是什么原因呢</div>               </li>               <li class="bot clearfix">                   <div>                     <a href="#reply" class="com_reply btn btn-noborder reply_btn" title="回复" commentid="7095692" floor="1">回复</a>                   </div>                </li>              </ul>            </dd>          </dl><div class="child_comment" data-listshow="false">   <div class="autoHeight clearfix">   </div></div>       </div><div class="clear"></div></div>
      </div>
    
      <div class="more_comment" style="display: block;">
          <div id="comment_bar" class="trackgin-ad" data-mod="popu_385" style="display: block;"><a id="load_comments" class="btn btn-large more_comment_btn" page="2">查看 <span>31</span> 条热评<i class="icon iconfont icon-xiajiantou"></i></a></div>
      </div>
    
      <h3 class="recommend_tit">相关文章推荐</h3>
      <div class="recommend_list clearfix">
                                                                                                                  <dl class="clearfix csdn-tracking-statistics downloadElement" data-mod="popu_387" data-poputype="feed" data-feed-show="true" data-dsm="post">
                          <dt><a href="http://download.csdn.net/detail/chenxh/3" target="_blank" strategy="BlogCommendFromBaidu_0"><img class="maxwidth" src="http://download.csdn.net/images/minetype/zip.svg" alt="" title=""></a></dt>
                          <dd>
                              <div class="summary">
                                  <h2><a href="http://download.csdn.net/detail/chenxh/3" target="_blank" strategy="BlogCommendFromBaidu_0">Delphi7高级应用开发随书源码</a></h2>
                                  <div class="summary">
                                      <ul>
                                          <li class="time">2003年04月30日 00:00</li>
                                          <li class="visited_num fileSize">676KB</li>
                                          <li class="download_btn"><a href="http://download.csdn.net/detail/chenxh/3" target="_blank">下载</a></li>
                                      </ul>
                                  </div>
                              </div>
                          </dd>
                      </dl>
                                                                                                                                <dl class="clearfix csdn-tracking-statistics downloadElement" data-mod="popu_387" data-poputype="feed" data-feed-show="true" data-dsm="post">
                          <dt><a href="http://download.csdn.net/detail/chenxh/3" target="_blank" strategy="BlogCommendFromBaidu_1"><img class="maxwidth" src="http://download.csdn.net/images/minetype/zip.svg" alt="" title=""></a></dt>
                          <dd>
                              <div class="summary">
                                  <h2><a href="http://download.csdn.net/detail/chenxh/3" target="_blank" strategy="BlogCommendFromBaidu_1">Delphi7高级应用开发随书源码</a></h2>
                                  <div class="summary">
                                      <ul>
                                          <li class="time">2003年04月30日 00:00</li>
                                          <li class="visited_num fileSize">676KB</li>
                                          <li class="download_btn"><a href="http://download.csdn.net/detail/chenxh/3" target="_blank">下载</a></li>
                                      </ul>
                                  </div>
                              </div>
                          </dd>
                      </dl>
                                                                                                              <script>
                          (function() {
                              var s = "_" + Math.random().toString(36).slice(2);
                              document.write('<div id="' + s + '"></div>');
                              (window.slotbydup=window.slotbydup || []).push({
                                  id: '4765209',
                                  container: s,
                                  size: '808,120',
                                  display: 'inlay-fix'
                              });
                          })();
                      </script><div id="_201aooihvkxh"></div><script charset="utf-8" src="http://pos.baidu.com/wcmm?di=4765209&amp;dri=0&amp;dis=0&amp;dai=0&amp;ps=11479x331&amp;enu=encoding&amp;dcb=___adblockplus&amp;dtm=SSP_JSONP&amp;dvi=0.0&amp;dci=-1&amp;dpt=none&amp;tsr=0&amp;tpr=1510157985204&amp;ti=%E5%BC%A0%E6%AD%A3%E5%8F%8B%E7%9B%B8%E6%9C%BA%E6%A0%87%E5%AE%9AOpencv%E5%AE%9E%E7%8E%B0%E4%BB%A5%E5%8F%8A%E6%A0%87%E5%AE%9A%E6%B5%81%E7%A8%8B%26%26%E6%A0%87%E5%AE%9A%E7%BB%93%E6%9E%9C%E8%AF%84%E4%BB%B7%26%26%E5%9B%BE%E5%83%8F%E7%9F%AB%E6%AD%A3%E6%B5%81%E7%A8%8B%E8%A7%A3%E6%9E%90%EF%BC%88%E9%99%84%E6%A0%87%E5%AE%9A%E7%A8%8B%E5%BA%8F%E5%92%8C%E6%A3%8B%E7%9B%98%E5%9B%BE%EF%BC%89%20-%20CSDN%E5%8D%9A%E5%AE%A2&amp;ari=2&amp;dbv=2&amp;drs=1&amp;pcs=1903x984&amp;pss=1903x11501&amp;cfv=0&amp;cpl=4&amp;chi=1&amp;cce=true&amp;cec=UTF-8&amp;tlm=1510157985&amp;rw=984&amp;ltu=http%3A%2F%2Fblog.csdn.net%2Fdcrmg%2Farticle%2Fdetails%2F52939318&amp;ltr=http%3A%2F%2Fblog.csdn.net%2Fpinbodexiaozhu%2Farticle%2Fdetails%2F43373247&amp;ecd=1&amp;uc=1920x1050&amp;pis=-1x-1&amp;sr=1920x1080&amp;tcn=1510157985"></script><a href="http://www.baidu.com/cb.php?c=IgF_pyfqnHmknjDLnjT0IZ0qnfK9ujYzP1nsrjDz0Aw-5Hc3rHnYnHb0TAq15HfLPWRznjb0T1Y3rHwWP1TznjR3PhwbnAuB0AwY5HDdnH0kPHT4rjn0IgF_5y9YIZ0lQzq-uZR8mLPbUB48ugfEXyN9T-KzUvdEIA-EUBqbugw9pysEn1qdIAdxTvqdThP-5yF_UvTkn0KzujY1P0KBUHYs0ZKz5H00Iy-b5HDdP1f1PWD0Uv-b5HDzrH63nHf0mv-b5HTzPWb1n6KEIv3qn0KsXHYznjm0mLFW5Hn4n1Dk" target="_blank">
    <dl class="clearfix csdn-tracking-statistics" data-mod="popu_393">
        <dt><img class="maxwidth" src="http://ubmcmm.baidustatic.com/media/v1/0f00009rjpV7MZT1zKJ2ls.jpg" alt="" title=""></dt>
        <dd>
            <div class="summary">
                <h2>11.11 程序员该买些什么犒劳自己?</h2>  <div class="summary">这是一份11.11程序员版爆款剁手清单!万万没想到,他们买了这些...</div> 
            </div>
        </dd>
    </dl>
    




    OpenCV之光流法跟踪运动目标



    OpenCV之光流法运动目标跟踪目录
    OpenCV之光流法运动目标跟踪
    目录
    光流计算方法
    大致可分为三类基于匹配的方法频域的方法和梯度的方法
    基于匹配的光流计算方法包括基于特征和基于区域两种2 基于…






    opencv相机标定



    针孔相机模型和变形

    这一节里的函数都使用针孔摄像机模型,这就是说,一幅视图是通过透视变换将三维空间中的点投影到图像平面。投影公式如下:

    或者

    这里(X, Y, Z)是一个点的…






    OpenCV相机标定函数


    照相机定标

    [编辑]

    ProjectPoints2







    (function() {
    var s = "_" + Math.random().toString(36).slice(2);
    document.write('
    ');
    (window.slotbydup=window.slotbydup || []).push({
    id: '4983339',
    container: s,
    size: '808,120',
    display: 'inlay-fix'
    });
    })();





    闲话微信幸运大抽奖

    简单的抽奖一个随机数加个动画效果即可实现,而复杂的抽奖则要从架构、设计、开发、运营、运维等各个角度周密考虑才能做到万无一失……









    Delphi7高级应用开发随书源码




    • 2003年04月30日 00:00
    • 676KB
    • 下载







    opencv相机标定



    主要是参照opencv2那本书,注视写的都很详细,方便以后查找!
    CameraCalibrator.h头文件#include #include

    include

    include

    inclu…

                              <ul>
                                  <li class="avatar_img"><a href="http://blog.csdn.net/hanshuobest" target="_blank" strategy="BlogCommendFromBaidu_6"><img src="http://avatar.csdn.net/F/4/C/3_hanshuobest.jpg" alt="hanshuobest" title="hanshuobest"></a></li>
                                  <li class="user_name"><a href="http://blog.csdn.net/hanshuobest" target="_blank">hanshuobest</a></li>
                                  <li class="time">2016年01月19日 01:25</li>
                                  <li class="visited_num"><i class="icon iconfont icon-read"></i><span>1441</span></li>
                              </ul>
                          </dd>
                      </dl>
                                                                                                                                <dl class="clearfix csdn-tracking-statistics" data-mod="popu_387" data-poputype="feed" data-feed-show="false" data-dsm="post">
                          <dd>
                              <h2><a href="http://blog.csdn.net/Real_Myth/article/details/52771177" target="_blank" strategy="BlogCommendFromBaidu_7">OpenCV相机标定</a></h2>
                              <div class="summary">
                                  OpenCV相机标定                              </div>
                              <ul>
                                  <li class="avatar_img"><a href="http://blog.csdn.net/Real_Myth" target="_blank" strategy="BlogCommendFromBaidu_7"><img src="http://avatar.csdn.net/9/D/E/3_real_myth.jpg" alt="Real_Myth" title="Real_Myth"></a></li>
                                  <li class="user_name"><a href="http://blog.csdn.net/Real_Myth" target="_blank">Real_Myth</a></li>
                                  <li class="time">2016年10月09日 22:23</li>
                                  <li class="visited_num"><i class="icon iconfont icon-read"></i><span>1309</span></li>
                              </ul>
                          </dd>
                      </dl>
                                                                                                                                <dl class="clearfix csdn-tracking-statistics" data-mod="popu_387" data-poputype="feed" data-feed-show="false" data-dsm="post">
                          <dd>
                              <h2><a href="http://blog.csdn.net/YhL_Leo/article/details/49427383" target="_blank" strategy="BlogCommendFromBaidu_8">Camera Calibration 相机标定:Opencv应用方法</a></h2>
                              <div class="summary">
                                  Opencv中Camera Calibration and 3D Reconstruction中使用的是Z. Zhang(PAMI, 2000). A Flexible New Technique f...                              </div>
                              <ul>
                                  <li class="avatar_img"><a href="http://blog.csdn.net/YhL_Leo" target="_blank" strategy="BlogCommendFromBaidu_8"><img src="http://avatar.csdn.net/9/A/A/3_yhl_leo.jpg" alt="YhL_Leo" title="YhL_Leo"></a></li>
                                  <li class="user_name"><a href="http://blog.csdn.net/YhL_Leo" target="_blank">YhL_Leo</a></li>
                                  <li class="time">2015年10月26日 17:32</li>
                                  <li class="visited_num"><i class="icon iconfont icon-read"></i><span>11981</span></li>
                              </ul>
                          </dd>
                      </dl>
                                                                                                                                <dl class="clearfix csdn-tracking-statistics" data-mod="popu_387" data-poputype="feed" data-feed-show="false" data-dsm="post">
                          <dd>
                              <h2><a href="http://blog.csdn.net/dcrmg/article/details/52950141" target="_blank" strategy="BlogCommendFromBaidu_9">透镜畸变及校正模型</a></h2>
                              <div class="summary">
                                  透镜由于制造精度以及组装工艺的偏差会引入畸变,导致原始图像的失真。镜头的畸变分为径向畸变和切向畸变两类。
    
    1. 径向畸变

    顾名思义,径向畸变就是沿着透镜半径方向分布的畸变,产生原因…


    • dcrmg
    • dcrmg
    • 2016年10月27日 22:10
    • 5499


            <dl class="clearfix csdn-tracking-statistics" data-mod="popu_387" data-poputype="feed" data-feed-show="false" data-dsm="post">
                <dd>
                    <h2><a href="/dddxxxx/article/details/52942347" target="_blank" strategy="BlogCommendFromCsdn_10">张正友相机标定Opencv实现以及标定流程&amp;&amp;标定结果评价&amp;&amp;图像矫正流程解析(附标定程序和棋盘图)</a></h2>
                    <div class="summary">
                        使用OpenCV实现张正友法相机标定之前,有几个问题事先要确认一下,那就是相机为什么需要标定,标定需要的输入和输出分别是哪些?
    

    相机标定的目的:获取摄像机的内参和外参矩阵(同时也会得到每一幅…



            <dl class="clearfix csdn-tracking-statistics" data-mod="popu_387" data-poputype="feed" data-feed-show="false" data-dsm="post">
                <dd>
                    <h2><a href="/kaychangeek/article/details/75098419" target="_blank" strategy="BlogCommendFromCsdn_11">张正友相机标定Opencv实现以及标定流程&amp;&amp;标定结果评价&amp;&amp;图像矫正流程解析(附标定程序和棋盘图)</a></h2>
                    <div class="summary">
                        原文来自:http://blog.csdn.net/dcrmg/article/details/52939318
    

    使用OpenCV实现张正友法相机标定之前,有几个问题事先要确认一下,那就是相机为…



            <dl class="clearfix csdn-tracking-statistics downloadElement" data-mod="popu_387" data-poputype="feed" data-feed-show="false" data-dsm="post">
                <dt><a href="http://download.csdn.net/detail/dcrmg/9665040" target="_blank" strategy="BlogCommendFromCsdn_12"><img class="maxwidth" src="http://download.csdn.net/images/minetype/rar.svg" alt="" title=""></a></dt>
        <dd>
            <div class="summary">
                <h2><a href="http://download.csdn.net/detail/dcrmg/9665040" target="_blank" strategy="BlogCommendFromCsdn_12">张正友相机标定Opencv实现(完整程序+棋盘图)实例源码</a></h2>
                <div class="summary">
                  <ul>
                      <li class="time">2016-10-26 22:50</li>
                      <li class="visited_num fileSize">10.26MB</li>
                      <li class="download_btn"><a href="http://download.csdn.net/detail/dcrmg/9665040" target="_blank">下载</a></li>
                  </ul>
                </div> 
            </div>
        </dd>
            </dl>
    
            <dl class="clearfix csdn-tracking-statistics downloadElement" data-mod="popu_387" data-poputype="feed" data-feed-show="false" data-dsm="post">
                <dt><a href="http://download.csdn.net/detail/u011574296/9918396" target="_blank" strategy="BlogCommendFromCsdn_13"><img class="maxwidth" src="http://download.csdn.net/images/minetype/zip.svg" alt="" title=""></a></dt>
        <dd>
            <div class="summary">
                <h2><a href="http://download.csdn.net/detail/u011574296/9918396" target="_blank" strategy="BlogCommendFromCsdn_13">OpenCV张正友相机标定程序,附实验数据</a></h2>
                <div class="summary">
                  <ul>
                      <li class="time">2017-08-02 09:41</li>
                      <li class="visited_num fileSize">8.29MB</li>
                      <li class="download_btn"><a href="http://download.csdn.net/detail/u011574296/9918396" target="_blank">下载</a></li>
                  </ul>
                </div> 
            </div>
        </dd>
            </dl>
    
            <dl class="clearfix csdn-tracking-statistics" data-mod="popu_387" data-poputype="feed" data-feed-show="false" data-dsm="post">
                <dd>
                    <h2><a href="/dcrmg/article/details/52929669" target="_blank" strategy="BlogCommendFromCsdn_14">Opencv 张正友相机标定傻瓜教程</a></h2>
                    <div class="summary">
                        先贴一下完整的工程代码:
    

    include “opencv2/core/core.hpp”

    include “opencv2/imgproc/imgproc.hpp”

    include “ope…

                    </div>
                    <ul>
                        <li class="avatar_img"><a href="http://blog.csdn.net/dcrmg" target="_blank" strategy="BlogCommendFromCsdn_14"><img src="http://avatar.csdn.net/A/8/1/2_dcrmg.jpg" alt="dcrmg" title="dcrmg"></a></li>
                        <li class="user_name"><a href="http://blog.csdn.net/dcrmg">dcrmg</a></li>
                        <li class="time">2016-10-26 00:41</li>
                        <li class="visited_num"><i class="icon iconfont icon-read"></i><span>9907</span></li>
                    </ul>
                </dd>
            </dl>
    
            <dl class="clearfix csdn-tracking-statistics downloadElement" data-mod="popu_387" data-poputype="feed" data-feed-show="false" data-dsm="post">
                <dt><a href="http://download.csdn.net/detail/huangshulang66/10103356" target="_blank" strategy="BlogCommendFromCsdn_15"><img class="maxwidth" src="http://download.csdn.net/images/minetype/unkonw.svg" alt="" title=""></a></dt>
        <dd>
            <div class="summary">
                <h2><a href="http://download.csdn.net/detail/huangshulang66/10103356" target="_blank" strategy="BlogCommendFromCsdn_15">VS2015+OpenCV3.1.0实现张正友相机标定法</a></h2>
                <div class="summary">
                  <ul>
                      <li class="time">5天前 21:39</li>
                      <li class="visited_num fileSize">9KB</li>
                      <li class="download_btn"><a href="http://download.csdn.net/detail/huangshulang66/10103356" target="_blank">下载</a></li>
                  </ul>
                </div> 
            </div>
        </dd>
            </dl>
    
            <dl class="clearfix csdn-tracking-statistics downloadElement" data-mod="popu_387" data-poputype="feed" data-feed-show="false" data-dsm="post">
                <dt><a href="http://download.csdn.net/detail/smnhw/9819284" target="_blank" strategy="BlogCommendFromCsdn_16"><img class="maxwidth" src="http://download.csdn.net/images/minetype/pdf.svg" alt="" title=""></a></dt>
        <dd>
            <div class="summary">
                <h2><a href="http://download.csdn.net/detail/smnhw/9819284" target="_blank" strategy="BlogCommendFromCsdn_16">OpenCV耦合改进张正友算法的相机标定算法</a></h2>
                <div class="summary">
                  <ul>
                      <li class="time">2017-04-19 17:13</li>
                      <li class="visited_num fileSize">2.14MB</li>
                      <li class="download_btn"><a href="http://download.csdn.net/detail/smnhw/9819284" target="_blank">下载</a></li>
                  </ul>
                </div> 
            </div>
        </dd>
            </dl>
    
            <dl class="clearfix csdn-tracking-statistics" data-mod="popu_387" data-poputype="feed" data-feed-show="false" data-dsm="post">
                <dd>
                    <h2><a href="/u010543769/article/details/38355573" target="_blank" strategy="BlogCommendFromCsdn_17">opencv实现摄像机标定(张正友的标定方法)</a></h2>
                    <div class="summary">
                        /**
    

    * 程序实现功能:标定摄像头参数
    * 输出:内参数矩阵、畸变系数、旋转向量、旋转矩阵、平移向量
    * 运行环境:Linux + eclip…



            <dl class="clearfix csdn-tracking-statistics downloadElement" data-mod="popu_387" data-poputype="feed" data-feed-show="false" data-dsm="post">
                <dt><a href="http://download.csdn.net/detail/qq_25315801/9495070" target="_blank" strategy="BlogCommendFromCsdn_18"><img class="maxwidth" src="http://download.csdn.net/images/minetype/rar.svg" alt="" title=""></a></dt>
        <dd>
            <div class="summary">
                <h2><a href="http://download.csdn.net/detail/qq_25315801/9495070" target="_blank" strategy="BlogCommendFromCsdn_18">张正友棋盘格标定程序源代码</a></h2>
                <div class="summary">
                  <ul>
                      <li class="time">2016-04-18 21:16</li>
                      <li class="visited_num fileSize">46KB</li>
                      <li class="download_btn"><a href="http://download.csdn.net/detail/qq_25315801/9495070" target="_blank">下载</a></li>
                  </ul>
                </div> 
            </div>
        </dd>
            </dl>
    
            <dl class="clearfix csdn-tracking-statistics downloadElement" data-mod="popu_387" data-poputype="feed" data-feed-show="false" data-dsm="post">
                <dt><a href="http://download.csdn.net/detail/cvbertie/4755379" target="_blank" strategy="BlogCommendFromCsdn_19"><img class="maxwidth" src="http://download.csdn.net/images/minetype/rar.svg" alt="" title=""></a></dt>
        <dd>
            <div class="summary">
                <h2><a href="http://download.csdn.net/detail/cvbertie/4755379" target="_blank" strategy="BlogCommendFromCsdn_19">张正友棋盘格标定</a></h2>
                <div class="summary">
                  <ul>
                      <li class="time">2012-11-11 09:39</li>
                      <li class="visited_num fileSize">56KB</li>
                      <li class="download_btn"><a href="http://download.csdn.net/detail/cvbertie/4755379" target="_blank">下载</a></li>
                  </ul>
                </div> 
            </div>
        </dd>
            </dl>
            </div>
    


      </div>
    






    width="300" height="250" scrolling="no" src="http://pos.baidu.com/s?hei=250&wid=300&di=u3032528&ltu=http%3A%2F%2Fblog.csdn.net%2Fdcrmg%2Farticle%2Fdetails%2F52939318&cja=false&tcn=1510157985&exps=111000&col=zh-CN&dai=1&ps=517x1273&chi=1&cec=UTF-8&par=1920x1050&cdo=-1&drs=1&tlm=1510157985&ant=0&tpr=1510157985369&ari=2&ltr=http%3A%2F%2Fblog.csdn.net%2Fpinbodexiaozhu%2Farticle%2Fdetails%2F43373247&psr=1920x1080&cfv=0&pcs=1903x984&cpl=4&pis=-1x-1&ccd=24&pss=1903x20196&ti=%E5%BC%A0%E6%AD%A3%E5%8F%8B%E7%9B%B8%E6%9C%BA%E6%A0%87%E5%AE%9AOpencv%E5%AE%9E%E7%8E%B0%E4%BB%A5%E5%8F%8A%E6%A0%87%E5%AE%9A%E6%B5%81%E7%A8%8B%26%26%E6%A0%87%E5%AE%9A%E7%BB%93%E6%9E%9C%E8%AF%84%E4%BB%B7%26%26%E5%9B%BE%E5%83%8F%E7%9F%AB%E6%AD%A3%E6%B5%81%E7%A8%8B%E8%A7%A3%E6%9E%90%EF%BC%88%E9%99%84%E6%A0%87%E5%AE%9A%E7%A8%8B%E5%BA%8F%E5%92%8C%E6%A3%8B%E7%9B%98%E5%9B%BE%EF%BC%89%20-%20CSDN%E5%8D%9A%E5%AE%A2&dis=0&cmi=5&cce=true&dc=2&dtm=HTML_POST&dri=0">




    博主专栏




    展开



                <!-- 广告位:PC端-博客详情页右侧视窗1(feed流)-300*250 -->
                <script>
                    (function() {
                        var s = "_" + Math.random().toString(36).slice(2);
                        document.write('<div id="' + s + '"></div>');
                        (window.slotbydup=window.slotbydup || []).push({
                            id: '4770930',
                            container: s,
                            size: '300,250',
                            display: 'inlay-fix'
                        });
                    })();
                </script><div id="_dgf01knz5ub"></div><script charset="utf-8" src="http://pos.baidu.com/wcmm?di=4770930&amp;dri=0&amp;dis=0&amp;dai=0&amp;ps=1027x1273&amp;enu=encoding&amp;dcb=___adblockplus&amp;dtm=SSP_JSONP&amp;dvi=0.0&amp;dci=-1&amp;dpt=none&amp;tsr=0&amp;tpr=1510157985204&amp;ti=%E5%BC%A0%E6%AD%A3%E5%8F%8B%E7%9B%B8%E6%9C%BA%E6%A0%87%E5%AE%9AOpencv%E5%AE%9E%E7%8E%B0%E4%BB%A5%E5%8F%8A%E6%A0%87%E5%AE%9A%E6%B5%81%E7%A8%8B%26%26%E6%A0%87%E5%AE%9A%E7%BB%93%E6%9E%9C%E8%AF%84%E4%BB%B7%26%26%E5%9B%BE%E5%83%8F%E7%9F%AB%E6%AD%A3%E6%B5%81%E7%A8%8B%E8%A7%A3%E6%9E%90%EF%BC%88%E9%99%84%E6%A0%87%E5%AE%9A%E7%A8%8B%E5%BA%8F%E5%92%8C%E6%A3%8B%E7%9B%98%E5%9B%BE%EF%BC%89%20-%20CSDN%E5%8D%9A%E5%AE%A2&amp;ari=2&amp;dbv=2&amp;drs=1&amp;pcs=1903x984&amp;pss=1903x20196&amp;cfv=0&amp;cpl=4&amp;chi=1&amp;cce=true&amp;cec=UTF-8&amp;tlm=1510157985&amp;rw=984&amp;ltu=http%3A%2F%2Fblog.csdn.net%2Fdcrmg%2Farticle%2Fdetails%2F52939318&amp;ltr=http%3A%2F%2Fblog.csdn.net%2Fpinbodexiaozhu%2Farticle%2Fdetails%2F43373247&amp;ecd=1&amp;uc=1920x1050&amp;pis=-1x-1&amp;sr=1920x1080&amp;tcn=1510157985"></script><div id="_wepzk8xckx9" style=""><iframe width="300" frameborder="0" height="250" scrolling="no" src="http://pos.baidu.com/s?hei=250&amp;wid=300&amp;di=u3032528&amp;ltu=http%3A%2F%2Fblog.csdn.net%2Fdcrmg%2Farticle%2Fdetails%2F52939318&amp;ccd=24&amp;dri=1&amp;ps=1339x1273&amp;dis=0&amp;dtm=HTML_POST&amp;pcs=1903x984&amp;ant=0&amp;col=zh-CN&amp;cce=true&amp;ari=2&amp;dc=2&amp;drs=3&amp;cec=UTF-8&amp;tpr=1510157985369&amp;exps=111000&amp;tlm=1510157988&amp;psr=1920x1080&amp;pss=1903x4036&amp;ti=%E5%BC%A0%E6%AD%A3%E5%8F%8B%E7%9B%B8%E6%9C%BA%E6%A0%87%E5%AE%9AOpencv%E5%AE%9E%E7%8E%B0%E4%BB%A5%E5%8F%8A%E6%A0%87%E5%AE%9A%E6%B5%81%E7%A8%8B%26%26%E6%A0%87%E5%AE%9A%E7%BB%93%E6%9E%9C%E8%AF%84%E4%BB%B7%26%26%E5%9B%BE%E5%83%8F%E7%9F%AB%E6%AD%A3%E6%B5%81%E7%A8%8B%E8%A7%A3%E6%9E%90%EF%BC%88%E9%99%84%E6%A0%87%E5%AE%9A%E7%A8%8B%E5%BA%8F%E5%92%8C%E6%A3%8B%E7%9B%98%E5%9B%BE%EF%BC%89%20-%20CSDN%E5%8D%9A%E5%AE%A2&amp;par=1920x1050&amp;chi=1&amp;cja=false&amp;cmi=5&amp;dai=2&amp;tcn=1510157989&amp;cpl=4&amp;ltr=http%3A%2F%2Fblog.csdn.net%2Fpinbodexiaozhu%2Farticle%2Fdetails%2F43373247&amp;pis=-1x-1&amp;cfv=0&amp;cdo=-1"></iframe></div><script type="text/javascript" src="http://mpb1.iteye.com/bwocoltlyzdec.js"></script>
            </div>
        </div>
    
    </div>
    <div class="user-hotArticle">
        <h3>热门文章</h3>
        <ul class="hotArticle-list csdn-tracking-statistics" data-mod="popu_521">
    



  • 向量点乘(内积)和叉乘(外积、向量积)概念及几何意义解读
    41026


  • Opencv中Mat矩阵相乘——点乘、dot、mul运算详解
    22500


  • 张正友相机标定Opencv实现以及标定流程&&标定结果评价&&图像矫正流程解析(附标定程序和棋盘图)
    21015


  • OpenCV2.4.13+VS2012开发环境配置
    19707


  • C++ main函数中参数argc和argv含义及用法
    15682






  • 2
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值