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;
}
效果: