鸟瞰图(立体视觉)

鸟瞰图(立体视觉)


1、鸟瞰图,具体算法流程为(参考学习opencv一书):

(1)读取摄像机的内参数和畸变参数模型。

(2)查找地平面上的已知物体(如棋盘),获得最少4个亚像素精度上的点。

(3)将找到的点输入到函数getPerspectiveTransform()中,计算地平面视图的单应矩阵H。

(4)使用函数warpPerspective(),设置标志INTER_LINEAR+WARP_INVERSE_MAP,获得地平面的前向平行视图。


2、opencv1.x代码(学习opencv一书)

参考自:http://blog.csdn.net/u014773418/article/details/50517857

argv[1 ]=12 //棋盘内点长 
argv[2 ]=12 //棋盘内点宽 
argv[3 ]=Intrinsics.xml //摄像机的内参数矩阵 
argv[4 ]=Distortion.xml //摄像机的畸变系数 
argv[5 ]=0.jpg //图片名 

代码:

#include <cv.h>
#include <highgui.h>
#include <stdio.h>
#include <stdlib.h>

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;
}

配置与运行


xml文件中内容:




猜你喜欢

转载自blog.csdn.net/liyuqian199695/article/details/69308180