#include "Stafx.h"

 ;   //棋盘上有13个格子,那么角点的数目12
 ;
 ;  //图片的总张数
 int main(int argc, char** argv)
 {
     ;
     int board_n=board_h*board_w;  //一张图像上,角点的数目
     CvSize board_sz=cvSize(board_w,board_h);
     CvMat* object_points=cvCreateMat(image_count*board_n,,CV_32FC1);  //实际坐标系(以棋盘左上角第一个角点为坐标原点),角点的坐标,单位是方块
     CvMat* image_points=cvCreateMat(image_count*board_n,,CV_32FC1);   //在图像上找到角点的坐标,坐标原点图像左上角,单位像素
     CvMat* point_counts=cvCreateMat(board_n,,CV_32SC1);    //每个图像上角点个数

     ;    //累计图像上所有角点被找到图像的张数
     while (count++<image_count)
     {
         std::string filename="E:\\软件学习\\LearningOpenCV_Code\\calibration\\";
         ];
         itoa(count,str,);//转换为字符串
         std::string str1;
         int length=strlen(str);
         *(str+length)='.';
         *(str+length+)='j';
         *(str+length+)='p';
         *(str+length+)='g';
         *(str+length+)='\0';
         str1=str;
         filename+=str1;
         IplImage* src=cvLoadImage(filename.c_str(),CV_LOAD_IMAGE_UNCHANGED);
         IplImage* gray=cvCreateImage(cvGetSize(src),IPL_DEPTH_8U,);
         cvCvtColor(src,gray,CV_RGB2GRAY);
         CvPoint2D32f* corners=new CvPoint2D32f[board_n];  //一张图像上角点的坐标
         int corner_count;     //一张图像上角点的数目
         int found=cvFindChessboardCorners(src,board_sz,corners,&corner_count,
                                 CV_CALIB_CB_ADAPTIVE_THRESH|CV_CALIB_CB_FILTER_QUADS);//找到棋盘的角点,如果所有角点找到返回1,否则返回0,这里指的是所有的角点

         cvFindCornerSubPix(gray, corners, corner_count, cvSize(,),cvSize(-,-),
                             cvTermCriteria(CV_TERMCRIT_EPS+CV_TERMCRIT_ITER,, 0.1)); //寻找亚素点,gray一定要是8位单通道的图像
         cvDrawChessboardCorners(src,board_sz,corners,corner_count,found);             //将角点画出,src一定要是彩色图像
         //cvShowImage("1",src);
         //cvWaitKey();
         if (corner_count==board_n)  //一张图像上所有角点被找到
         {
             int step=a*board_n;  //第k幅角点全部找到图像上角点的存储的起始地址
             ;
             for (int i=step;j<corner_count;i++,j++)
             {
                 CV_MAT_ELEM(*object_points,)=j/board_w;  //角点的横坐标,单位不是像素,而是以棋盘上每个方块为一个单位
                 CV_MAT_ELEM(*object_points,)=j%board_w;  //角点的纵坐标,每个方块为一个单位
                 CV_MAT_ELEM(*object_points,)=;      //齐次坐标,表示点
                 CV_MAT_ELEM(*image_points,)=corners[j].x; //图像坐标系的坐标
                 CV_MAT_ELEM(*image_points,)=corners[j].y;
             };
             CV_MAT_ELEM(*point_counts,)=board_n;
             a++;
         }
     }
     //由于图像中存在所有角点未找到的情况,所以上面object_points的空间未存满,需要重新定义
     CvMat* object_points2=cvCreateMat(a*board_n,,CV_32FC1);
     CvMat* image_points2=cvCreateMat(a*board_n,,CV_32FC1);
     CvMat* point_counts2=cvCreateMat(a,,CV_32SC1);
     CvMat* intrinsic_matrix=cvCreateMat(,,CV_32FC1);   //相机内参数矩阵
     CvMat* distortion_coeffs=cvCreateMat(,,CV_32FC1);  //畸变系数矩阵
     CvMat* rotation_vector=cvCreateMat(a,,CV_32FC1);    //旋转矩阵
     CvMat* translation_vector=cvCreateMat(a,,CV_32FC1);  //平移矩阵
     ;i<a*board_n;i++)
     {
         CV_MAT_ELEM(*object_points2,)=CV_MAT_ELEM(*object_points,);
         CV_MAT_ELEM(*object_points2,)=CV_MAT_ELEM(*object_points,);
         CV_MAT_ELEM(*object_points2,)=;
         CV_MAT_ELEM(*image_points2,)=CV_MAT_ELEM(*image_points,);
         CV_MAT_ELEM(*image_points2,)=CV_MAT_ELEM(*image_points,);
     }
     ;i<a;i++)
         CV_MAT_ELEM(*point_counts2,)=CV_MAT_ELEM(*point_counts,);
     cvReleaseMat(&object_points);
     cvReleaseMat(&image_points);
     cvReleaseMat(&point_counts);
     //内置参数矩阵设置,初始化
     CV_MAT_ELEM(*intrinsic_matrix,,)=1.0;
     CV_MAT_ELEM(*intrinsic_matrix,,)=1.0;
     //校正相机参数,cvSize(1600,1200)为输入图像的真实长度和宽度,单位为像素
     cvCalibrateCamera2(object_points2,image_points2,point_counts2,cvSize(,),
                             intrinsic_matrix,distortion_coeffs,rotation_vector,translation_vector,CV_CALIB_FIX_ASPECT_RATIO);
     //图像校正
     IplImage* mapx=cvCreateImage(cvSize(,),IPL_DEPTH_32F,);
     IplImage* mapy=cvCreateImage(cvSize(,),IPL_DEPTH_32F,);
     cvInitUndistortMap(intrinsic_matrix,distortion_coeffs,mapx,mapy);
     IplImage* test_image=cvLoadImage("E:\\软件学习\\LearningOpenCV_Code\\calibration\\22.jpg",CV_LOAD_IMAGE_UNCHANGED);
     if (!test_image)
     {
         std::cout<<"error"<<std::endl;
     }
     cvShowImage("原图像",test_image);
     IplImage* t=cvCloneImage(test_image);
     cvRemap(t,test_image,mapx,mapy);
     cvShowImage("校正后图像",test_image);
     cvWaitKey();
     ;
 }

测试图片:opencv课后习题答案中LearningOpencv_Code中calibration文件中的图片

利用opencv进行相机标定程序的更多相关文章

  1. 【opencv】相机标定程序内存溢出

    运行相机内参标定程序出现内存溢出的错误 opencv的alloc.cpp报cv::OutOfMemoryError 因为同时开了多个线程,每个线程标定一台相机,每个线程都会imread读入所有标定图片 ...

  2. 使用OpenCV进行相机标定

    1. 使用OpenCV进行标定 相机已经有很长一段历史了.但是,伴随着20世纪后期的廉价针孔照相机的问世,它们已经变成我们日常生活的一种常见的存在.不幸的是,这种廉价是由代价的:显著的变形.幸运的是, ...

  3. 相机标定 matlab opencv ROS三种方法标定步骤(2)

    二  ubuntu下Opencv的相机标定 一般直接用Opencv的源码就可以进行相机的标定,但是可能只是会实现结果,却不懂实现的过程,我也是模模糊糊的看了<计算机视觉中的多视图几何>以及 ...

  4. 相机标定问题-Matlab & Py-Opencv

    一.相机标定基本理论 1.相机成像系统介绍 图中总共有4个坐标系: 图像坐标系:Op    坐标表示方法(u,v)                 Unit:Dots(个) 成像坐标系:Oi      ...

  5. 张正友相机标定Opencv实现以及标定流程&&标定结果评价&&图像矫正流程解析(附标定程序和棋盘图)

    使用Opencv实现张正友法相机标定之前,有几个问题事先要确认一下,那就是相机为什么需要标定,标定需要的输入和输出分别是哪些? 相机标定的目的:获取摄像机的内参和外参矩阵(同时也会得到每一幅标定图像的 ...

  6. Opencv——相机标定

    相机标定的目的:获取摄像机的内参和外参矩阵(同时也会得到每一幅标定图像的选择和平移矩阵),内参和外参系数可以对之后相机拍摄的图像就进行矫正,得到畸变相对很小的图像. 相机标定的输入:标定图像上所有内角 ...

  7. 相机标定过程(opencv) + matlab参数导入opencv + matlab标定和矫正

    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 辛苦原创所得,转载请注明出处 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ...

  8. Camera Calibration 相机标定:Opencv应用方法

    本系列文章由 @YhL_Leo 出品,转载请注明出处. 文章链接: http://blog.csdn.net/yhl_leo/article/details/49427383 Opencv中Camer ...

  9. 双目相机标定以及立体测距原理及OpenCV实现

    单目相机标定的目标是获取相机的内参和外参,内参(1/dx,1/dy,Cx,Cy,f)表征了相机的内部结构参数,外参是相机的旋转矩阵R和平移向量t.内参中dx和dy是相机单个感光单元芯片的长度和宽度,是 ...

随机推荐

  1. tomcat bin 中startup.sh中的环境变量配置

    JAVA_HOME=/usr/lib/jvm/java-1.7.0-openjdk-amd64 JRE_HOME=/usr/lib/jvm/java-1.7.0-openjdk-amd64/jre P ...

  2. 【leetcode】Reverse Linked List II (middle)

    Reverse a linked list from position m to n. Do it in-place and in one-pass. For example:Given 1-> ...

  3. iOS-JavaScript向WKWebView传值

    一.本地代码所需操作 1.创建viewController并遵守协议 @interface ViewController ()<WKNavigationDelegate,WKScriptMess ...

  4. PHP安全编程:过滤用户输入

    如果你能正确可靠地识别和过滤输入,你的工作就基本完成了.最后一步是使用一个命名约定或其它可以帮助你正确和可靠地区分已过滤和被污染数据的方 法.我推荐一个比较简单的命名约定,因为它可以同时用在面向过程和 ...

  5. EF性能调优

    首先说明下: 第一次运行真是太慢了,处理9600多个员工数据,用了81分钟!! 代码也挺简单,主要是得到数据-->对比分析-->插入分析结果到数据库.用的是EF的操作模式. public ...

  6. Mac下java开发环境的搭建与开发工具的安装

    一.安装JDK 1.根据你当前环境的需要,下载相应的JDK并安装,安装步骤与其他Mac软件安装方法相同,我安装的是jdk1.8.0_74.jdk,mac中jdk1.8的默认位置:/Library/Ja ...

  7. vector reserve与resize区别

    vector 的reserve增加了vector的capacity,但是它的size没有改变!而resize改变了vector的capacity同时也增加了它的size!原因如下:reserve是容器 ...

  8. 51nod1019逆序数(归并排序/树状数组)

    题目链接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1019 题意:中文题诶- 思路: 方法1:归并排序- 归并排序过 ...

  9. android DisplayMetrics 获取屏幕分辨率

    Android 提供DisplayMetircs 类可以很方便的获取分辨率.下面介绍 DisplayMetics 类: Andorid.util 包下的DisplayMetrics 类提供了一种关于显 ...

  10. Xcode常用代码块

    Xcode的代码片段(Code Snippets)创建自定义的代码片段,当你重用这些代码片段时,会给你带来很大的方便. 常用的: 1.strong:@property (nonatomic,stron ...