首页 > 代码库 > 利用opencv进行相机标定程序

利用opencv进行相机标定程序

  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=http://www.mamicode.com/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进行相机标定程序