OpenCV sample目錄下自帶兩個(gè)與相機(jī)標(biāo)定的cpp文件即:calibration.cpp和calibration_artificial.cpp
calibration.cpp 是通過用戶輸入可選參數(shù)進(jìn)行攝像機(jī)標(biāo)定的程序。
calibration_artificial.cpp 是程序模擬模擬攝像機(jī)標(biāo)定的過程,即程序創(chuàng)建棋盤然后自主標(biāo)定。
通常我們有兩種方式去標(biāo)定,一個(gè)是實(shí)時(shí)的從攝像機(jī)獲取拍攝到的棋盤進(jìn)行標(biāo)定,一個(gè)是已經(jīng)獲得了一些棋盤的圖片來標(biāo)定。
本文詳細(xì)介紹第二種,即用已獲得的棋盤圖片的整個(gè)過程。
方法一:編譯生成 .exe文件,然后在commond 窗口輸入?yún)?shù)執(zhí)行
方法二:通過添加輸入?yún)?shù)的代碼,然后執(zhí)行(可以單步調(diào)試)(推薦此方法)
calibration.cpp 和 calibration_artificial.cpp 位置如圖所示。此外,棋盤圖片也在同一目錄下
找到文件后,開始新建工程吧。不過在用以獲得的圖像來進(jìn)行標(biāo)定,應(yīng)先通過OpenCV自帶的imagelist_creator.cpp 產(chǎn)生一個(gè)xml或者yaml格式的圖像列表,然后在使用下面的程序。
第一步,新建項(xiàng)目demo,添加剛才那個(gè)目錄下的imagelist_creator.cpp 編譯執(zhí)行得到可執(zhí)行文件 demo.exe
第二步,執(zhí)行demo.exe 產(chǎn)生一個(gè)xml或者yaml格式的圖像列表
static void help(char** av)
{
cout 《《 “\nThis creates a yaml or xml list of files from the command line args\n”
“usage:\n./” 《《 av[0] 《《 “ imagelist.yaml *.png\n”
《《 “Try using different extensions.(e.g. yaml yml xml xml.gz etc.。。)\n”
《《 “This will serialize this list of images or whatever with opencv‘s FileStorage framework” 《《 endl;
}
輸入命令:demo imagelist.yaml left01.jpg left02.jpg left03.jpg left04.jpg left05.jpg left06.jpg left07.jpg left08.jpg left09.jpg left010.jpg left11.jpg left12.jpg left13.jpg left14.jpg right01.jpg right02.jpg right03.jpg right04.jpg right05.jpg right06.jpg right07.jpg right08.jpg right09.jpg right10.jpg right11.jpg right12.jpg right13.jpg right14.jpg 。回車,生成imagelist.yaml
第三步,進(jìn)行相機(jī)的標(biāo)定
先把14張棋盤圖片放到debug目錄下,然后移除imagelist_creator.cpp 添加 calibration.cpp ,如圖所示
編譯執(zhí)行,得到新的demo.exe ,進(jìn)入cmd ,輸入 demo -w 6 -h 9 imagelist.yaml 回車即可。如圖所示,開始對(duì)每張圖片進(jìn)行角點(diǎn)檢測(cè)
最后,得到一個(gè) out_camera_data.yml 文件
內(nèi)容如下:
%YAML:1.0
calibration_time: “08/21/15 16:54:26”
image_width: 640
image_height: 480
board_width: 6
board_height: 9
square_size: 1.
flags: 0
camera_matrix: ??!opencv-matrix
rows: 3
cols: 3
dt: d
data: [ 5.3765976500165073e+002, 0., 3.4011155767874686e+002, 0.,
5.3789341813113867e+002, 2.3694081464807104e+002, 0., 0., 1. ]
distortion_coefficients: ??!opencv-matrix
rows: 5
cols: 1
dt: d
data: [ -2.7762353155161251e-001, 5.3976467600878486e-002,
2.1257384355991209e-003, -3.9487502777272009e-004,
4.8679847473271927e-002 ]
avg_reprojection_error: 4.4034956116049290e-001
此時(shí),大功告成 =。=
//對(duì)于想自己?jiǎn)尾秸{(diào)試的親,補(bǔ)充第二種方法,即通過添加代碼調(diào)試。
第一步:將圖片及imagelist放到 D:\Workspace\demo\demo目錄下
第二步: 添加代碼
具體過程如圖所示:
在該目錄下放入imagelist.yaml 和14張圖片
添加代碼
argc = 6;
argv[0] = “demo.exe”;
argv[1] = “-w”;
argv[2] = “6”;
argv[3] = “-h”;
argv[4] = “9”;
argv[5] = “imagelist.yaml”;
代碼
#include “stdafx.h”
#include “cv.h”
#include “highgui.h”
#include 《string》
#include 《iostream》
using namespace std;
int main()
{
int cube_length=7;
CvCapture* capture;
capture=cvCreateCameraCapture(0);
if(capture==0){
printf(“無法捕獲攝像頭設(shè)備!\n\n”);
return 0;
}else{
printf(“捕獲攝像頭設(shè)備成功?。n\n”);
}
IplImage* frame;
cvNamedWindow(“攝像機(jī)幀截取窗口”,1);
printf(“按“C”鍵截取當(dāng)前幀并保存為標(biāo)定圖片。。。\n按“Q”鍵退出截取幀過程。。。\n\n”);
int number_image=1;
char *str1;
str1=“.jpg”;
char filename[20]=“”;
while(true)
{
frame=cvQueryFrame(capture);
if(!frame)
break;
cvShowImage(“攝像機(jī)幀截取窗口”,frame);
if(cvWaitKey(10)==‘c’){
sprintf_s (filename,“%d.jpg”,number_image);
cvSaveImage(filename,frame);
cout《《“成功獲取當(dāng)前幀,并以文件名”《《filename《《“保存。。。\n\n”;
printf(“按“C”鍵截取當(dāng)前幀并保存為標(biāo)定圖片。。。\n按“Q”鍵退出截取幀過程。。。\n\n”);
number_image++;
}else if(cvWaitKey(10)==‘q’){
printf(“截取圖像幀過程完成。。。\n\n”);
cout《《“共成功截取”《《--number_image《《“幀圖像??!\n\n”;
break;
}
}
cvReleaseImage(&frame);
cvDestroyWindow(“攝像機(jī)幀截取窗口”);
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《《“幀圖片無法找到棋盤格所有角點(diǎn)!\n\n”;
cvNamedWindow(“RePlay”,1);
cvShowImage(“RePlay”,show);
cvWaitKey(0);
}else{
cout《《“第”《《a《《“幀圖像成功獲得”《《count《《“個(gè)角點(diǎn)。。。\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《《“在源圖像上繪制角點(diǎn)過程完成。。。\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《《“幀圖片中,標(biāo)定成功的圖片為”《《successes《《“幀。。。\n”;
cout《《number_image《《“幀圖片中,標(biāo)定失敗的圖片為”《《number_image-successes《《“幀。。。\n\n”;
cout《《“*********************************************\n\n”;
cout《《“按任意鍵開始計(jì)算攝像機(jī)內(nèi)參數(shù)。。。\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《《“攝像機(jī)內(nèi)參數(shù)矩陣為:\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《《“畸變系數(shù)矩陣為:\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《《“攝像機(jī)矩陣、畸變系數(shù)向量已經(jīng)分別存儲(chǔ)在名為Intrinsics.xml、Distortion.xml文檔中\(zhòng)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;
}
評(píng)論
查看更多