首页 > 代码库 > 利用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进行相机标定程序
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。