极简OpenCV的相机标定代码

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

至于自定义头文件“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;
	//创建棋盘规格Size
	CvSize board_sz=CvSize();
	board_sz.width=b_w;
	board_sz.height=b_h;
	//创建搜索窗Size
	CvSize winSize=CvSize();
	winSize.width=11;
	winSize.height=11;
	//创建拒绝域Size
	CvSize 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);
}


猜你喜欢

转载自blog.csdn.net/cyoubo/article/details/48286543