opencv单目摄像机标定
#include <cv.h>
#include <highgui.h>
#include <iostream>
#include <stdio.h>
#include <stdlib.h> using namespace std; int n_boards=;//图像数目
const int board_dt=;//等20帧每棋盘视图 //int sn_board=0;//成功找到角点的图像数目
int board_w;//图像的角点行列数 canshu
int board_h; //canshu
int main(int argc ,char * argv[])
{
/*读入图像*/
board_w=; //canshu
board_h=; //canshu
n_boards=; //canshu int board_n=board_h*board_w;//每幅图像的角点数
CvSize board_size=cvSize(board_w,board_h);//每幅图像的角点数
CvCapture*capture;
capture=cvCreateCameraCapture();
//assert(capture); if(!capture) { printf("\nCouldn't open the camera\n"); return -;}
cvNamedWindow("MyCalib");
cvNamedWindow("Raw Video"); //allocate storage
CvMat*object_points = cvCreateMat(board_n*n_boards,,CV_32FC1);
CvMat*image_points =cvCreateMat(board_n*n_boards,,CV_32FC1);
CvMat*point_counts =cvCreateMat(n_boards,,CV_32SC1);
CvMat * camera_matrix =cvCreateMat(,,CV_32FC1);//摄像机矩阵(内参数矩阵)
CvMat * distortion_coeffs=cvCreateMat(,,CV_32FC1);//畸变系数
CvPoint2D32f*corners=new CvPoint2D32f[board_n];//一幅图像的角点数组
int corner_count;
int successes=; // 本文 successes就是 sn_board
int step,frame=; IplImage*image=cvQueryFrame(capture);
IplImage *gray_image=cvCreateImage(cvGetSize(image),,);//创建头并分配数据 //亚像素subpixel
//capture corner views loop until we've got n_boards
//成功捕获(找到所有角点on the board) while (successes<n_boards)
{ //skip every board_dt frames to allow user to move chessboard
if(frame++%board_dt==)
{
int found=cvFindChessboardCorners(image,board_size,corners,&corner_count,CV_CALIB_CB_ADAPTIVE_THRESH|CV_CALIB_CB_FILTER_QUADS); //精确到亚像素,绘制棋盘角点
cvCvtColor(image,gray_image,CV_BGR2GRAY);
cvFindCornerSubPix(gray_image,corners,corner_count,cvSize(,),cvSize(-,-),cvTermCriteria(CV_TERMCRIT_EPS+CV_TERMCRIT_ITER,,0.1));
cvDrawChessboardCorners(image,board_size,corners,corner_count,found);
//cvShowImage("MyCalib",image); //如果得到一个好板,则把把它加入到我们的数据中
if(corner_count==board_n){ //xin
cvShowImage( "Calibration", image ); //show in color if we did collect the image
step=successes*board_n; //xin
for(int i=step,j=;j<board_n;++i,++j){
CV_MAT_ELEM(*image_points,float,i,) =corners[j].x;//CV_MAT_ELEM用来访问矩阵每个元素的宏,这个宏只对单通道矩阵有效,多通道会报错
CV_MAT_ELEM(*image_points,float,i,) =corners[j].y;//(要访问的矩阵,矩阵元素的类型,所要访问元素的行数,列数)
//上两句是将检测到的点以坐标形式存储
CV_MAT_ELEM(*object_points,float,i,) =float(j/board_w);
CV_MAT_ELEM(*object_points,float,i,) =float(j%board_w);
//上两句是将检测到的点的数目,以行列形式存储
CV_MAT_ELEM(*object_points,float,i,) =0.0f;
}
CV_MAT_ELEM(*point_counts,int,successes,)=board_n;
successes++;
printf("Collected our %d of %d needed chessboard images\n",successes,n_boards);
}
else
cvShowImage( "Calibration", gray_image );//Show Gray if we didn't collect the image
}//end skip board_dt between chessboard capture //暂停模块
int c = cvWaitKey();
if(c == 'p'){
c = ;
while(c != 'p' && c != ){
c = cvWaitKey();
}
}
if(c == )
return ;
image = cvQueryFrame( capture ); //Get next image
cvShowImage("Raw Video", image);
} //END COLLECTION WHILE LOOP.
cvDestroyWindow("Calibration");
printf("\n\n*** CALLIBRATING THE CAMERA..."); //重新赋值,又重新分配了矩阵空间
CvMat * object_points0= cvCreateMat(board_n*successes,,CV_32FC1);
CvMat * image_points0=cvCreateMat(board_n*successes,,CV_32FC1);
CvMat * point_counts0=cvCreateMat(successes,,CV_32SC1);
//transfer THE points INTO THE correct size matrices
for (int i=;i<successes*board_n;i++)//board_n为每幅图像的角点数*sn_board为成功找到角点的图像数目
{
CV_MAT_ELEM(*image_points0,float,i,)=CV_MAT_ELEM(*image_points,float,i,);
CV_MAT_ELEM(*image_points0,float,i,)=CV_MAT_ELEM(*image_points,float,i,);
CV_MAT_ELEM(*object_points0,float,i,)=CV_MAT_ELEM(*object_points,float,i,);
CV_MAT_ELEM(*object_points0,float,i,)=CV_MAT_ELEM(*object_points,float,i,);
CV_MAT_ELEM(*object_points0,float,i,)=0.0f;
}
for (int i=;i<successes;i++)
{
CV_MAT_ELEM(*point_counts0,int,i,)=CV_MAT_ELEM(*point_counts,int,i,);
}
cvReleaseMat(&object_points);//世界坐标点
cvReleaseMat(&point_counts); //每张图像中的角点数
cvReleaseMat(&image_points); //图像坐标点
//使用cvReleaseMat函数之后,系统将释放刚才载入矩阵的内存空间(也即这个矩阵已经不在内存中了) // At this point we have all of the chessboard corners we need
// Initialize the intrinsic matrix such that the two focal
// lengths have a ratio of 1.0
CV_MAT_ELEM( *camera_matrix, float, , ) = 1.0f;
CV_MAT_ELEM( *camera_matrix, float, , ) = 1.0f;
//CALIBRATE THE CAMERA!
cvCalibrateCamera2(
object_points0, image_points0,
point_counts0, cvGetSize( image ),
camera_matrix, distortion_coeffs,
NULL, NULL, //CV_CALIB_FIX_ASPECT_RATIO
); // SAVE THE INTRINSICS AND DISTORTIONS xin
printf("......保存内部参数与畸变参数\n");
cvSave("camera_matrix1111.xml",camera_matrix);
cvSave("distortion_coeffs.xml",distortion_coeffs); // EXAMPLE OF LOADING THESE MATRICES BACK IN: xin
CvMat *intrinsic = (CvMat*)cvLoad("Intrinsics.xml");
CvMat *distortion = (CvMat*)cvLoad("Distortion.xml"); // Build the undistort map which we will use for all
// subsequent frames.建立不失真的图map
//
IplImage* mapx = cvCreateImage( cvGetSize(image), IPL_DEPTH_32F, );
IplImage* mapy = cvCreateImage( cvGetSize(image), IPL_DEPTH_32F, );
cvInitUndistortMap(intrinsic,distortion,mapx, mapy); // Just run the camera to the screen, now showing the raw and
// the undistorted image.
//
cvNamedWindow( "Undistort" );
while(image) {
IplImage *t = cvCloneImage(image);
cvShowImage( "Raw Video", image ); // Show raw image
cvRemap( t, image, mapx, mapy ); // Undistort image
cvReleaseImage(&t);
cvShowImage("Undistort", image); // Show corrected image //Handle pause/unpause and ESC
int c = cvWaitKey();
if(c == 'p'){
c = ;
while(c != 'p' && c != ){
c = cvWaitKey();
}
}
if(c == )
break;
image = cvQueryFrame( capture );
} return ;
}
opencv单目摄像机标定的更多相关文章
- opencv单目摄像机标定(一)
#include <string> #include <iostream> #include <cv.h> #include <highgui.h> u ...
- opencv单目摄像机标定(二)
// 引入实际标定板方格宽度的标定程序 #include <string> #include <iostream> #include <cv.h> #include ...
- 机器视觉学习笔记(5)——基于OpenCV的单目摄像机标定
本文CameraCalibrator类源代码来自于OpenCV2 计算机视觉编程手册(Robert Laganiere 著 张静 译) 强烈建议阅读机器视觉学习笔记(4)--单目摄像机标定参数说明之后 ...
- 基于OpenCV单目相机的快速标定--源码、工程、实现过程
相机的标定是所有人走进视觉世界需要做的第一件事,辣么多的视觉标定原理解释你可以随便在网上找到,这里只讲到底如何去实现,也算是给刚入门的朋友做个简单的分享. 1.单目相机标定的工程源码 首先请到同性交友 ...
- matlab单目相机标定——标定步骤以及参数含义
参考博客园的一篇文章: https://www.cnblogs.com/flyinggod/p/8470407.html#commentform
- 基于EmguCV的摄像机标定及矫正
标签: EmguCV摄像头标定C# 2015-05-03 14:55 501人阅读 评论(6) 收藏 举报 分类: C# 版权声明:本文为博主原创文章,未经博主允许不得转载. 目录(?)[+] ...
- [OpenCV-Python] OpenCV 中摄像机标定和 3D 重构 部分 VII
部分 VII摄像机标定和 3D 重构 OpenCV-Python 中文教程(搬运)目录 42 摄像机标定 目标 • 学习摄像机畸变以及摄像机的内部参数和外部参数 • 学习找到这些参数,对畸变图像进行修 ...
- 【OpenCV】摄像机标定+畸变校正
摄像机标定 本文目的在于记录如何使用MATLAB做摄像机标定,并通过OpenCV进行校正后的显示. 首先关于校正的基本知识通过OpenCV官网的介绍即可简单了解: http://docs.open ...
- 用OpenCV进行摄像机标定
用OpenCV进行摄像机标定 照相机已经存在很长时间了.然而,随着廉价针孔相机在20世纪末的引入,日常生活中变得司空见惯.不幸的是,这种廉价伴随着它的代价:显著的扭曲.幸运的是,这些常数,通过校准和一 ...
随机推荐
- mac下有道词典用不了
有道词典 对于Chrome取词,通过安装插件就可以解决 Chrome 下取词的问题,这个插件就放在有道词典程序目录中.最简便的安装方法如下: 首先确保你已经安装好了有道词典.然后复 ...
- Web打印--Lodop API
Lodop是一款专业的WEB打印控件,其设计目标是简单易用.功能足够强大,开创WEB打印开发的新局面. Lodop设计者对WEB下的打印开发任务进行了分类汇总,高度抽象,设计出仅用几个功能函数,就可实 ...
- [转]在 ASP.NET MVC 4 中创建为移动设备优化的视图
原文链接 https://msdn.microsoft.com/zh-cn/magazine/dn296507.aspx 如果深入探讨有关编写移动设备网站的常识性考虑因素,会发现其中有一种内在矛盾. ...
- RBAC在thinkphp中有Auth类 可以很好的实现权限控制
import('ORG.Util.Auth');//加载类库 $auth=new Auth(); if($auth->check('show_button',1)){// 第一个参数是规则名称, ...
- 移动端自动化环境搭建-Appium Client的安装和AppiumLibrary库的安装
A.安装依赖 appium client是配合原生的webdriver来使用的(特别是用java而不用maven的同学),因此二者必须配合使用缺一不可. B.安装过程 1.在线安装 pip insta ...
- Android-monkey稳定性测试(多台设备同时进行)
1.目的(原创文章,转载请注明出处-) 主要为指引开展android平台应用的稳定性测试,尽可能地在应用发布前发现crash及an ...
- Parquet与ORC:高性能列式存储格式(收藏)
背景 随着大数据时代的到来,越来越多的数据流向了Hadoop生态圈,同时对于能够快速的从TB甚至PB级别的数据中获取有价值的数据对于一个产品和公司来说更加重要,在Hadoop生态圈的快速发展过程中,涌 ...
- C# Mysql You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ????
有几年没用过MySql数据了,今天在使用C#访问MySql数据库时出现了一个小插曲. 错误提示: You have an error in your SQL syntax; check the man ...
- InnoDB Checkpoints
检查点的工作机制: innodb会自动维护一个检查点的机制,叫做 fuzzy checkpointing(当然sharp checkpoint也是检查点之一),fuzzy checkpointing就 ...
- ASP.NET保存信息总结(Application、Session、Cookie、ViewState和Cache等) ZT
http://www.cnblogs.com/ranran/p/4065619.html http://www.cnblogs.com/jxlsomnus/p/4450911.html 以下是关于AS ...