zoukankan      html  css  js  c++  java
  • opencv单目摄像机标定(二)

     // 引入实际标定板方格宽度的标定程序
       #include <string>  
       #include <iostream>  
       #include <cv.h>  
       #include <highgui.h>  
        
    using namespace std;
    
    int main()
    {
    CvCapture* capture; //摄像头指针
    capture=cvCreateCameraCapture(0);
    if(capture==0){
    printf("无法捕获摄像头设备!
    
    ");
    return 0;
    }else{
    printf("捕获摄像头设备成功!!
    
    ");
    }
    IplImage* frame; //图像指针
    cvNamedWindow("摄像机帧截取窗口",1);
    printf("按“C”键截取当前帧并保存为标定图片...
    按“Q”键退出截取帧过程...
    
    ");
    int number_image=1; //文件名后的编号,从1开始,也是截取的图像帧数
    char filename[20]=""; //保存文件名的字符串数组
    while(true)
    {
    frame=cvQueryFrame(capture);
    if(!frame)
    break;
    cvShowImage("摄像机帧截取窗口",frame);
    
    if(cvWaitKey(10)=='c'){
    sprintf (filename,"%d.jpg",number_image);
    cvSaveImage(filename,frame);
    cout<<"成功获取当前帧,并以文件名"<<filename<<"保存...
    
    ";
    printf("按“C”键截取当前帧并保存为标定图片...
    按“Q”键退出截取帧过程...
    
    ");
    number_image++;
    }else if(cvWaitKey(10)=='q'){
    printf("截取图像帧过程完成...
    
    ");
    cout<<"共成功截取"<<--number_image<<"帧图像!!
    
    ";
    break;
    }
    }
    cvReleaseImage(&frame);
    cvReleaseCapture(&capture);
    cvDestroyWindow("摄像机帧截取窗口");
    
    IplImage * show; //RePlay图像指针
    cvNamedWindow("RePlay",1);
    int number_image_copy=number_image; //复制图像帧数
    CvSize board_size=cvSize(7,7); //标定板角点数
    CvSize2D32f square_size=cvSize2D32f(18.2,18.2); //cvSize2D32f( double width, double height );假设我的每个标定方格长宽都是1.82厘米
    float square_length=square_size.width; //方格长度
    float square_height=square_size.height; //方格高度
    int board_width=board_size.width; //每行角点数
    int board_height=board_size.height; //每列角点数
    int total_per_image=board_width*board_height; //每张图片角点总数
    int count; //存储每帧图像中实际识别的角点数
    int found; //识别标定板角点的标志位
    int step; //存储步长,step=successes*total_per_image;
    int successes=0; //存储成功找到标定板上所有角点的图像帧数
    int a=1; //临时变量,表示在操作第a帧图像
    
    CvPoint2D32f * image_points_buf = new CvPoint2D32f[total_per_image]; //存储角点图像坐标的数组
    CvMat * image_points=cvCreateMat(number_image*total_per_image,2,CV_32FC1); //存储角点的图像坐标的矩阵
    CvMat * object_points=cvCreateMat(number_image*total_per_image,3,CV_32FC1); //存储角点的三维坐标的矩阵
    CvMat * point_counts=cvCreateMat(number_image,1,CV_32SC1); //存储每帧图像的识别的角点数
    CvMat * intrinsic_matrix=cvCreateMat(3,3,CV_32FC1); //内参数矩阵
    CvMat * distortion_coeffs=cvCreateMat(5,1,CV_32FC1); //畸变系数
    
    
    while(a<=number_image_copy){
    sprintf (filename,"%d.jpg",a);
    show=cvLoadImage(filename,-1);
    found=cvFindChessboardCorners(show,board_size,image_points_buf,&count,
    CV_CALIB_CB_ADAPTIVE_THRESH|CV_CALIB_CB_FILTER_QUADS);
    if(found==0){ //如果没找到标定板角点时
    cout<<""<<a<<"帧图片无法找到棋盘格所有角点!
    
    ";
    cvNamedWindow("RePlay",1);
    cvShowImage("RePlay",show);
    cvWaitKey(0);
    
    }else{ //找到标定板角点时
    cout<<""<<a<<"帧图像成功获得"<<count<<"个角点...
    ";
    cvNamedWindow("RePlay",1);
    IplImage * gray_image= cvCreateImage(cvGetSize(show),8,1);
    cvCvtColor(show,gray_image,CV_BGR2GRAY);
    cout<<"获取源图像灰度图过程完成...
    ";
    cvFindCornerSubPix(gray_image,image_points_buf,count,cvSize(11,11),cvSize(-1,-1),
    cvTermCriteria(CV_TERMCRIT_EPS+CV_TERMCRIT_ITER,30,0.1));
    cout<<"灰度图亚像素化过程完成...
    ";
    cvDrawChessboardCorners(show,board_size,image_points_buf,count,found);
    cout<<"在源图像上绘制角点过程完成...
    
    ";
    cvShowImage("RePlay",show);
    cvWaitKey(0);
    }
    
    if(total_per_image==count){
    step=successes*total_per_image; //计算存储相应坐标数据的步长
    for(int i=step,j=0;j<total_per_image;++i,++j){
    CV_MAT_ELEM(*image_points,float,i,0)=image_points_buf[j].x;
    CV_MAT_ELEM(*image_points,float,i,1)=image_points_buf[j].y;
    CV_MAT_ELEM(*object_points,float,i,0)=(float)((j/board_width)*square_length);
    CV_MAT_ELEM(*object_points,float,i,1)=(float)((j%board_width)*square_height);
    CV_MAT_ELEM(*object_points,float,i,2)=0.0f;
    }
    CV_MAT_ELEM(*point_counts,int,successes,0)=total_per_image;
    successes++;
    }
    a++;
    }
    
    cvReleaseImage(&show);
    cvDestroyWindow("RePlay");
    
    
    cout<<"*********************************************
    ";
    cout<<number_image<<"帧图片中,标定成功的图片为"<<successes<<"帧...
    ";
    cout<<number_image<<"帧图片中,标定失败的图片为"<<number_image-successes<<"帧...
    
    ";
    cout<<"*********************************************
    
    ";
    
    cout<<"按任意键开始计算摄像机内参数...
    
    ";
    
    CvCapture* capture1;
    capture1=cvCreateCameraCapture(0);
    IplImage * show_colie;
    show_colie=cvQueryFrame(capture1);
    
    CvMat * object_points2=cvCreateMat(successes*total_per_image,3,CV_32FC1);
    CvMat * image_points2=cvCreateMat(successes*total_per_image,2,CV_32FC1);
    CvMat * point_counts2=cvCreateMat(successes,1,CV_32SC1);
    
    for(int i=0;i<successes*total_per_image;++i){
    CV_MAT_ELEM(*image_points2,float,i,0)=CV_MAT_ELEM(*image_points,float,i,0);
    CV_MAT_ELEM(*image_points2,float,i,1)=CV_MAT_ELEM(*image_points,float,i,1);
    CV_MAT_ELEM(*object_points2,float,i,0)=CV_MAT_ELEM(*object_points,float,i,0);
    CV_MAT_ELEM(*object_points2,float,i,1)=CV_MAT_ELEM(*object_points,float,i,1);
    CV_MAT_ELEM(*object_points2,float,i,2)=CV_MAT_ELEM(*object_points,float,i,2);
    }
    
    for(int i=0;i<successes;++i){
    CV_MAT_ELEM(*point_counts2,int,i,0)=CV_MAT_ELEM(*point_counts,int,i,0);
    }
    
    cvReleaseMat(&object_points);
    cvReleaseMat(&image_points);
    cvReleaseMat(&point_counts);
    
        //初始化相机内参矩阵
    CV_MAT_ELEM(*intrinsic_matrix,float,0,0)=1.0f;
    CV_MAT_ELEM(*intrinsic_matrix,float,1,1)=1.0f;
    
     //标定相机的内参矩阵和畸变系数向量
    cvCalibrateCamera2(object_points2,image_points2,point_counts2,cvGetSize(show_colie),
    intrinsic_matrix,distortion_coeffs,NULL,NULL,0);
    
    cout<<"摄像机内参数矩阵为:
    ";
    cout<<CV_MAT_ELEM(*intrinsic_matrix,float,0,0)<<" "<<CV_MAT_ELEM(*intrinsic_matrix,float,0,1)
    <<" "<<CV_MAT_ELEM(*intrinsic_matrix,float,0,2)
    <<"
    
    ";
    cout<<CV_MAT_ELEM(*intrinsic_matrix,float,1,0)<<" "<<CV_MAT_ELEM(*intrinsic_matrix,float,1,1)
    <<" "<<CV_MAT_ELEM(*intrinsic_matrix,float,1,2)
    <<"
    
    ";
    cout<<CV_MAT_ELEM(*intrinsic_matrix,float,2,0)<<" "<<CV_MAT_ELEM(*intrinsic_matrix,float,2,1)
    <<" "<<CV_MAT_ELEM(*intrinsic_matrix,float,2,2)
    <<"
    
    ";
    
    cout<<"畸变系数矩阵为:
    ";
    cout<<CV_MAT_ELEM(*distortion_coeffs,float,0,0)<<" "<<CV_MAT_ELEM(*distortion_coeffs,float,1,0)
    <<" "<<CV_MAT_ELEM(*distortion_coeffs,float,2,0)
    <<" "<<CV_MAT_ELEM(*distortion_coeffs,float,3,0)
    <<" "<<CV_MAT_ELEM(*distortion_coeffs,float,4,0)
    <<"
    
    ";
    
    cvSave("Intrinsics.xml",intrinsic_matrix);
    cvSave("Distortion.xml",distortion_coeffs);
    
    cout<<"摄像机矩阵、畸变系数向量已经分别存储在名为Intrinsics.xml、Distortion.xml文档中
    
    ";
    
    CvMat * intrinsic=(CvMat *)cvLoad("Intrinsics.xml");
    CvMat * distortion=(CvMat *)cvLoad("Distortion.xml");
    
    IplImage * mapx=cvCreateImage(cvGetSize(show_colie),IPL_DEPTH_32F,1);
    IplImage * mapy=cvCreateImage(cvGetSize(show_colie),IPL_DEPTH_32F,1);
    
    cvInitUndistortMap(intrinsic,distortion,mapx,mapy);
    
    cvNamedWindow("原始图像",1);
    cvNamedWindow("非畸变图像",1);
    
    cout<<"按‘E’键退出显示...
    
    ";
    
    while(show_colie){
    IplImage * clone=cvCloneImage(show_colie);
    cvShowImage("原始图像",show_colie);
    cvRemap(clone,show_colie,mapx,mapy);
    cvReleaseImage(&clone);
    cvShowImage("非畸变图像",show_colie);
    
    if(cvWaitKey(10)=='e'){
    break;
    }
    
    show_colie=cvQueryFrame(capture1);
    }
    
    return 0;
    
    }

     

  • 相关阅读:
    进程与线程的区别
    开启线程的两种方式
    线程
    生产者消费者模型(重要)
    队列
    互斥锁
    守护进程(了解)
    Process对象的其它方法与属性(join)
    僵尸进程与孤儿进程
    Servlet
  • 原文地址:https://www.cnblogs.com/Jessica-jie/p/6126170.html
Copyright © 2011-2022 走看看