码迷,mamicode.com
首页 > 其他好文 > 详细

利用opencv进行相机标定程序

时间:2014-12-10 15:51:07      阅读:136      评论:0      收藏:0      [点我收藏+]

标签:style   blog   io   ar   color   sp   for   on   文件   

  1 #include "Stafx.h"
  2 
  3 int board_w=12;   //棋盘上有13个格子,那么角点的数目12
  4 int board_h=12;
  5 int image_count=23;  //图片的总张数
  6 int main(int argc, char** argv) 
  7 {
  8     int count=0;
  9     int board_n=board_h*board_w;  //一张图像上,角点的数目
 10     CvSize board_sz=cvSize(board_w,board_h);
 11     CvMat* object_points=cvCreateMat(image_count*board_n,3,CV_32FC1);  //实际坐标系(以棋盘左上角第一个角点为坐标原点),角点的坐标,单位是方块
 12     CvMat* image_points=cvCreateMat(image_count*board_n,2,CV_32FC1);   //在图像上找到角点的坐标,坐标原点图像左上角,单位像素
 13     CvMat* point_counts=cvCreateMat(board_n,1,CV_32SC1);    //每个图像上角点个数
 14 
 15     
 16     int a=0;    //累计图像上所有角点被找到图像的张数
 17     while (count++<image_count)
 18     {
 19         std::string filename="E:\\软件学习\\LearningOpenCV_Code\\calibration\\";
 20         char str[10];
 21         itoa(count,str,10);//转换为字符串
 22         std::string str1;
 23         int length=strlen(str);
 24         *(str+length)=.;
 25         *(str+length+1)=j;
 26         *(str+length+2)=p;
 27         *(str+length+3)=g;
 28         *(str+length+4)=\0;
 29         str1=str;
 30         filename+=str1;
 31         IplImage* src=cvLoadImage(filename.c_str(),CV_LOAD_IMAGE_UNCHANGED);
 32         IplImage* gray=cvCreateImage(cvGetSize(src),IPL_DEPTH_8U,1);
 33         cvCvtColor(src,gray,CV_RGB2GRAY);
 34         CvPoint2D32f* corners=new CvPoint2D32f[board_n];  //一张图像上角点的坐标
 35         int corner_count;     //一张图像上角点的数目
 36         int found=cvFindChessboardCorners(src,board_sz,corners,&corner_count,
 37                                 CV_CALIB_CB_ADAPTIVE_THRESH|CV_CALIB_CB_FILTER_QUADS);//找到棋盘的角点,如果所有角点找到返回1,否则返回0,这里指的是所有的角点
 38         
 39         cvFindCornerSubPix(gray, corners, corner_count, cvSize(11,11),cvSize(-1,-1), 
 40                             cvTermCriteria(CV_TERMCRIT_EPS+CV_TERMCRIT_ITER,30, 0.1)); //寻找亚素点,gray一定要是8位单通道的图像
 41         cvDrawChessboardCorners(src,board_sz,corners,corner_count,found);             //将角点画出,src一定要是彩色图像
 42         //cvShowImage("1",src);
 43         //cvWaitKey();
 44         if (corner_count==board_n)  //一张图像上所有角点被找到
 45         {
 46             int step=a*board_n;  //第k幅角点全部找到图像上角点的存储的起始地址
 47             int j=0;
 48             for (int i=step;j<corner_count;i++,j++)
 49             {
 50                 CV_MAT_ELEM(*object_points,float,i,0)=j/board_w;  //角点的横坐标,单位不是像素,而是以棋盘上每个方块为一个单位
 51                 CV_MAT_ELEM(*object_points,float,i,1)=j%board_w;  //角点的纵坐标,每个方块为一个单位
 52                 CV_MAT_ELEM(*object_points,float,i,2)=0;      //齐次坐标,表示点
 53                 CV_MAT_ELEM(*image_points,float,i,0)=corners[j].x; //图像坐标系的坐标
 54                 CV_MAT_ELEM(*image_points,float,i,1)=corners[j].y;
 55             };
 56             CV_MAT_ELEM(*point_counts,int,a,0)=board_n;
 57             a++;
 58         }
 59     }
 60     //由于图像中存在所有角点未找到的情况,所以上面object_points的空间未存满,需要重新定义
 61     CvMat* object_points2=cvCreateMat(a*board_n,3,CV_32FC1); 
 62     CvMat* image_points2=cvCreateMat(a*board_n,2,CV_32FC1); 
 63     CvMat* point_counts2=cvCreateMat(a,1,CV_32SC1);    
 64     CvMat* intrinsic_matrix=cvCreateMat(3,3,CV_32FC1);   //相机内参数矩阵
 65     CvMat* distortion_coeffs=cvCreateMat(5,1,CV_32FC1);  //畸变系数矩阵
 66     CvMat* rotation_vector=cvCreateMat(a,3,CV_32FC1);    //旋转矩阵
 67     CvMat* translation_vector=cvCreateMat(a,3,CV_32FC1);  //平移矩阵
 68     for (int i=0;i<a*board_n;i++)
 69     {
 70         CV_MAT_ELEM(*object_points2,float,i,0)=CV_MAT_ELEM(*object_points,float,i,0);
 71         CV_MAT_ELEM(*object_points2,float,i,1)=CV_MAT_ELEM(*object_points,float,i,1);
 72         CV_MAT_ELEM(*object_points2,float,i,2)=0;
 73         CV_MAT_ELEM(*image_points2,float,i,0)=CV_MAT_ELEM(*image_points,float,i,0);
 74         CV_MAT_ELEM(*image_points2,float,i,1)=CV_MAT_ELEM(*image_points,float,i,1);    
 75     }
 76     for(int i=0;i<a;i++)
 77         CV_MAT_ELEM(*point_counts2,int,i,0)=CV_MAT_ELEM(*point_counts,int,i,0);
 78     cvReleaseMat(&object_points);
 79     cvReleaseMat(&image_points);
 80     cvReleaseMat(&point_counts);
 81     //内置参数矩阵设置,初始化
 82     CV_MAT_ELEM(*intrinsic_matrix,float,0,0)=1.0;
 83     CV_MAT_ELEM(*intrinsic_matrix,float,1,1)=1.0;
 84     //校正相机参数,cvSize(1600,1200)为输入图像的真实长度和宽度,单位为像素
 85     cvCalibrateCamera2(object_points2,image_points2,point_counts2,cvSize(1600,1200),
 86                             intrinsic_matrix,distortion_coeffs,rotation_vector,translation_vector,CV_CALIB_FIX_ASPECT_RATIO);
 87     //图像校正
 88     IplImage* mapx=cvCreateImage(cvSize(1600,1200),IPL_DEPTH_32F,1);
 89     IplImage* mapy=cvCreateImage(cvSize(1600,1200),IPL_DEPTH_32F,1);
 90     cvInitUndistortMap(intrinsic_matrix,distortion_coeffs,mapx,mapy);
 91     IplImage* test_image=cvLoadImage("E:\\软件学习\\LearningOpenCV_Code\\calibration\\22.jpg",CV_LOAD_IMAGE_UNCHANGED);
 92     if (!test_image)
 93     {
 94         std::cout<<"error"<<std::endl;
 95     }
 96     cvShowImage("原图像",test_image);
 97     IplImage* t=cvCloneImage(test_image);
 98     cvRemap(t,test_image,mapx,mapy);
 99     cvShowImage("校正后图像",test_image);
100     cvWaitKey();
101     return 0;
102 }

测试图片:opencv课后习题答案中LearningOpencv_Code中calibration文件中的图片

 

利用opencv进行相机标定程序

标签:style   blog   io   ar   color   sp   for   on   文件   

原文地址:http://www.cnblogs.com/gzy-zju-edu/p/4155390.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!