鸟瞰图(立体视觉)
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文件中内容: