本文为《学习opencv(中文版)》第十二章第一个例子:鸟瞰图,原书上的第445页的代码是可以运行的,只是书中没有把输入的参数写清楚,需要自己动手。
1. mian()的参数,argc和argv说明
2. 本例中argv【1】~argv【5】的具体值
3. 代码展示
argc和argv这两个参数一般在用命令行编译程序时有用,int类型的argc,用来统计程序运行时发送给main函数的命令行参数的个数,char *类型的argv[],为字符串数组,用来存放指向的字符串擦数的指针数组,每个元素指向一个参数。各成员含义:
- argv[0]指向成员运行的全路径名,
- argv[1 ]指向在dos命令行中执行程序名后的第一个字符串,
- argv[2 ]指向执行程序名后的第二个字符串,
- argv[3 ]指向执行程序名后的第三个字符串
- ……
在vs中argv的值对应于【项目】->【属性】->【配置属性】->【调试】->【命令参数】中的值。如果有多个字符串,则用空格隔开,argv[0]不需要输入,命令参数中的值从argv[1 ]开始。—— 《opencv3编程入门》(毛星云,冷雪飞等著)。
argv[1 ]=12 //棋盘内点长
argv[2 ]=12 //棋盘内点宽
argv[3 ]=Intrinsics.xml //摄像机的内参数矩阵
argv[4 ]=Distortion.xml //摄像机的畸变系数
argv[5 ]=0.jpg //图片名
参数三和参数四是两个文件,文件由《学习opencv》第十一章的一次完成标定程序生成的,
#include
#include
#include
#include
void help(){
printf("Birds eye view\n\n"
" birdseye board_w board_h intrinsics_mat.xml distortion_mat.xml checker_image \n\n"
"Where: board_{w,h} are the # of internal corners in the checkerboard\n"
" intrinsic intrinsic path/name of matrix from prior calibration\n"
" distortion distortion path/name of matrix from pror calibration\n"
" checker_image is the path/name of image of checkerboard on the plane \n"
" Frontal view of this will be shown.\n\n"
" ADJUST VIEW HEIGHT using keys 'u' up, 'd' down. ESC to quit.\n\n");
}
int main(int argc, char* argv[]) {
if(argc!=6)
return -1;
help();
//INPUT PARAMETERS:
int board_w = atoi(argv[1]);
int board_h = atoi(argv[2]);
int board_n = board_w * board_h;
CvSize board_sz = cvSize( board_w, board_h );
CvMat *intrinsic = (CvMat*)cvLoad(argv[3]);
CvMat *distortion = (CvMat*)cvLoad(argv[4]);
IplImage *image = 0, *gray_image = 0;
if((image = cvLoadImage(argv[5]))== 0){
printf("Error: Couldn't load %s\n",argv[5]);
return -1;
}
gray_image = cvCreateImage(cvGetSize(image),8,1);
cvCvtColor(image, gray_image, CV_BGR2GRAY);
//UNDISTORT OUR IMAGE
IplImage* mapx = cvCreateImage( cvGetSize(image), IPL_DEPTH_32F, 1 );
IplImage* mapy = cvCreateImage( cvGetSize(image), IPL_DEPTH_32F, 1 );
cvInitUndistortMap(
intrinsic,
distortion,
mapx,
mapy
);
IplImage *t = cvCloneImage(image);
cvRemap( t, image, mapx, mapy );
//GET THE CHECKERBOARD ON THE PLANE
cvNamedWindow("Checkers");
CvPoint2D32f* corners = new CvPoint2D32f[ board_n ];
int corner_count = 0;
int found = cvFindChessboardCorners(
image,
board_sz,
corners,
&corner_count,
CV_CALIB_CB_ADAPTIVE_THRESH | CV_CALIB_CB_FILTER_QUADS
);
if(!found){
printf("Couldn't aquire checkerboard on %s, only found %d of %d corners\n",
argv[5],corner_count,board_n);
return -1;
}
//Get Subpixel accuracy on those corners
cvFindCornerSubPix(gray_image, corners, corner_count,
cvSize(11,11),cvSize(-1,-1),
cvTermCriteria( CV_TERMCRIT_EPS+CV_TERMCRIT_ITER, 30, 0.1 ));
//GET THE IMAGE AND OBJECT POINTS:
//Object points are at (r,c): (0,0), (board_w-1,0), (0,board_h-1), (board_w-1,board_h-1)
//That means corners are at: corners[r*board_w + c]
CvPoint2D32f objPts[4], imgPts[4];
objPts[0].x = 0; objPts[0].y = 0;
objPts[1].x = board_w-1; objPts[1].y = 0;
objPts[2].x = 0; objPts[2].y = board_h-1;
objPts[3].x = board_w-1; objPts[3].y = board_h-1;
imgPts[0] = corners[0];
imgPts[1] = corners[board_w-1];
imgPts[2] = corners[(board_h-1)*board_w];
imgPts[3] = corners[(board_h-1)*board_w + board_w-1];
//DRAW THE POINTS in order: B,G,R,YELLOW
cvCircle(image,cvPointFrom32f(imgPts[0]),9,CV_RGB(0,0,255),3);
cvCircle(image,cvPointFrom32f(imgPts[1]),9,CV_RGB(0,255,0),3);
cvCircle(image,cvPointFrom32f(imgPts[2]),9,CV_RGB(255,0,0),3);
cvCircle(image,cvPointFrom32f(imgPts[3]),9,CV_RGB(255,255,0),3);
//DRAW THE FOUND CHECKERBOARD
cvDrawChessboardCorners(image, board_sz, corners, corner_count, found);
IplImage *image_temp = cvCreateImage(cvSize(image->width/2, image->height/2),image->depth,image->nChannels);
cvResize(image, image_temp);
cvShowImage( "Checkers", image_temp );
//FIND THE HOMOGRAPHY
CvMat *H = cvCreateMat( 3, 3, CV_32F);
CvMat *H_invt = cvCreateMat(3,3,CV_32F);
cvGetPerspectiveTransform(objPts,imgPts,H);
//LET THE USER ADJUST THE Z HEIGHT OF THE VIEW
float Z = 25;
int key = 0;
IplImage *birds_image = cvCloneImage(image);
cvNamedWindow("Birds_Eye");
while(key != 27) {//escape key stops
CV_MAT_ELEM(*H,float,2,2) = Z;
// cvInvert(H,H_invt); //If you want to invert the homography directly
// cvWarpPerspective(image,birds_image,H_invt,CV_INTER_LINEAR+CV_WARP_FILL_OUTLIERS );
//USE HOMOGRAPHY TO REMAP THE VIEW
cvWarpPerspective(image,birds_image,H,
CV_INTER_LINEAR+CV_WARP_INVERSE_MAP+CV_WARP_FILL_OUTLIERS );
IplImage *birds_image1 = cvCreateImage(cvSize(birds_image->width/2, birds_image->height/2),birds_image->depth,birds_image->nChannels);
cvResize(birds_image, birds_image1);
cvShowImage("Birds_Eye", birds_image1);
key = cvWaitKey();
if(key == 'u') Z += 0.5;
if(key == 'd') Z -= 0.5;
}
//SHOW ROTATION AND TRANSLATION VECTORS
CvMat* image_points = cvCreateMat(4,1,CV_32FC2);
CvMat* object_points = cvCreateMat(4,1,CV_32FC3);
for(int i=0;i<4;++i){
CV_MAT_ELEM(*image_points,CvPoint2D32f,i,0) = imgPts[i];
CV_MAT_ELEM(*object_points,CvPoint3D32f,i,0) = cvPoint3D32f(objPts[i].x,objPts[i].y,0);
}
CvMat *RotRodrigues = cvCreateMat(3,1,CV_32F);
CvMat *Rot = cvCreateMat(3,3,CV_32F);
CvMat *Trans = cvCreateMat(3,1,CV_32F);
cvFindExtrinsicCameraParams2(object_points,image_points,
intrinsic,distortion,
RotRodrigues,Trans);
cvRodrigues2(RotRodrigues,Rot);
//SAVE AND EXIT
cvSave("Rot.xml",Rot);
cvSave("Trans.xml",Trans);
cvSave("H.xml",H);
cvInvert(H,H_invt);
cvSave("H_invt.xml",H_invt); //Bottom row of H invert is horizon line
return 0;
}
下载程序