zoukankan      html  css  js  c++  java
  • opencv单目摄像机标定

    #include <cv.h>
    #include <highgui.h>
    #include <iostream>
    #include <stdio.h>
    #include <stdlib.h>
     
    using namespace std;
     
     int n_boards=0;//图像数目  
     const int board_dt=20;//等20帧每棋盘视图 //int sn_board=0;//成功找到角点的图像数目
     int board_w;//图像的角点行列数   canshu
     int board_h; //canshu
    int main(int argc ,char * argv[])
    {
     /*读入图像*/ 
    board_w=7;      //canshu
    board_h=7;      //canshu
    n_boards=20;     //canshu
     
    int board_n=board_h*board_w;//每幅图像的角点数
    CvSize board_size=cvSize(board_w,board_h);//每幅图像的角点数
    CvCapture*capture;  
    capture=cvCreateCameraCapture(0);
    //assert(capture);              
     
    if(!capture) { printf("
    Couldn't open the camera
    "); return -1;}
    cvNamedWindow("MyCalib");
    cvNamedWindow("Raw Video");
     
     //allocate storage
     CvMat*object_points     = cvCreateMat(board_n*n_boards,3,CV_32FC1);
     CvMat*image_points      =cvCreateMat(board_n*n_boards,2,CV_32FC1);
     CvMat*point_counts      =cvCreateMat(n_boards,1,CV_32SC1);
     CvMat * camera_matrix   =cvCreateMat(3,3,CV_32FC1);//摄像机矩阵(内参数矩阵) 
     CvMat * distortion_coeffs=cvCreateMat(4,1,CV_32FC1);//畸变系数
     CvPoint2D32f*corners=new CvPoint2D32f[board_n];//一幅图像的角点数组
     int corner_count;
     int successes=0;     //   本文 successes就是 sn_board
     int step,frame=0;    
     
     IplImage*image=cvQueryFrame(capture);              
     IplImage *gray_image=cvCreateImage(cvGetSize(image),8,1);//创建头并分配数据
      
     //亚像素subpixel
     //capture corner views  loop  until  we've got n_boards
     //成功捕获(找到所有角点on the board)
     
     while (successes<n_boards)
     {   //skip every board_dt frames to allow user to move chessboard
        if(frame++%board_dt==0)
        {
            int found=cvFindChessboardCorners(image,board_size,corners,&corner_count,CV_CALIB_CB_ADAPTIVE_THRESH|CV_CALIB_CB_FILTER_QUADS);
     
            //精确到亚像素,绘制棋盘角点
            cvCvtColor(image,gray_image,CV_BGR2GRAY);           
            cvFindCornerSubPix(gray_image,corners,corner_count,cvSize(15,15),cvSize(-1,-1),cvTermCriteria(CV_TERMCRIT_EPS+CV_TERMCRIT_ITER,30,0.1));
            cvDrawChessboardCorners(image,board_size,corners,corner_count,found); 
            //cvShowImage("MyCalib",image);
     
            //如果得到一个好板,则把把它加入到我们的数据中
            if(corner_count==board_n){   //xin
                 cvShowImage( "Calibration", image ); //show in color if we did collect the image
                step=successes*board_n;   //xin
                for(int i=step,j=0;j<board_n;++i,++j){  
                    CV_MAT_ELEM(*image_points,float,i,0)  =corners[j].x;//CV_MAT_ELEM用来访问矩阵每个元素的宏,这个宏只对单通道矩阵有效,多通道会报错
                    CV_MAT_ELEM(*image_points,float,i,1)  =corners[j].y;//(要访问的矩阵,矩阵元素的类型,所要访问元素的行数,列数)
                                             //上两句是将检测到的点以坐标形式存储
                    CV_MAT_ELEM(*object_points,float,i,0) =float(j/board_w);
                    CV_MAT_ELEM(*object_points,float,i,1) =float(j%board_w);
                                            //上两句是将检测到的点的数目,以行列形式存储
                    CV_MAT_ELEM(*object_points,float,i,2) =0.0f;
                }
                 CV_MAT_ELEM(*point_counts,int,successes,0)=board_n;
                 successes++;
                 printf("Collected our %d of %d needed chessboard images
    ",successes,n_boards);
           }
           else
             cvShowImage( "Calibration", gray_image );//Show Gray if we didn't collect the image
          }//end skip board_dt between chessboard capture
         
        //暂停模块
         int c = cvWaitKey(15);
         if(c == 'p'){ 
           c = 0;
           while(c != 'p' && c != 27){
                c = cvWaitKey(250);
           }
         }
         if(c == 27)
            return 0;
        image = cvQueryFrame( capture ); //Get next image
        cvShowImage("Raw Video", image);
      } //END COLLECTION WHILE LOOP.
       cvDestroyWindow("Calibration");
        printf("
    
    *** CALLIBRATING THE CAMERA...");
     
     
         //重新赋值,又重新分配了矩阵空间
      CvMat * object_points0= cvCreateMat(board_n*successes,3,CV_32FC1);
      CvMat * image_points0=cvCreateMat(board_n*successes,2,CV_32FC1);
      CvMat * point_counts0=cvCreateMat(successes,1,CV_32SC1);    
      //transfer THE points INTO THE correct size matrices
       for (int i=0;i<successes*board_n;i++)//board_n为每幅图像的角点数*sn_board为成功找到角点的图像数目
        {
        CV_MAT_ELEM(*image_points0,float,i,0)=CV_MAT_ELEM(*image_points,float,i,0);
        CV_MAT_ELEM(*image_points0,float,i,1)=CV_MAT_ELEM(*image_points,float,i,1);
        CV_MAT_ELEM(*object_points0,float,i,0)=CV_MAT_ELEM(*object_points,float,i,0);
        CV_MAT_ELEM(*object_points0,float,i,1)=CV_MAT_ELEM(*object_points,float,i,1);
        CV_MAT_ELEM(*object_points0,float,i,2)=0.0f;
        }
      for (int i=0;i<successes;i++)
       {
        CV_MAT_ELEM(*point_counts0,int,i,0)=CV_MAT_ELEM(*point_counts,int,i,0);
       }
       cvReleaseMat(&object_points);//世界坐标点
       cvReleaseMat(&point_counts); //每张图像中的角点数
       cvReleaseMat(&image_points); //图像坐标点
       //使用cvReleaseMat函数之后,系统将释放刚才载入矩阵的内存空间(也即这个矩阵已经不在内存中了)
    
       // At this point we have all of the chessboard corners we need 
       // Initialize the intrinsic matrix such that the two focal
      // lengths have a ratio of 1.0
        CV_MAT_ELEM( *camera_matrix, float, 0, 0 ) = 1.0f;  
        CV_MAT_ELEM( *camera_matrix, float, 1, 1 ) = 1.0f;  
      //CALIBRATE THE CAMERA!
      cvCalibrateCamera2(                                 
          object_points0, image_points0,               
          point_counts0,  cvGetSize( image ),              
          camera_matrix, distortion_coeffs,
          NULL, NULL,0  //CV_CALIB_FIX_ASPECT_RATIO
      );
     
       // SAVE THE INTRINSICS AND DISTORTIONS     xin
       printf("......保存内部参数与畸变参数
    ");
       cvSave("camera_matrix1111.xml",camera_matrix);
       cvSave("distortion_coeffs.xml",distortion_coeffs);
     
       // EXAMPLE OF LOADING THESE MATRICES BACK IN:      xin
      CvMat *intrinsic = (CvMat*)cvLoad("Intrinsics.xml");
      CvMat *distortion = (CvMat*)cvLoad("Distortion.xml");
     
     
      // Build the undistort map which we will use for all
      // subsequent frames.建立不失真的图map
      //
      IplImage* mapx = cvCreateImage( cvGetSize(image), IPL_DEPTH_32F, 1 );
      IplImage* mapy = cvCreateImage( cvGetSize(image), IPL_DEPTH_32F, 1 );
      cvInitUndistortMap(intrinsic,distortion,mapx, mapy);
     
      // Just run the camera to the screen, now showing the raw and
      // the undistorted image.
      //
      cvNamedWindow( "Undistort" );
      while(image) {
        IplImage *t = cvCloneImage(image);
        cvShowImage( "Raw Video", image ); // Show raw image
        cvRemap( t, image, mapx, mapy );     // Undistort image
        cvReleaseImage(&t);
        cvShowImage("Undistort", image);     // Show corrected image
     
      //Handle pause/unpause and ESC
        int c = cvWaitKey(15);
        if(c == 'p'){
           c = 0;
           while(c != 'p' && c != 27){
                c = cvWaitKey(250);
           }
        }
         if(c == 27)
            break;
        image = cvQueryFrame( capture );
      }
     
      return 0;
    }
  • 相关阅读:
    jquery,日常 记录知识 点 (选择器的引用类型)
    jQuery之map()和get() map().get().join意思
    转 谈谈JS里的{ }大括号和[ ]中括号的用法,理解后就可以看懂JSON结构了。
    CSS属性
    CSS3属性
    写网页的随意 记录要点
    css,查询相应标签,div等
    CSS ,浮动,clear记录,和一些转载别处
    linux下如何关闭防火墙?如何查看防火墙当前的状态
    Objective-C和Swift混合编程开发
  • 原文地址:https://www.cnblogs.com/Jessica-jie/p/6126462.html
Copyright © 2011-2022 走看看