鸟瞰图(附源码)

opencv自带的鸟瞰图略坑,先看一下,稍后研究一下其他的论文,再实现对比一下效果。

#include 
#include 
#include 
#include 
#include 
using namespace std;

void help(){
	printf("Birds eye view\n\n"
		
		" ADJUST VIEW HEIGHT using keys 'u' up, 'd' down. ESC to quit. 很坑爹\n\n");
}
int main(int argc, char* argv[]){
	argc =6;
	argv[1]="12";
	argv[2]="12";
	argv[3]="Intrinsics.xml";	
	argv[4]="Distortion.xml";
	argv[5]="1.jpg";
	argv[0]="ch12_ex12_1";

	if(argc != 6){
		printf("\nERROR\n");
		help();
		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 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);

	//求角点
	cvNamedWindow("checkers",0);
	CvPoint2D32f *corners=  new CvPoint2D32f[board_n];// board_n 个cvpoint
	int  corner_count =0;
	//bool found = cvFindChessboardCorners(image,board_sz,corners,&corner_count, CV_CALIB_CB_ADAPTIVE_THRESH | CV_CALIB_CB_FILTER_QUADS);
	bool found = cvFindChessboardCorners(gray_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
	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] ,coz by rows
	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)*board_w];
	imgPts[2]=corners[board_h-1];
	imgPts[3]=corners[(board_w-1)*board_w+(board_h-1)];

	// draw the points in order : B,G,R,Yellow
	cvCircle(image,cvPointFrom32f(imgPts[0]),9,CV_RGB(0,0,255),3);	//		converts CvPoint2D32f to CvPoint, f
	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 chessboard
	cvDrawChessboardCorners(image,board_sz,corners,corner_count,found);
	cvShowImage("checkers",image);

	// 寻找单应性矩阵
	CvMat *H =cvCreateMat(3,3,CV_32F);
	CvMat *H_invt = cvCreateMat(3,3,CV_32F);
	cvGetPerspectiveTransform(objPts,imgPts,H);
	// 景深 Z
	float z=25;
	int key =0;
	IplImage *bird_image=cvCloneImage(image);
	cvNamedWindow("birds_eye",0);
	//CV_MAT_ELEM( matrix, elemtype, row, col ) 用来访问矩阵每个元素的宏,这个宏只对单通道矩阵有效,多通道会报错
	//
	while(key!=27)
	{
		CV_MAT_ELEM(*H,float,2,2)=z;
		cvWarpPerspective(image,bird_image,H,CV_INTER_LINEAR|CV_WARP_INVERSE_MAP|CV_WARP_FILL_OUTLIERS);//整个图像的透视变换
		cvShowImage("birds_eye",bird_image);
		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

	system("pause");
	int h=0;
	cin>>h;
	return 0;
}
效果:

鸟瞰图(附源码)_第1张图片

你可能感兴趣的:(计算机视觉,OpenCV)