极简OpenCV的相机标定代码

来源:互联网 发布:淘宝网上书店首页 编辑:程序博客网 时间:2024/04/30 03:25

            照例,在正式贴代码之前要说一段废话。这个是我毕业论文做的东西,之前也是在这个算法中做了很多测试,后来发现要用的时候,系统重装而且没有备份。所以这次写了一个极简的标定程序,用于临时的项目测试。

至于自定义头文件“CommonHead.h”就只是一个void std_calibration(char**);的申明,就不贴代码了。

/*利用OpenCV完成相机的标定@author cyoubo@DateTime 2015.9.8@OpenCV Version 2.4.10*/#include <cv.h>#include <highgui.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include "CommonHead.h"void std_calibration(char** path){//分别表示棋盘格的行数、列数、张数、共计角点数、有效棋盘影像张数、当前处理影像编号int b_w=6,b_h=9,n_b=5,b_n,success=0,step=0;//计算共计棋盘角点数b_n=b_w*b_h;//创建棋盘规格SizeCvSize board_sz=CvSize();board_sz.width=b_w;board_sz.height=b_h;//创建搜索窗SizeCvSize winSize=CvSize();winSize.width=11;winSize.height=11;//创建拒绝域SizeCvSize noSize=CvSize();noSize.width=-1;noSize.height=-1;//创建影像尺寸Size,具体值等待后期输入CvSize imageSize=CvSize();//创建迭代需求对象CvTermCriteria term;term.type=CV_TERMCRIT_EPS+CV_TERMCRIT_ITER;term.epsilon=0.1;term.max_iter=30;CvMat* image_point=cvCreateMat(n_b*b_n,2,CV_32FC1);CvMat* object_point=cvCreateMat(n_b*b_n,3,CV_32FC1);CvMat* point_count=cvCreateMat(n_b,1,CV_32SC1);CvMat* Intrinsic=cvCreateMat(3,3,CV_32FC1);CvMat* Distortion=cvCreateMat(5,1,CV_32FC1);//循环获取影像中的角点for(int index=0;index<n_b;index++){int conner_count;CvPoint2D32f* corners=new CvPoint2D32f[b_n];IplImage  *image =cvLoadImage(path[index]);imageSize=cvGetSize(image);IplImage *gray_image=cvCreateImage(imageSize,8,1);cvCvtColor(image,gray_image,CV_BGR2GRAY);int found=cvFindChessboardCorners(gray_image,board_sz,corners,&conner_count,CV_CALIB_CB_ADAPTIVE_THRESH|CV_CALIB_CB_FILTER_QUADS);if(conner_count==b_n){cvFindCornerSubPix(gray_image,corners,conner_count,winSize,noSize,term);if(b_n==conner_count){step=success*b_n;for (int i = step, j = 0; j < b_n; ++i, ++j) {  CV_MAT_ELEM(*image_point, float, i, 0) = corners[j].x;  CV_MAT_ELEM(*image_point, float, i, 1) = corners[j].y;  CV_MAT_ELEM(*object_point, float, i, 0) = (j/b_w);  CV_MAT_ELEM(*object_point, float, i, 1) = (j % b_w);  CV_MAT_ELEM(*object_point, float, i, 2) = 0.0f;  }  CV_MAT_ELEM(*point_count, int, success, 0) = b_n;  success++;  //如果个数一致,则认为改张影像有效}}}//依据有效影像重新创建标定解算的像控点对CvMat* image_point2 = cvCreateMat(b_n*(success), 2, CV_32FC1);  CvMat* object_point2 = cvCreateMat(b_n*(success), 3, CV_32FC1);  CvMat* point_count2 = cvCreateMat((success), 1, CV_32SC1);  for (int i = 0; i < success*b_n; ++i){CV_MAT_ELEM(*image_point2, float, i, 0) = CV_MAT_ELEM(*image_point, float, i, 0);  CV_MAT_ELEM(*image_point2, float, i, 1) = CV_MAT_ELEM(*image_point, float, i, 1);  CV_MAT_ELEM(*object_point2, float, i, 0) = CV_MAT_ELEM(*object_point, float, i, 0);  CV_MAT_ELEM(*object_point2, float, i, 1) = CV_MAT_ELEM(*object_point, float, i, 1);  CV_MAT_ELEM(*object_point2, float, i, 2) = CV_MAT_ELEM(*object_point, float, i, 2);  }  for (int i = 0; i < success; ++i){  CV_MAT_ELEM(*point_count2, int, i, 0) = CV_MAT_ELEM(*point_count, int, i, 0);  }  cvReleaseMat(&object_point);  cvReleaseMat(&image_point);  cvReleaseMat(&point_count);  //设置内方位元素中主距分量的初始值为1,并开始迭代解算CV_MAT_ELEM(*Intrinsic, float, 0, 0) = 1.0f;  CV_MAT_ELEM(*Intrinsic, float, 1, 1) = 1.0f;  double Rmse=cvCalibrateCamera2(  object_point2,  image_point2,  point_count2,  board_sz,  Intrinsic,  Distortion,  NULL,  NULL,  0 ); printf("the rms is %f",Rmse);cvSave("G:\\Intrinsic.xml", Intrinsic);  cvSave("G:\\Distortion.xml", Distortion); cvReleaseMat(&image_point2);  cvReleaseMat(&object_point2);  cvReleaseMat(&point_count2);  //依据标定结果重绘影像IplImage *mapx=cvCreateImage(imageSize,IPL_DEPTH_32F,1);IplImage *mapy=cvCreateImage(imageSize,IPL_DEPTH_32F,1);cvInitUndistortMap(Intrinsic,Distortion,mapx,mapy);IplImage *src_map=cvLoadImage(path[1]);IplImage *dst_map=cvCloneImage(src_map);cvRemap(src_map,dst_map,mapx,mapy);cvSaveImage("G:\\result2.jpeg",dst_map);cvReleaseImage(&src_map);cvReleaseImage(&dst_map);cvReleaseImage(&mapx);cvReleaseImage(&mapy);}


0 0
原创粉丝点击