opencv单目摄像机标定(二)
- // 引入实际标定板方格宽度的标定程序
- #include <string>
- #include <iostream>
- #include <cv.h>
- #include <highgui.h>
- using namespace std;
- int main()
- {
- CvCapture* capture; //摄像头指针
- capture=cvCreateCameraCapture();
- if(capture==){
- printf("无法捕获摄像头设备!\n\n");
- return ;
- }else{
- printf("捕获摄像头设备成功!!\n\n");
- }
- IplImage* frame; //图像指针
- cvNamedWindow("摄像机帧截取窗口",);
- printf("按“C”键截取当前帧并保存为标定图片...\n按“Q”键退出截取帧过程...\n\n");
- int number_image=; //文件名后的编号,从1开始,也是截取的图像帧数
- char filename[]=""; //保存文件名的字符串数组
- while(true)
- {
- frame=cvQueryFrame(capture);
- if(!frame)
- break;
- cvShowImage("摄像机帧截取窗口",frame);
- if(cvWaitKey()=='c'){
- sprintf (filename,"%d.jpg",number_image);
- cvSaveImage(filename,frame);
- cout<<"成功获取当前帧,并以文件名"<<filename<<"保存...\n\n";
- printf("按“C”键截取当前帧并保存为标定图片...\n按“Q”键退出截取帧过程...\n\n");
- number_image++;
- }else if(cvWaitKey()=='q'){
- printf("截取图像帧过程完成...\n\n");
- cout<<"共成功截取"<<--number_image<<"帧图像!!\n\n";
- break;
- }
- }
- cvReleaseImage(&frame);
- cvReleaseCapture(&capture);
- cvDestroyWindow("摄像机帧截取窗口");
- IplImage * show; //RePlay图像指针
- cvNamedWindow("RePlay",);
- int number_image_copy=number_image; //复制图像帧数
- CvSize board_size=cvSize(,); //标定板角点数
- 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=; //存储成功找到标定板上所有角点的图像帧数
- int a=; //临时变量,表示在操作第a帧图像
- CvPoint2D32f * image_points_buf = new CvPoint2D32f[total_per_image]; //存储角点图像坐标的数组
- CvMat * image_points=cvCreateMat(number_image*total_per_image,,CV_32FC1); //存储角点的图像坐标的矩阵
- CvMat * object_points=cvCreateMat(number_image*total_per_image,,CV_32FC1); //存储角点的三维坐标的矩阵
- CvMat * point_counts=cvCreateMat(number_image,,CV_32SC1); //存储每帧图像的识别的角点数
- CvMat * intrinsic_matrix=cvCreateMat(,,CV_32FC1); //内参数矩阵
- CvMat * distortion_coeffs=cvCreateMat(,,CV_32FC1); //畸变系数
- while(a<=number_image_copy){
- sprintf (filename,"%d.jpg",a);
- show=cvLoadImage(filename,-);
- found=cvFindChessboardCorners(show,board_size,image_points_buf,&count,
- CV_CALIB_CB_ADAPTIVE_THRESH|CV_CALIB_CB_FILTER_QUADS);
- if(found==){ //如果没找到标定板角点时
- cout<<"第"<<a<<"帧图片无法找到棋盘格所有角点!\n\n";
- cvNamedWindow("RePlay",);
- cvShowImage("RePlay",show);
- cvWaitKey();
- }else{ //找到标定板角点时
- cout<<"第"<<a<<"帧图像成功获得"<<count<<"个角点...\n";
- cvNamedWindow("RePlay",);
- IplImage * gray_image= cvCreateImage(cvGetSize(show),,);
- cvCvtColor(show,gray_image,CV_BGR2GRAY);
- cout<<"获取源图像灰度图过程完成...\n";
- cvFindCornerSubPix(gray_image,image_points_buf,count,cvSize(,),cvSize(-,-),
- cvTermCriteria(CV_TERMCRIT_EPS+CV_TERMCRIT_ITER,,0.1));
- cout<<"灰度图亚像素化过程完成...\n";
- cvDrawChessboardCorners(show,board_size,image_points_buf,count,found);
- cout<<"在源图像上绘制角点过程完成...\n\n";
- cvShowImage("RePlay",show);
- cvWaitKey();
- }
- if(total_per_image==count){
- step=successes*total_per_image; //计算存储相应坐标数据的步长
- for(int i=step,j=;j<total_per_image;++i,++j){
- CV_MAT_ELEM(*image_points,float,i,)=image_points_buf[j].x;
- CV_MAT_ELEM(*image_points,float,i,)=image_points_buf[j].y;
- CV_MAT_ELEM(*object_points,float,i,)=(float)((j/board_width)*square_length);
- CV_MAT_ELEM(*object_points,float,i,)=(float)((j%board_width)*square_height);
- CV_MAT_ELEM(*object_points,float,i,)=0.0f;
- }
- CV_MAT_ELEM(*point_counts,int,successes,)=total_per_image;
- successes++;
- }
- a++;
- }
- cvReleaseImage(&show);
- cvDestroyWindow("RePlay");
- cout<<"*********************************************\n";
- cout<<number_image<<"帧图片中,标定成功的图片为"<<successes<<"帧...\n";
- cout<<number_image<<"帧图片中,标定失败的图片为"<<number_image-successes<<"帧...\n\n";
- cout<<"*********************************************\n\n";
- cout<<"按任意键开始计算摄像机内参数...\n\n";
- CvCapture* capture1;
- capture1=cvCreateCameraCapture();
- IplImage * show_colie;
- show_colie=cvQueryFrame(capture1);
- CvMat * object_points2=cvCreateMat(successes*total_per_image,,CV_32FC1);
- CvMat * image_points2=cvCreateMat(successes*total_per_image,,CV_32FC1);
- CvMat * point_counts2=cvCreateMat(successes,,CV_32SC1);
- for(int i=;i<successes*total_per_image;++i){
- CV_MAT_ELEM(*image_points2,float,i,)=CV_MAT_ELEM(*image_points,float,i,);
- CV_MAT_ELEM(*image_points2,float,i,)=CV_MAT_ELEM(*image_points,float,i,);
- CV_MAT_ELEM(*object_points2,float,i,)=CV_MAT_ELEM(*object_points,float,i,);
- CV_MAT_ELEM(*object_points2,float,i,)=CV_MAT_ELEM(*object_points,float,i,);
- CV_MAT_ELEM(*object_points2,float,i,)=CV_MAT_ELEM(*object_points,float,i,);
- }
- for(int i=;i<successes;++i){
- CV_MAT_ELEM(*point_counts2,int,i,)=CV_MAT_ELEM(*point_counts,int,i,);
- }
- cvReleaseMat(&object_points);
- cvReleaseMat(&image_points);
- cvReleaseMat(&point_counts);
- //初始化相机内参矩阵
- CV_MAT_ELEM(*intrinsic_matrix,float,,)=1.0f;
- CV_MAT_ELEM(*intrinsic_matrix,float,,)=1.0f;
- //标定相机的内参矩阵和畸变系数向量
- cvCalibrateCamera2(object_points2,image_points2,point_counts2,cvGetSize(show_colie),
- intrinsic_matrix,distortion_coeffs,NULL,NULL,);
- cout<<"摄像机内参数矩阵为:\n";
- cout<<CV_MAT_ELEM(*intrinsic_matrix,float,,)<<" "<<CV_MAT_ELEM(*intrinsic_matrix,float,,)
- <<" "<<CV_MAT_ELEM(*intrinsic_matrix,float,,)
- <<"\n\n";
- cout<<CV_MAT_ELEM(*intrinsic_matrix,float,,)<<" "<<CV_MAT_ELEM(*intrinsic_matrix,float,,)
- <<" "<<CV_MAT_ELEM(*intrinsic_matrix,float,,)
- <<"\n\n";
- cout<<CV_MAT_ELEM(*intrinsic_matrix,float,,)<<" "<<CV_MAT_ELEM(*intrinsic_matrix,float,,)
- <<" "<<CV_MAT_ELEM(*intrinsic_matrix,float,,)
- <<"\n\n";
- cout<<"畸变系数矩阵为:\n";
- cout<<CV_MAT_ELEM(*distortion_coeffs,float,,)<<" "<<CV_MAT_ELEM(*distortion_coeffs,float,,)
- <<" "<<CV_MAT_ELEM(*distortion_coeffs,float,,)
- <<" "<<CV_MAT_ELEM(*distortion_coeffs,float,,)
- <<" "<<CV_MAT_ELEM(*distortion_coeffs,float,,)
- <<"\n\n";
- cvSave("Intrinsics.xml",intrinsic_matrix);
- cvSave("Distortion.xml",distortion_coeffs);
- cout<<"摄像机矩阵、畸变系数向量已经分别存储在名为Intrinsics.xml、Distortion.xml文档中\n\n";
- CvMat * intrinsic=(CvMat *)cvLoad("Intrinsics.xml");
- CvMat * distortion=(CvMat *)cvLoad("Distortion.xml");
- IplImage * mapx=cvCreateImage(cvGetSize(show_colie),IPL_DEPTH_32F,);
- IplImage * mapy=cvCreateImage(cvGetSize(show_colie),IPL_DEPTH_32F,);
- cvInitUndistortMap(intrinsic,distortion,mapx,mapy);
- cvNamedWindow("原始图像",);
- cvNamedWindow("非畸变图像",);
- cout<<"按‘E’键退出显示...\n\n";
- while(show_colie){
- IplImage * clone=cvCloneImage(show_colie);
- cvShowImage("原始图像",show_colie);
- cvRemap(clone,show_colie,mapx,mapy);
- cvReleaseImage(&clone);
- cvShowImage("非畸变图像",show_colie);
- if(cvWaitKey()=='e'){
- break;
- }
- show_colie=cvQueryFrame(capture1);
- }
- return ;
- }
opencv单目摄像机标定(二)的更多相关文章
- opencv单目摄像机标定(一)
#include <string> #include <iostream> #include <cv.h> #include <highgui.h> u ...
- opencv单目摄像机标定
#include <cv.h> #include <highgui.h> #include <iostream> #include <stdio.h> ...
- 机器视觉学习笔记(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世纪末的引入,日常生活中变得司空见惯.不幸的是,这种廉价伴随着它的代价:显著的扭曲.幸运的是,这些常数,通过校准和一 ...
随机推荐
- Eclipse导入Tomcat源码(转)
想要研究下Tomcat的体系结构或者源码,最好将Tomcat的源码导入到ide中,编写实例进行代码跟踪(debug). 这里参考了网上一些资料,将自己操作过程记个流水账. 准备: 1.Tomcat源码 ...
- backprop示例
http://home.agh.edu.pl/~vlsi/AI/backp_t_en/backprop.html
- 20条Linux命令面试问答
程序师 http://www.techug.com/20-linux-command-interview-questions 问:1 如何查看当前的Linux服务器的运行级别? 答: ‘who -r ...
- 英语学习app分析
以下数据分析由队员张波收集整理队员链接 队友的博客 一.数据统计 为了让统计数据更加准确可信,我们选取了三款android平台的应用市场软件作为数据的来源. 英语学习app下载量统计表: 序号 应用名 ...
- grub的sol
http://smcijohnny.blogspot.com/2015/06/linuxsolserial-over-lan.html https://www.hiroom2.com/2016/06/ ...
- Openstack Day1简介及虚拟环境搭建
本文章仅作为作者本人存档记忆!恕不详细展开内容! openstack kilo版本重要组件(module)简介 ======================================= Ke ...
- 关于Oracle数据库字符集
我们现在使用的字符集有以下两种: 推荐使用 AL32UTF8,避免以后数据导入导出字符集不同的麻烦. 推荐数据库设置参考图:
- Ninject之旅之六:Ninject约定
摘要 在小的应用系统中一个一个注册一些服务类型不怎么困难.但是,如果是一个实际的有上百个服务的应用程序呢?约定配置允许我们使用约定绑定一组服务,而不用一个一个分别绑定. 要使用约定配置,需要添加Nin ...
- 解决ASP.Net第一次访问慢的处理(IIS8)
本篇经验以IIS8,Windows Server 2012R2做为案例. IIS8 运行在 Windows Server 2012 and Windows 8 版本以上的平台上. IIS中应用程序池和 ...
- PHP简单利用token防止表单重复提交
<?php /* * PHP简单利用token防止表单重复提交 * 此处理方法纯粹是为了给初学者参考 */ session_start(); function set_token() { $_S ...