opencv 鸟瞰图变化实例

 
opencv 鸟瞰图变化实例
2011-08-15 23:30

《learning opencv》书上的例子

opencv2.2版本,vc9.0

个人仿真了下,觉得这个例子欠妥,仿真的结果也和书上不一样

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

int main(int argc , char * argv[])
{
 if (argc!=6)
 {
  printf("there is something wrong");
  return -1;
 }

 int board_w=atoi(argv[1]);
 int board_h=atoi(argv[2]);
 int board_n=board_h*board_w;
 CvSize board_sz=cvSize(board_w,board_h);
 CvMat * intrisic=(CvMat *)cvLoad(argv[3]);
 CvMat * distortion=(CvMat *)cvLoad(argv[4]);

 IplImage * image=NULL;
 IplImage * gray_image=NULL;

 if ((image=cvLoadImage(argv[5]))==0)
 {
  printf("there is something error !",argv[5]);
  return -1;
 }

 gray_image=cvCreateImage(cvGetSize(image),8,1);
// cvCvtColor(image,gray_image,CV_BGR2GRAY);

 //矫正图像
 IplImage * mapx=cvCreateImage(cvGetSize(image),IPL_DEPTH_32F,1);
 IplImage * mapy=cvCreateImage(cvGetSize(image),IPL_DEPTH_32F,1);

 cvInitUndistortMap(intrisic,distortion,mapx,mapy);

 IplImage * t=cvCloneImage(image);//分配了新的存储空间

 cvRemap(t,image,mapx,mapy);

 //得到棋盘上的角点
 cvCvtColor(image,gray_image,CV_BGR2GRAY);//自己添加
 cvNamedWindow("chessboard",0);
 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);//cvFindChessboardCorners 中的图像应该是单通道的

//《learning opencv》p417,书上程序却用了image,image为3个通道的。但如果运行程序,还是能通过,不知原因,可能2.2版本没问题
 int found=cvFindChessboardCorners(gray_image,board_sz,corners,&corner_count,  CV_CALIB_CB_ADAPTIVE_THRESH|CV_CALIB_CB_FILTER_QUADS);

//在原程序中gray_image为未校正的原图的灰度图,所以在自己的程序中把gray_image改为矫正后图像的灰度图。

 if (!found)
 {
  printf("fail finding the corner !");
  return -1;
 }

 cvFindCornerSubPix(gray_image,corners,corner_count,cvSize(11,11),cvSize(-1,-1),cvTermCriteria(
  CV_TERMCRIT_EPS|CV_TERMCRIT_ITER,30,0.1));

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

 //画图
 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);//cvPointFrom32f from f to int

 //DRAW THE FOUND CHECKERBOARD
 cvDrawChessboardCorners(image, board_sz, corners, corner_count, found);
 cvShowImage( "chessboard", image );
 
 //求解单应矩阵H
 CvMat * H =cvCreateMat(3,3,CV_32F);
 cvGetPerspectiveTransform(objPts,imgPts,H);

//这样求解出来的H,感觉有点忽悠人。上一语句的意思为,objPts为一长方形,imgPts为一梯形,所以以后再用H对整幅图像中进行变换显

//然能把原本为长方形的图像透视变换为一梯形,但是也不能成为俯视图么~而且对对objPts的边长放大10,效果又会变化很大。
 float aa=CV_MAT_ELEM(*H,float,2,2);
 printf("%f\n",aa);

 //用户操作
 float z=25;//预设高度
 int key=0;
 IplImage *birds_image=cvCloneImage(image);
 cvNamedWindow("Birds_Eye",0);

 while (key!=27)
 {
  CV_MAT_ELEM(*H,float,2,2)=z;//改变z的大小可以使得图像放大缩小,但不影响图像的透视变化后的形状。不明白其中的道理

  cvWarpPerspective(image,birds_image,H,CV_INTER_LINEAR|CV_WARP_INVERSE_MAP|CV_WARP_FILL_OUTLIERS);
  cvShowImage("Birds_Eye", birds_image);
  key = cvWaitKey();
  if(key == 'u') z += 0.5;
  if(key == 'd') z -= 0.5;
 }
 cvSave("H.xml",H);
 return 0;
}

程序上的问题已经在程序中用备注的方式说明

opencv 鸟瞰图变化实例_第1张图片

你可能感兴趣的:(image,filter,存储,float)