生活随笔
收集整理的這篇文章主要介紹了
相机标定获得内参矩阵及其他参数
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
csdn博客推薦:http://blog.csdn.net/chenyusiyuan/article/details/5963256
理論方面和單目標定opencv代碼網址:
http://pan.baidu.com/s/1cFRWg2
下面為轉載的一部分
我自己寫了一個攝像機標定程序,核心算法參照learning opencv,但是那個程序要從命令行預先輸入參數,且標定圖片要預先準備好,我覺得不太好,我就自己寫了一個,跟大家分享下。
若有紕漏,希望大家指正!
[cpp]?view plaincopy
#include?<string>?? #include?<iostream>?? #include?<cv.h>?? #include?<highgui.h>?? ?? #pragma?comment(lib,?"ml.lib")?? #pragma?comment(lib,?"cv.lib")?? #pragma?comment(lib,?"cvaux.lib")?? #pragma?comment(lib,?"cvcam.lib")?? #pragma?comment(lib,?"cxcore.lib")?? #pragma?comment(lib,?"cxts.lib")?? #pragma?comment(lib,?"highgui.lib")?? #pragma?comment(lib,?"cvhaartraining.lib")?? ?? using?namespace?std;?? ?? int?main()?? {?? ????int?cube_length=7;?? ?? ????CvCapture*?capture;?? ?? ????capture=cvCreateCameraCapture(0);?? ?? ????if(capture==0)?? ????{?? ????????printf("無法捕獲攝像頭設備!\n\n");?? ????????return?0;?? ????}?? ????else?? ????{?? ????????printf("捕獲攝像頭設備成功!!\n\n");?? ????}?? ?? ????IplImage*?frame?=?NULL;?? ?? ????cvNamedWindow("攝像機幀截取窗口",1);?? ?? ????printf("按“C”鍵截取當前幀并保存為標定圖片...\n按“Q”鍵退出截取幀過程...\n\n");?? ?? ????int?number_image=1;?? ????char?*str1;?? ????str1=".jpg";?? ????char?filename[20]="";?? ?? ????while(true)?? ????{?? ????????frame=cvQueryFrame(capture);?? ????????if(!frame)?? ????????????break;?? ????????cvShowImage("攝像機幀截取窗口",frame);?? ?? ????????if(cvWaitKey(10)=='c')?? ????????{?? ????????????sprintf_s?(filename,"%d.jpg",number_image);?? ????????????cvSaveImage(filename,frame);?? ????????????cout<<"成功獲取當前幀,并以文件名"<<filename<<"保存...\n\n";?? ????????????printf("按“C”鍵截取當前幀并保存為標定圖片...\n按“Q”鍵退出截取幀過程...\n\n");?? ????????????number_image++;?? ????????}?? ????????else?if(cvWaitKey(10)=='q')?? ????????{?? ????????????printf("截取圖像幀過程完成...\n\n");?? ????????????cout<<"共成功截取"<<--number_image<<"幀圖像!!\n\n";?? ????????????break;?? ????????}?? ????}?? ?? ????cvReleaseImage(&frame);?? ????cvDestroyWindow("攝像機幀截取窗口");?? ?? ????IplImage?*?show;?? ????cvNamedWindow("RePlay",1);?? ?? ????int?a=1;?? ????int?number_image_copy?=?number_image;?? ?? ????CvSize?board_size=cvSize(7,7);?? ????int?board_width=board_size.width;?? ????int?board_height=board_size.height;?? ????int?total_per_image=board_width*board_height;?? ????CvPoint2D32f?*?image_points_buf?=?new?CvPoint2D32f[total_per_image];?? ????CvMat?*?image_points=cvCreateMat(number_image*total_per_image,2,CV_32FC1);?? ????CvMat?*?object_points=cvCreateMat(number_image*total_per_image,3,CV_32FC1);?? ????CvMat?*?point_counts=cvCreateMat(number_image,1,CV_32SC1);?? ????CvMat?*?intrinsic_matrix=cvCreateMat(3,3,CV_32FC1);?? ????CvMat?*?distortion_coeffs=cvCreateMat(5,1,CV_32FC1);?? ?? ????int?count;?? ????int?found;?? ????int?step;?? ????int?successes=0;?? ?? ????while(a<=number_image_copy)?? ????{?? ????????sprintf_s?(filename,"%d.jpg",a);?? ????????show=cvLoadImage(filename,-1);?? ?? ????????found=cvFindChessboardCorners(show,board_size,image_points_buf,&count,?? ????????????CV_CALIB_CB_ADAPTIVE_THRESH|CV_CALIB_CB_FILTER_QUADS);?? ????????if(found==0)?? ????????{????????? ????????????cout<<"第"<<a<<"幀圖片無法找到棋盤格所有角點!\n\n";?? ????????????cvNamedWindow("RePlay",1);?? ????????????cvShowImage("RePlay",show);?? ????????????cvWaitKey(0);?? ?? ????????}?? ????????else?? ????????{?? ????????????cout<<"第"<<a<<"幀圖像成功獲得"<<count<<"個角點...\n";?? ?? ????????????cvNamedWindow("RePlay",1);?? ?? ????????????IplImage?*?gray_image=?cvCreateImage(cvGetSize(show),8,1);?? ????????????cvCvtColor(show,gray_image,CV_BGR2GRAY);?? ????????????cout<<"獲取源圖像灰度圖過程完成...\n";?? ????????????cvFindCornerSubPix(gray_image,image_points_buf,count,cvSize(11,11),cvSize(-1,-1),?? ????????????????cvTermCriteria(CV_TERMCRIT_EPS+CV_TERMCRIT_ITER,30,0.1));?? ????????????cout<<"灰度圖亞像素化過程完成...\n";?? ????????????cvDrawChessboardCorners(show,board_size,image_points_buf,count,found);?? ????????????cout<<"在源圖像上繪制角點過程完成...\n\n";?? ????????????cvShowImage("RePlay",show);?? ?? ????????????cvWaitKey(0);?? ????????}?? ?? ????????if(total_per_image==count)?? ????????{?? ????????????step=successes*total_per_image;?? ????????????for(int?i=step,j=0;j<total_per_image;++i,++j)?? ????????????{?? ????????????????CV_MAT_ELEM(*image_points,float,i,0)=image_points_buf[j].x;?? ????????????????CV_MAT_ELEM(*image_points,float,i,1)=image_points_buf[j].y;?? ????????????????CV_MAT_ELEM(*object_points,float,i,0)=(float)(j/cube_length);?? ????????????????CV_MAT_ELEM(*object_points,float,i,1)=(float)(j%cube_length);?? ????????????????CV_MAT_ELEM(*object_points,float,i,2)=0.0f;?? ????????????}?? ????????????CV_MAT_ELEM(*point_counts,int,successes,0)=total_per_image;?? ????????????successes++;?? ????????}?? ????????a++;?? ????}?? ?? ????cvReleaseImage(&show);?? ????cvDestroyWindow("RePlay");?? ?? ?? ????cout<<"*********************************************\n";?? ????cout<<number_image<<"幀圖片中,標定成功的圖片為"<<successes<<"幀...\n";?? ????cout<<number_image<<"幀圖片中,標定失敗的圖片為"<<number_image-successes<<"幀...\n\n";?? ????cout<<"*********************************************\n\n";?? ?? ????cout<<"按任意鍵開始計算攝像機內參數...\n\n";?? ?? ????CvCapture*?capture1;?? ????capture1=cvCreateCameraCapture(0);?? ????IplImage?*?show_colie;?? ????show_colie=cvQueryFrame(capture1);?? ?? ????CvMat?*?object_points2=cvCreateMat(successes*total_per_image,3,CV_32FC1);?? ????CvMat?*?image_points2=cvCreateMat(successes*total_per_image,2,CV_32FC1);?? ????CvMat?*?point_counts2=cvCreateMat(successes,1,CV_32SC1);?? ?? ????for(int?i=0;i<successes*total_per_image;++i)?? ????{?? ????????CV_MAT_ELEM(*image_points2,float,i,0)=CV_MAT_ELEM(*image_points,float,i,0);?? ????????CV_MAT_ELEM(*image_points2,float,i,1)=CV_MAT_ELEM(*image_points,float,i,1);?? ????????CV_MAT_ELEM(*object_points2,float,i,0)=CV_MAT_ELEM(*object_points,float,i,0);?? ????????CV_MAT_ELEM(*object_points2,float,i,1)=CV_MAT_ELEM(*object_points,float,i,1);?? ????????CV_MAT_ELEM(*object_points2,float,i,2)=CV_MAT_ELEM(*object_points,float,i,2);?? ????}?? ?? ????for(int?i=0;i<successes;++i)?? ????{?? ????????CV_MAT_ELEM(*point_counts2,int,i,0)=CV_MAT_ELEM(*point_counts,int,i,0);?? ????}?? ?? ????cvReleaseMat(&object_points);?? ????cvReleaseMat(&image_points);?? ????cvReleaseMat(&point_counts);?? ?? ????CV_MAT_ELEM(*intrinsic_matrix,float,0,0)=1.0f;?? ????CV_MAT_ELEM(*intrinsic_matrix,float,1,1)=1.0f;?? ?? ????cvCalibrateCamera2(object_points2,image_points2,point_counts2,cvGetSize(show_colie),?? ????????intrinsic_matrix,distortion_coeffs,NULL,NULL,0);?? ?? ????cout<<"攝像機內參數矩陣為:\n";?? ????cout<<CV_MAT_ELEM(*intrinsic_matrix,float,0,0)<<"????"<<CV_MAT_ELEM(*intrinsic_matrix,float,0,1)?? ????????<<"????"<<CV_MAT_ELEM(*intrinsic_matrix,float,0,2)?? ????????<<"\n\n";?? ????cout<<CV_MAT_ELEM(*intrinsic_matrix,float,1,0)<<"????"<<CV_MAT_ELEM(*intrinsic_matrix,float,1,1)?? ????????<<"????"<<CV_MAT_ELEM(*intrinsic_matrix,float,1,2)?? ????????<<"\n\n";?? ????cout<<CV_MAT_ELEM(*intrinsic_matrix,float,2,0)<<"????"<<CV_MAT_ELEM(*intrinsic_matrix,float,2,1)?? ????????<<"??????????"<<CV_MAT_ELEM(*intrinsic_matrix,float,2,2)?? ????????<<"\n\n";?? ?? ????cout<<"畸變系數矩陣為:\n";?? ????cout<<CV_MAT_ELEM(*distortion_coeffs,float,0,0)<<"????"<<CV_MAT_ELEM(*distortion_coeffs,float,1,0)?? ????????<<"????"<<CV_MAT_ELEM(*distortion_coeffs,float,2,0)?? ????????<<"????"<<CV_MAT_ELEM(*distortion_coeffs,float,3,0)?? ????????<<"????"<<CV_MAT_ELEM(*distortion_coeffs,float,4,0)?? ????????<<"\n\n";?? ?? ????cvSave("Intrinsics.xml",intrinsic_matrix);?? ????cvSave("Distortion.xml",distortion_coeffs);?? ?? ????cout<<"攝像機矩陣、畸變系數向量已經分別存儲在名為Intrinsics.xml、Distortion.xml文檔中\n\n";?? ?? ????CvMat?*?intrinsic=(CvMat?*)cvLoad("Intrinsics.xml");?? ????CvMat?*?distortion=(CvMat?*)cvLoad("Distortion.xml");?? ?? ????IplImage?*?mapx=cvCreateImage(cvGetSize(show_colie),IPL_DEPTH_32F,1);?? ????IplImage?*?mapy=cvCreateImage(cvGetSize(show_colie),IPL_DEPTH_32F,1);?? ?? ????cvInitUndistortMap(intrinsic,distortion,mapx,mapy);?? ?? ????cvNamedWindow("原始圖像",1);?? ????cvNamedWindow("非畸變圖像",1);?? ?? ????cout<<"按‘E’鍵退出顯示...\n\n";?? ?? ????while(show_colie)?? ????{?? ????????IplImage?*?clone=cvCloneImage(show_colie);?? ????????cvShowImage("原始圖像",show_colie);?? ????????cvRemap(clone,show_colie,mapx,mapy);?? ????????cvReleaseImage(&clone);?? ????????cvShowImage("非畸變圖像",show_colie);?? ?? ????????if(cvWaitKey(10)=='e')?? ????????{?? ????????????break;?? ????????}?? ?? ????????show_colie=cvQueryFrame(capture1);?? ????}?? ?? ????return?0;?? } ?
總結
以上是生活随笔為你收集整理的相机标定获得内参矩阵及其他参数的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。