opencv3 鱼眼相机标定

鱼眼镜头模型 
  鱼眼镜头的内参模型可以表示为 这里写图片描述,与普通镜头的内参一样,但畸变参数不同,为这里写图片描述,含义如下:

  设(X,Y,Z)为一个三维坐标点,投影在图像上的二维坐标为(u,v),如果不考虑畸变,投影关系如下: 
                                                                        这里写图片描述 
  R和t分别代表相机外参中的旋转矩阵和平移向量。 
                                                                           这里写图片描述

标定流程 

  首先调用OpenCV的FindChessboardCorners()来寻找图像上的标定板的角点,再根据标定板的尺寸指定这些角点对应的三维点的三维坐标,再调用fisheye::calibrate()来进行标定,利用标定结果中的内参和畸变参数调用fisheye::undistortImage()对图像做去畸变操作。最后调用一张待测试的畸变图片利用标定结果进行畸变校正。  

<code class="hljs cpp has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//运行环境 VS2012+opencv3.0</span>
<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#include <opencv2\opencv.hpp></span>
<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#include <fstream></span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">using</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">namespace</span> <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">std</span>;
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">using</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">namespace</span> cv;

<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> main()
{
    ofstream fout(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"caliberation_result.txt"</span>);  <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/**    保存定标结果的文件     **/</span>

    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/************************************************************************  
           读取每一幅图像,从中提取出角点,然后对角点进行亚像素精确化  
    *************************************************************************/</span>   
    <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">cout</span><<<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"开始提取角点………………"</span><<endl; 
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> image_count=  <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">25</span>;                    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/****    图像数量     ****/</span>    
    Size board_size = Size(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">9</span>,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">6</span>);            <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/****    定标板上每行、列的角点数       ****/</span>  
    <span class="hljs-stl_container" style="box-sizing: border-box;"><span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">vector</span><Point2f></span> corners;                  <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/****    缓存每幅图像上检测到的角点       ****/</span>
    <span class="hljs-stl_container" style="box-sizing: border-box;"><span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">vector</span><<span class="hljs-stl_container" style="box-sizing: border-box;"><span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">vector</span><Point2f></span>></span>  corners_Seq;    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/****  保存检测到的所有角点       ****/</span>   
    <span class="hljs-stl_container" style="box-sizing: border-box;"><span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">vector</span><Mat></span>  image_Seq;
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> successImageNum = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>;                <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/****   成功提取角点的棋盘图数量    ****/</span>

    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> count = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>;
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span>( <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> i = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>;  i != image_count ; i++)
    {
        <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">cout</span><<<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Frame #"</span><<i+<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span><<<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"..."</span><<endl;
        <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">string</span> imageFileName;
        <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">std</span>::<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">stringstream</span> StrStm;
        StrStm<<i+<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>;
        StrStm>>imageFileName;
        imageFileName += <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">".jpg"</span>;
        cv::Mat image = imread(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"img"</span>+imageFileName); 
        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/* 提取角点 */</span>   
        Mat imageGray;
        cvtColor(image, imageGray , CV_RGB2GRAY);
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">bool</span> patternfound = findChessboardCorners(image, board_size, corners,CALIB_CB_ADAPTIVE_THRESH + CALIB_CB_NORMALIZE_IMAGE+ 
            CALIB_CB_FAST_CHECK );
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (!patternfound)   
        {   
            <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">cout</span><<<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"can not find chessboard corners!\n"</span>;  
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">continue</span>;
            <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">exit</span>(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>);   
        } 
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span>
        {   
            <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/* 亚像素精确化 */</span>
            cornerSubPix(imageGray, corners, Size(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">11</span>, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">11</span>), Size(-<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>, -<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>), TermCriteria(CV_TERMCRIT_EPS + CV_TERMCRIT_ITER, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">30</span>, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0.1</span>));
            <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/* 绘制检测到的角点并保存 */</span>
            Mat imageTemp = image.clone();
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span> (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> j = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>; j < corners.size(); j++)
            {
                circle( imageTemp, corners[j], <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">10</span>, Scalar(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">255</span>), <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">8</span>, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>);
            }
            <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">string</span> imageFileName;
            <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">std</span>::<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">stringstream</span> StrStm;
            StrStm<<i+<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>;
            StrStm>>imageFileName;
            imageFileName += <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"_corner.jpg"</span>;
            imwrite(imageFileName,imageTemp);
            <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">cout</span><<<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Frame corner#"</span><<i+<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span><<<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"...end"</span><<endl;

            count = count + corners.size();
            successImageNum = successImageNum + <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>;
            corners_Seq.push_back(corners);
        }   
        image_Seq.push_back(image);
    }   
    <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">cout</span><<<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"角点提取完成!\n"</span>; 
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/************************************************************************  
           摄像机定标  
    *************************************************************************/</span>   
    <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">cout</span><<<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"开始定标………………"</span><<endl;  
    Size square_size = Size(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">20</span>,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">20</span>);     
    <span class="hljs-stl_container" style="box-sizing: border-box;"><span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">vector</span><<span class="hljs-stl_container" style="box-sizing: border-box;"><span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">vector</span><Point3f></span>></span>  object_Points;        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/****  保存定标板上角点的三维坐标   ****/</span>

    Mat image_points = Mat(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>, count, CV_32FC2, Scalar::all(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>));  <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/*****   保存提取的所有角点   *****/</span>
    <span class="hljs-stl_container" style="box-sizing: border-box;"><span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">vector</span><<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span>></span>  point_counts;                                                         
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/* 初始化定标板上角点的三维坐标 */</span>
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span> (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> t = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>; t<successImageNum; t++)
    {
        <span class="hljs-stl_container" style="box-sizing: border-box;"><span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">vector</span><Point3f></span> tempPointSet;
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span> (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> i = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>; i<board_size.height; i++)
        {
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span> (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> j = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>; j<board_size.width; j++)
            {
                <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/* 假设定标板放在世界坐标系中z=0的平面上 */</span>
                Point3f tempPoint;
                tempPoint.x = i*square_size.width;
                tempPoint.y = j*square_size.height;
                tempPoint.z = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>;
                tempPointSet.push_back(tempPoint);
            }
        }
        object_Points.push_back(tempPointSet);
    }
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span> (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> i = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>; i< successImageNum; i++)
    {
        point_counts.push_back(board_size.width*board_size.height);
    }
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/* 开始定标 */</span>
    Size image_size = image_Seq[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>].size();
    cv::Matx33d intrinsic_matrix;    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/*****    摄像机内参数矩阵    ****/</span>
    cv::Vec4d distortion_coeffs;     <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/* 摄像机的4个畸变系数:k1,k2,k3,k4*/</span>
    <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">std</span>::<span class="hljs-stl_container" style="box-sizing: border-box;"><span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">vector</span><cv::Vec3d></span> rotation_vectors;                           <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/* 每幅图像的旋转向量 */</span>
    <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">std</span>::<span class="hljs-stl_container" style="box-sizing: border-box;"><span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">vector</span><cv::Vec3d></span> translation_vectors;                        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/* 每幅图像的平移向量 */</span>
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> flags = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>;
    flags |= cv::fisheye::CALIB_RECOMPUTE_EXTRINSIC;
    flags |= cv::fisheye::CALIB_CHECK_COND;
    flags |= cv::fisheye::CALIB_FIX_SKEW;
    fisheye::calibrate(object_Points, corners_Seq, image_size, intrinsic_matrix, distortion_coeffs, rotation_vectors, translation_vectors, flags, cv::TermCriteria(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">3</span>, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">20</span>, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1e-6</span>));
    <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">cout</span><<<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"定标完成!\n"</span>;   

    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/************************************************************************  
           对定标结果进行评价  
    *************************************************************************/</span>   
    <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">cout</span><<<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"开始评价定标结果………………"</span><<endl;   
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">double</span> total_err = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0.0</span>;                   <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/* 所有图像的平均误差的总和 */</span>   
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">double</span> err = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0.0</span>;                        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/* 每幅图像的平均误差 */</span>   
    <span class="hljs-stl_container" style="box-sizing: border-box;"><span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">vector</span><Point2f></span>  image_points2;             <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/****   保存重新计算得到的投影点    ****/</span>   

    <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">cout</span><<<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"每幅图像的定标误差:"</span><<endl;   
    <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">cout</span><<<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"每幅图像的定标误差:"</span><<endl<<endl;   
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span> (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> i=<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>;  i<image_count;  i++) 
    {
        <span class="hljs-stl_container" style="box-sizing: border-box;"><span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">vector</span><Point3f></span> tempPointSet = object_Points[i];
        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/****    通过得到的摄像机内外参数,对空间的三维点进行重新投影计算,得到新的投影点     ****/</span>
        fisheye::projectPoints(tempPointSet, image_points2, rotation_vectors[i], translation_vectors[i], intrinsic_matrix, distortion_coeffs);
        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/* 计算新的投影点和旧的投影点之间的误差*/</span>  
        <span class="hljs-stl_container" style="box-sizing: border-box;"><span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">vector</span><Point2f></span> tempImagePoint = corners_Seq[i];
        Mat tempImagePointMat = Mat(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>,tempImagePoint.size(),CV_32FC2);
        Mat image_points2Mat = Mat(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>,image_points2.size(), CV_32FC2);
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span> (size_t i = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span> ; i != tempImagePoint.size(); i++)
        {
            image_points2Mat.at<Vec2f>(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>,i) = Vec2f(image_points2[i].x, image_points2[i].y);
            tempImagePointMat.at<Vec2f>(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>,i) = Vec2f(tempImagePoint[i].x, tempImagePoint[i].y);
        }
        err = norm(image_points2Mat, tempImagePointMat, NORM_L2);
        total_err += err/=  point_counts[i];   
        <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">cout</span><<<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"第"</span><<i+<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span><<<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"幅图像的平均误差:"</span><<err<<<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"像素"</span><<endl;   
        fout<<<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"第"</span><<i+<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span><<<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"幅图像的平均误差:"</span><<err<<<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"像素"</span><<endl;   
    }   
    <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">cout</span><<<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"总体平均误差:"</span><<total_err/image_count<<<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"像素"</span><<endl;   
    fout<<<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"总体平均误差:"</span><<total_err/image_count<<<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"像素"</span><<endl<<endl;   
    <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">cout</span><<<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"评价完成!"</span><<endl;   

    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/************************************************************************  
           保存定标结果  
    *************************************************************************/</span>   
    <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">cout</span><<<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"开始保存定标结果………………"</span><<endl;       
    Mat rotation_matrix = Mat(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">3</span>,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">3</span>,CV_32FC1, Scalar::all(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>)); <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/* 保存每幅图像的旋转矩阵 */</span>   

    fout<<<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"相机内参数矩阵:"</span><<endl;   
    fout<<intrinsic_matrix<<endl;   
    fout<<<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"畸变系数:\n"</span>;   
    fout<<distortion_coeffs<<endl;   
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span> (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> i=<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>; i<image_count; i++) 
    { 
        fout<<<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"第"</span><<i+<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span><<<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"幅图像的旋转向量:"</span><<endl;   
        fout<<rotation_vectors[i]<<endl;   

        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/* 将旋转向量转换为相对应的旋转矩阵 */</span>   
        Rodrigues(rotation_vectors[i],rotation_matrix);   
        fout<<<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"第"</span><<i+<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span><<<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"幅图像的旋转矩阵:"</span><<endl;   
        fout<<rotation_matrix<<endl;   
        fout<<<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"第"</span><<i+<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span><<<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"幅图像的平移向量:"</span><<endl;   
        fout<<translation_vectors[i]<<endl;   
    }   
    <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">cout</span><<<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"完成保存"</span><<endl; 
    fout<<endl;


    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/************************************************************************  
           显示定标结果  
    *************************************************************************/</span>
    Mat mapx = Mat(image_size,CV_32FC1);
    Mat mapy = Mat(image_size,CV_32FC1);
    Mat R = Mat::eye(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">3</span>,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">3</span>,CV_32F);
    <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">cout</span><<<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"保存矫正图像"</span><<endl;
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span> (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> i = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span> ; i != image_count ; i++)
    {
        <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">cout</span><<<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Frame #"</span><<i+<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span><<<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"..."</span><<endl;
        Mat newCameraMatrix = Mat(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">3</span>,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">3</span>,CV_32FC1,Scalar::all(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>));
        fisheye::initUndistortRectifyMap(intrinsic_matrix,distortion_coeffs,R,intrinsic_matrix,image_size,CV_32FC1,mapx,mapy);
        Mat t = image_Seq[i].clone();
        cv::remap(image_Seq[i],t,mapx, mapy, INTER_LINEAR);
        <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">string</span> imageFileName;
        <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">std</span>::<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">stringstream</span> StrStm;
        StrStm<<i+<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>;
        StrStm>>imageFileName;
        imageFileName += <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"_d.jpg"</span>;
        imwrite(imageFileName,t);
    }
    <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">cout</span><<<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"保存结束"</span><<endl;


    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/************************************************************************  
           测试一张图片  
    *************************************************************************/</span>
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>)
    {
        <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">cout</span><<<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"TestImage ..."</span><<endl;
        Mat newCameraMatrix = Mat(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">3</span>,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">3</span>,CV_32FC1,Scalar::all(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>));
        Mat testImage = imread(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"a.jpg"</span>,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>);
        fisheye::initUndistortRectifyMap(intrinsic_matrix,distortion_coeffs,R,intrinsic_matrix,image_size,CV_32FC1,mapx,mapy);
        Mat t = testImage.clone();
        cv::remap(testImage,t,mapx, mapy, INTER_LINEAR);

        imwrite(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"TestOutput.jpg"</span>,t);
        <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">cout</span><<<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"保存结束"</span><<endl;
    }


    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>;
}</code>
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
鱼眼相机标定是通过对鱼眼镜头进行参数校准,从而纠正图像的畸变。OpenCV提供了一个函数来执行鱼眼相机标定,该函数是`cv2.fisheye.calibrate()`。 首先,你需要准备一组鱼眼相机的标定图像,这些图像包含了不同的场景和角度。然后,你可以使用`cv2.findChessboardCorners()`函数来检测标定图像中的棋盘格角点。 一旦你获得了棋盘格角点的像素坐标,你可以使用`cv2.fisheye.calibrate()`函数来进行鱼眼相机的标定。此函数将返回相机矩阵、畸变系数、旋转矩阵和平移向量等参数。 以下是一个简单的示例代码: ```python import cv2 import numpy as np # 准备标定图像和棋盘格参数 images = [...] # 标定图像列表 pattern_size = (9, 6) # 棋盘格内角点数目 # 检测棋盘格角点 obj_points = [] # 3D 空间中的棋盘格角点 img_points = [] # 2D 图像平面上的棋盘格角点 for image in images: gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) ret, corners = cv2.findChessboardCorners(gray, pattern_size) if ret: obj_points.append(np.zeros((pattern_size[0] * pattern_size[1], 3), np.float32)) obj_points[-1][:, :2] = np.mgrid[0:pattern_size[0], 0:pattern_size[1]].T.reshape(-1, 2) img_points.append(corners) # 鱼眼相机标定 ret, K, D, rvecs, tvecs = cv2.fisheye.calibrate(obj_points, img_points, gray.shape[::-1], None, None) # 打印标定结果 print("相机矩阵:\n", K) print("畸变系数:\n", D) print("旋转向量:\n", rvecs) print("平移向量:\n", tvecs) ``` 请注意,鱼眼相机标定的准确性取决于标定图像的质量和角点检测的准确性。因此,为了获得更好的标定结果,你可能需要使用更多的标定图像,并确保棋盘格角点在图像中被正确检测到。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值