zoukankan      html  css  js  c++  java
  • opencv标定程序(改动)

    转载请注明来自:http://blog.csdn.net/zhouyelihua/article/details/38421377

    资源下载见:点击打开链接

    百度云盘免积分下载:https://pan.baidu.com/s/1bzy20u

    有关于标定的基本原理详见点击打开链接


     看到本文被转载非常多次非常高兴可是之前的代码有点小问题且不易懂。于是乎写了一个简洁的代码

    首先介绍用本程序标定的步骤:

    1,。

    拍完图片之后将图片重命名为下图所看到的形式


    2.将照片放在程序的cam目录下


    3.然后执行程序。依照提示输入信息


    4.最后在output目录找到result_data_no_optim.txt


    代码例如以下:

    //author:YeahPingYE
    //function:auto calibration
    //time:2014/11/25
    //
    //
    #include<highgui.h>
    #include<cv.h>
    #include<iostream>
    #include<fstream>
    using namespace std;
    
    void save_result(CvMat*cam_rotation_all, CvMat*cam_translation_vector_all,
    	CvMat*cam_intrinsic_matrix, CvMat*cam_distortion_coeffs,char*pathc,int sucesses);
    int main()
    {
    	/*initialation
    	//input:the number of images......num_image
    	//      prj_board_w,prj_board_h
    	//      cam_board_w,cam_board_h
    	*/
    	CvMat*cam_object_points2;
      CvMat*cam_image_points2;
      int cam_board_n;
      int successes = 0;
    	int img_num, cam_board_w, cam_board_h,cam_Dx,cam_Dy;
    	cout << "输入的图像的组数
    ";
    	cin >> img_num;
    	cout << "输入**真实**棋盘格的##横轴##方向的角点个数
    ";
    	cin >> cam_board_w;
    	cout << "输入**真实**棋盘格的##纵轴##方向的角点个数
    ";
    	cin >> cam_board_h;
    	cout << "输入**真实**棋盘格的##横轴##方向的长度
    ";
    	cin >> cam_Dx;
    	cout << "输入**真实**棋盘格的##纵轴##方向的长度
    ";
    	cin >> cam_Dy;
    	cam_board_n = cam_board_w*cam_board_h;
    	/*
    	//init
    	//
    	//
    	*/
    
    	//camera init
    	CvSize cam_board_sz = cvSize(cam_board_w, cam_board_h);
    	CvMat*cam_image_points = cvCreateMat(cam_board_n*(img_num), 2, CV_32FC1);
    	CvMat*cam_object_points = cvCreateMat(cam_board_n*(img_num), 3, CV_32FC1);
    	CvMat*cam_point_counts = cvCreateMat((img_num), 1, CV_32SC1);
    	CvPoint2D32f*cam_corners = new CvPoint2D32f[cam_board_n];
    	int cam_corner_count;
    	int cam_step;
    	CvMat*cam_intrinsic_matrix = cvCreateMat(3, 3, CV_32FC1);
    	CvMat*cam_distortion_coeffs = cvCreateMat(4, 1, CV_32FC1);
    	CvSize cam_image_sz;
    	//window intit
    	cvNamedWindow("window", 0);
    
    	//get image size
    	IplImage *cam_image_temp = cvLoadImage("..\cam\cam1.bmp", 0);
    	cam_image_sz = cvGetSize(cam_image_temp);
    	char failurebuf[20] = { 0 };
    	/*
    	//extract cornner
    	// camera image
    	// 
    	// pattern
    	*/
    
    
    
    
    	/*
    	//extrat the cam cornner 
    	//
    	//
    	//
    	*/
    	fstream cam_data;
    	cam_data.open("..\output\TXT\cam_corners.txt", ofstream::out);
    	fstream cam_object_data;
    	cam_object_data.open("..\output\TXT\cam_object_data.txt", ofstream::out);
    	//process the prj image so that we can easy find cornner
    	for (int ii = 1; ii < img_num + 1; ii++)
    	{
    		char cambuf[20] = { 0 };
    		sprintf(cambuf, "..\cam\cam%d.bmp", ii);
    		IplImage *cam_image = cvLoadImage(cambuf, 0);
    
    		//extract cam cornner
    		int cam_found = cvFindChessboardCorners(cam_image, cam_board_sz, cam_corners, &cam_corner_count,
    			 CV_CALIB_CB_ADAPTIVE_THRESH | CV_CALIB_CB_FILTER_QUADS);
    		cvFindCornerSubPix(cam_image, cam_corners, cam_corner_count,
    			cvSize(11, 11), cvSize(-1, -1), cvTermCriteria(CV_TERMCRIT_EPS + CV_TERMCRIT_ITER, 30, 0.1));
    		cvDrawChessboardCorners(cam_image, cam_board_sz, cam_corners, cam_corner_count, cam_found);
    
    		if (cam_corner_count != cam_board_n)
    			cout << "find cam"<<ii<<"  corner failed!
    ";
    		
    		//when cam and prj are success store the result
    		if ( cam_corner_count == cam_board_n) {
    			//store cam result
    			cam_step = successes*cam_board_n;
    			for (int i = cam_step, j = 0; j < cam_board_n; ++i, ++j) {
    				CV_MAT_ELEM(*cam_image_points, float, i, 0) = cam_corners[j].x;
    				CV_MAT_ELEM(*cam_image_points, float, i, 1) = cam_corners[j].y;
    				CV_MAT_ELEM(*cam_object_points, float, i, 0) = (j/cam_board_w)*cam_Dx;
    				CV_MAT_ELEM(*cam_object_points, float, i, 1) = (j % cam_board_w)*cam_Dy;
    				CV_MAT_ELEM(*cam_object_points, float, i, 2) = 0.0f;
    				cam_data << cam_corners[j].x << "	" << cam_corners[j].y << "
    ";
    				cam_object_data << (j/cam_board_w)*cam_Dx << "	" << (j %cam_board_w)*cam_Dy << "	0
    ";
    			}
    			CV_MAT_ELEM(*cam_point_counts, int, successes, 0) = cam_board_n;
    			successes++;
    			cout << "success number" << successes << endl;
    			cvShowImage("window", cam_image);
    			cvWaitKey(500);
    		}
    		
    
    		
    	}
    	if (successes < 2)
    		exit(0);
    	/*
    	//restore the success point
    	*/
    	//cam
    	cam_image_points2 = cvCreateMat(cam_board_n*(successes), 2, CV_32FC1);
    	cam_object_points2 = cvCreateMat(cam_board_n*(successes), 3, CV_32FC1);
    	CvMat*cam_point_counts2 = cvCreateMat((successes), 1, CV_32SC1);
    	for (int i = 0; i < successes*cam_board_n; ++i){
    		CV_MAT_ELEM(*cam_image_points2, float, i, 0) = CV_MAT_ELEM(*cam_image_points, float, i, 0);
    		CV_MAT_ELEM(*cam_image_points2, float, i, 1) = CV_MAT_ELEM(*cam_image_points, float, i, 1);
    		CV_MAT_ELEM(*cam_object_points2, float, i, 0) = CV_MAT_ELEM(*cam_object_points, float, i, 0);
    		CV_MAT_ELEM(*cam_object_points2, float, i, 1) = CV_MAT_ELEM(*cam_object_points, float, i, 1);
    		CV_MAT_ELEM(*cam_object_points2, float, i, 2) = CV_MAT_ELEM(*cam_object_points, float, i, 2);
    
    	}
    	for (int i = 0; i < successes; ++i){
    		CV_MAT_ELEM(*cam_point_counts2, int, i, 0) = CV_MAT_ELEM(*cam_point_counts, int, i, 0);
    	}
    	cvSave("..\output\XML\cam_corners.xml", cam_image_points2);
    
    	cvReleaseMat(&cam_object_points);
    	cvReleaseMat(&cam_image_points);
    	cvReleaseMat(&cam_point_counts);
    
    	
    	/*
    	//calibration for camera 
    	//
    	*/
    	//calib for cam
    	CV_MAT_ELEM(*cam_intrinsic_matrix, float, 0, 0) = 1.0f;
    	CV_MAT_ELEM(*cam_intrinsic_matrix, float, 1, 1) = 1.0f;
    	CvMat* cam_rotation_all = cvCreateMat( successes, 3, CV_32FC1);
    	CvMat* cam_translation_vector_all = cvCreateMat( successes,3, CV_32FC1);
    	cvCalibrateCamera2(
    		cam_object_points2,
    		cam_image_points2,
    		cam_point_counts2,
    		cam_image_sz,
    		cam_intrinsic_matrix,
    		cam_distortion_coeffs,
    		cam_rotation_all,
    		cam_translation_vector_all,
    		0//CV_CALIB_FIX_ASPECT_RATIO  
    		);
    	cvSave("..\output\XML\cam_intrinsic_matrix.xml", cam_intrinsic_matrix);
    	cvSave("..\output\XML\cam_distortion_coeffs.xml", cam_distortion_coeffs);
    	//calib 
    	cvSave("..\output\XML\cam_rotation_all.xml", cam_rotation_all);
    	cvSave("..\output\XML\cam_translation_vector_all.xml", cam_translation_vector_all);
    	char path1[100] = "..\output\result_data_no_optim.txt";
    	save_result(cam_rotation_all, cam_translation_vector_all,
    		cam_intrinsic_matrix, cam_distortion_coeffs,path1,successes);
    }
    void save_result(CvMat*cam_rotation_all, CvMat*cam_translation_vector_all,
    	CvMat*cam_intrinsic_matrix, CvMat*cam_distortion_coeffs,char*pathc,int sucesses)
    {
    	fstream Yeah_result;
    	Yeah_result.open(pathc, ofstream::out);
    	Yeah_result << setprecision(12) << "fc[0] =" << CV_MAT_ELEM(*cam_intrinsic_matrix, float, 0, 0
    		) << "; fc[1] =" << CV_MAT_ELEM(*cam_intrinsic_matrix, float, 1, 1) << "; //CAM的焦距
    ";
    	Yeah_result  << setprecision(12) << "cc[0] = " << CV_MAT_ELEM(*cam_intrinsic_matrix, float, 0, 2) 
    		<< "; cc[1] = " << CV_MAT_ELEM(*cam_intrinsic_matrix, float, 1, 2) << ";//CAM中心点
    ";
    	Yeah_result  << setprecision(12) << "kc[0] =" << CV_MAT_ELEM(*cam_distortion_coeffs, float, 0, 0) <<
    		"; kc[1] =" << CV_MAT_ELEM(*cam_distortion_coeffs, float, 1, 0) <<
    		";  kc[2] =" << CV_MAT_ELEM(*cam_distortion_coeffs, float, 2, 0) << 
    		";  kc[3] =" << CV_MAT_ELEM(*cam_distortion_coeffs, float, 3, 0) 
    		<< ";  kc[4] =0;//畸变參数,请參照MATLAB里的定义
    
    外參数:
    ";
    		for(int i=0;i<sucesses;++i)
    		{
    			Yeah_result<<"r:("<<setprecision(12) <<CV_MAT_ELEM(*cam_rotation_all, float, i, 0)<<"	,"<<CV_MAT_ELEM(*cam_rotation_all, float, i, 1)<<"	,"<<CV_MAT_ELEM(*cam_rotation_all, float, i, 2)<<")
    ";
    			Yeah_result<<"t:("<<setprecision(12) <<CV_MAT_ELEM(*cam_translation_vector_all, float, i, 0)<<"	,"<<CV_MAT_ELEM(*cam_translation_vector_all, float, i, 1)<<"	,"<<CV_MAT_ELEM(*cam_translation_vector_all, float, i, 2)<<")
    
    
    ";
    		}
    	
    
    }


    假设您认为此博客对您实用,欢迎对我进行小额赞助


    不筹钱娶媳妇的程序猿不是好程序猿。


    1.  

  • 相关阅读:
    不用加减乘除做加法
    数组中只出现一次的数字
    平衡二叉树
    二叉树的深度
    两个链表的第一个公共结点
    连续子数组的最大和
    最小的K个数
    数组中出现次数超过一半的数字
    二叉搜索树与双向链表
    复杂链表的复制
  • 原文地址:https://www.cnblogs.com/zhchoutai/p/7083770.html
Copyright © 2011-2022 走看看