鸟瞰图opencv(附源码)

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

效果:


图片.png

图片.png

你可能感兴趣的:(鸟瞰图opencv(附源码))