利用opencv进行相机标定程序
#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进行相机标定程序的更多相关文章
- 【opencv】相机标定程序内存溢出
运行相机内参标定程序出现内存溢出的错误 opencv的alloc.cpp报cv::OutOfMemoryError 因为同时开了多个线程,每个线程标定一台相机,每个线程都会imread读入所有标定图片 ...
- 使用OpenCV进行相机标定
1. 使用OpenCV进行标定 相机已经有很长一段历史了.但是,伴随着20世纪后期的廉价针孔照相机的问世,它们已经变成我们日常生活的一种常见的存在.不幸的是,这种廉价是由代价的:显著的变形.幸运的是, ...
- 相机标定 matlab opencv ROS三种方法标定步骤(2)
二 ubuntu下Opencv的相机标定 一般直接用Opencv的源码就可以进行相机的标定,但是可能只是会实现结果,却不懂实现的过程,我也是模模糊糊的看了<计算机视觉中的多视图几何>以及 ...
- 相机标定问题-Matlab & Py-Opencv
一.相机标定基本理论 1.相机成像系统介绍 图中总共有4个坐标系: 图像坐标系:Op 坐标表示方法(u,v) Unit:Dots(个) 成像坐标系:Oi ...
- 张正友相机标定Opencv实现以及标定流程&&标定结果评价&&图像矫正流程解析(附标定程序和棋盘图)
使用Opencv实现张正友法相机标定之前,有几个问题事先要确认一下,那就是相机为什么需要标定,标定需要的输入和输出分别是哪些? 相机标定的目的:获取摄像机的内参和外参矩阵(同时也会得到每一幅标定图像的 ...
- Opencv——相机标定
相机标定的目的:获取摄像机的内参和外参矩阵(同时也会得到每一幅标定图像的选择和平移矩阵),内参和外参系数可以对之后相机拍摄的图像就进行矫正,得到畸变相对很小的图像. 相机标定的输入:标定图像上所有内角 ...
- 相机标定过程(opencv) + matlab参数导入opencv + matlab标定和矫正
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 辛苦原创所得,转载请注明出处 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ...
- Camera Calibration 相机标定:Opencv应用方法
本系列文章由 @YhL_Leo 出品,转载请注明出处. 文章链接: http://blog.csdn.net/yhl_leo/article/details/49427383 Opencv中Camer ...
- 双目相机标定以及立体测距原理及OpenCV实现
单目相机标定的目标是获取相机的内参和外参,内参(1/dx,1/dy,Cx,Cy,f)表征了相机的内部结构参数,外参是相机的旋转矩阵R和平移向量t.内参中dx和dy是相机单个感光单元芯片的长度和宽度,是 ...
随机推荐
- NGUI 不写一行代码实现翻拍效果
正面UI添加一个TweenRotation组件,取消掉Active状态 ,To参数改成0,90,0) 背面UI添加一个TweenRotation组件,取消掉Active状态, From参数改成0,27 ...
- 解读Unity中的CG编写Shader系列八(多光源漫反射)
转自http://www.itnose.net/detail/6117338.html 前文中完成最简单的漫反射shader只是单个光源下的漫反射,而往往场景中不仅仅只有一个光源,那么多个光源的情况下 ...
- STL:原地归并排序模板(InplaceMergeSort)
原理:就是在归并排序上改进,以时间复杂度换空间复杂度,利用元素反转完成排序 具体过程如下: 具体操作看代码吧,应该没什么难度,主要是reverse要反转三次 typedef int Position; ...
- Linux rpm 命令参数使用详解[介绍和应用]
RPM是RedHat Package Manager(RedHat软件包管理工具)类似Windows里面的“添加/删除程序” rpm 执行安装包 二进制包(Binary)以及源代码包(Source)两 ...
- 【mongo】Can't take a write lock while out of disk space错误
今天遇到了这个错误,各种无法操作.找了很久的方案,都没用.最终发现,原来是我虚拟机硬盘满了......清除了些没用的东西,就恢复了.
- LeetCode 441 Arranging Coins
Problem: You have a total of n coins that you want to form in a staircase shape, where every k-th ro ...
- UVA 10815 Andy's First Dictionary ---set
题目链接 题意:输入一个文本,找出所有不同的单词(连续的字母序列),按字典序从小到大输出.单词不区分大小写. 刘汝佳算法竞赛入门经典(第二版)P112 #include <iostream> ...
- codeforces gym 100286 H - Hell on the Markets (贪心算法)
题目链接 题意:n个数分别为a[i],问是否存在一组对应的b[i],b[i]=1 || b[i]=-1,使得ai*bi的n项和为0. 题解: 先证明一个结论吧,对于1≤ai≤i+1,前面ai个数一定可 ...
- 完美解决:Could not retrieve mirrorlist http://mirrorlist.centos.org/?release=6&arch=x
如题: 原因:没有配置resolv.conf 解决方法: 到/etc目录下配置resolv.conf加入nameserver IP,如: nameserver 8.8.8.8nameserver 8. ...
- 多线程编程3 - GCD
一.简介 在iOS所有实现多线程的方案中,GCD应该是最有魅力的,因为GCD本身是苹果公司为多核的并行运算提出的解决方案.GCD在工作时会自动利用更多的处理器核心,以充分利用更强大的机器.GCD是Gr ...