第二周02:Fusion ICP逐帧融合
本周主要任务02:Fusion 使用ICP进行逐帧融合
任务时间: 2014年9月8日-2014年9月14日
任务完成情况:
已实现将各帧融合到统一的第一帧所定义的摄像机坐标系下,但是由于部分帧之间的ICP融合结果 不佳,导致所有帧融合在统一坐标系下结果不好。
任务涉及基本方法:
1.exe文件当前目录搜索文件
程序文件:
fusion.cpp
//fusion.cpp
//函数:main()
//功能:
//输入:
//创建时间:2014/09/10
//最近更新时间:2014/09/16
//创建者:肖泽东 #include <iostream>
#include <fstream> #include <pcl/io/pcd_io.h>
#include <pcl/io/io.h>
#include <pcl/point_cloud.h>
#include <pcl/console/parse.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <pcl/registration/icp.h>
int state = ;
bool next_flag = false; //显示帮助
void showHelp(char* program_name)
{
std::cout << std::endl;
std::cout << "Usage: " << program_name << " sourcefile.pcd targetfile.pcd" << std::endl;
std::cout << "-h: Show this help." << std::endl;
} //按键触发
void keyboardEventOccurred (const pcl::visualization::KeyboardEvent& event,
void* nothing)
{
if (event.getKeySym () == "space" && event.keyDown ()) //空格按键触发
{
state++; //状态标志
state = state % ; //四种状态依次交替
next_flag = true; //允许变换到下一状态
}
} int main(int argc, char** argv)
{
// 显示帮助文档
if(pcl::console::find_switch (argc,argv,"-h") || pcl::console::find_switch(argc,argv,"--help"))
{
showHelp(argv[]);
return ;
}
//搜索.xml文件名
fstream outFile;
char buffer[];
//std::string dir = "C:\\Users\\xzd\\Documents\\KinectFile\\2014-09-07\\Select\\mengyue\\";
std::string dir = ".\\pcdFiles\\"; //在exe当前目录搜索文件夹(.\\...)
std::string source_filename, target_filename; //定义ICP融合源文件和目标文件
outFile.open("pcdFileList.txt",ios::in); //打开保存各帧pcd文件的文件列表txt Eigen::Matrix4f RT[]; //定义矩阵数组保存各帧之间的坐标系变换矩阵
Eigen::Matrix4f RT2First[]; //定义矩阵数组保存各帧到起始帧之间的坐标系变换矩阵
int index = ; //定义帧索引 //定义配准源点云和目标点云
pcl::PointCloud<pcl::PointXYZ>::Ptr source_cloud (new pcl::PointCloud<pcl::PointXYZ> ()); //源点云
pcl::PointCloud<pcl::PointXYZ>::Ptr target_cloud (new pcl::PointCloud<pcl::PointXYZ> ()); //目标点云
pcl::PointCloud<pcl::PointXYZ>::Ptr aligned_cloud(new pcl::PointCloud<pcl::PointXYZ> ()); //配准对齐后点云 //ICP 配准定义
pcl::IterativeClosestPoint<pcl::PointXYZ, pcl::PointXYZ> icp; //定义ICP类型实例icp
//设置ICP基本参数
icp.setMaxCorrespondenceDistance(); //设置对应点容忍最大距离
icp.setMaximumIterations(); //设置最大迭代次数
icp.setRANSACIterations(); //不进行RANSAC迭代 outFile.getline(buffer,,'\n'); //读取第一行,将该行数据存到buffer
target_filename = dir + buffer; //目标点云位置,第一帧点云为最初的目标点云
std::cout << target_filename << std::endl;
if(pcl::io::loadPCDFile(target_filename,*target_cloud) < ) //导入目标点云
{
std::cout << "Error loading point cloud " << target_filename << std::endl;
showHelp(argv[]);
return -;
} while(index < ) //加入计算的帧数
{
outFile.getline(buffer,,'\n'); //从第二行起,依次获取每行数据
source_filename = dir + buffer; //源点云位置,除第一帧点云外,其他帧依次作为其前一帧的ICP源点云
std::cout << source_filename << std::endl; // if(pcl::io::loadPCDFile(source_filename,*source_cloud) < ) //导入源点云
{
std::cout << "Error loading point cloud " << source_filename << std::endl;
showHelp(argv[]);
return -;
} icp.setInputCloud(source_cloud); //初始化源点云
icp.setInputTarget(target_cloud); //初始化目标点云 icp.align(*aligned_cloud); //配准后点云
std::cout << "has converged:" << icp.hasConverged() << " score: " <<
icp.getFitnessScore() << std::endl; //配准结果 RT[index] = icp.getFinalTransformation(); //将得到的ICP变换矩阵赋值给RT矩阵数组,
//由index索引,RT[0]表示第二帧点云向第一帧点云的变换矩阵 //计算所有点云向第一帧点云的变换,计算方法是相邻帧点云变换矩阵的累乘
if(index == ) //如果第一个变换
RT2First[index] = RT[index]; //第二帧先第一帧的变换
else
RT2First[index] = RT[index] * RT2First[index-]; //其他帧向第一帧的变换 index++; //转向下一变换 std::cout << icp.getFinalTransformation() << std::endl; //输出变换矩阵
*target_cloud = *source_cloud; //当前帧作为目标点云,下一次循环将使下一帧点云作为源点云
}
outFile.close(); //结束关闭pcd文件列表txt
std::cout << "Computer transform matrix completed" << std::endl; //提示变换矩阵计算完成信息 //测试各帧到第一帧的变换是否准确
target_filename = dir + "Depth0070.xml.pcd"; //目标帧:第一帧
source_filename = dir + "Depth0071.xml.pcd"; //源帧:可以是已计算的系列帧中任意一帧 if(pcl::io::loadPCDFile(source_filename,*source_cloud) < ) //导入源点云
{
std::cout << "Error loading point cloud " << source_filename << std::endl;
showHelp(argv[]);
return -;
} if(pcl::io::loadPCDFile(target_filename,*target_cloud) < ) //导入目标点云
{
std::cout << "Error loading point cloud " << target_filename << std::endl;
showHelp(argv[]);
return -;
} //执行变换
pcl::PointCloud<pcl::PointXYZ>::Ptr transformed_cloud (new pcl::PointCloud<pcl::PointXYZ> ()); //定义变换后点云
pcl::PointCloud<pcl::PointXYZ>& Transform_cloud = *transformed_cloud; //点云 pcl::transformPointCloud (*source_cloud, *transformed_cloud,RT2First[]); //执行变换
icp.setInputCloud(transformed_cloud); //初始化源点云
icp.setInputTarget(target_cloud); //初始化目标点云
//icp.align(*aligned_cloud); //执行融合,ICP pcl::visualization::PCLVisualizer viewer ("ICP transform"); //定义显示对象实例 int v1 (); //显示窗口分隔
int v2 ();
viewer.createViewPort(0.0, 0.0, 0.5, 1.0, v1); //窗口分隔位置 creatViewPort(x_min,y_min,x_max,y_max,int &viewport)
viewer.createViewPort(0.5, 0.0, 1.0, 1.0, v2); // Define R,G,B colors for the point cloud
pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> source_cloud_color_handler (source_cloud, , , );//White
// We add the point cloud to the viewer and pass the color handler
viewer.addPointCloud (source_cloud, source_cloud_color_handler, "source_cloud_v1", v1); pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> target_cloud_color_handler (target_cloud, , , ); // Red
viewer.addPointCloud (target_cloud, target_cloud_color_handler, "target_cloud_v1", v1); //viewer.addCoordinateSystem (1.0, "cloud", 0);
//viewer.setBackgroundColor(0.05, 0.05, 0.05, 0); // Setting background to a dark grey
viewer.setBackgroundColor(0.05, 0.05, 0.05, v1);
viewer.setBackgroundColor(0.05, 0.05, 0.05, v2);
viewer.setPointCloudRenderingProperties (pcl::visualization::PCL_VISUALIZER_POINT_SIZE, , "source_cloud_v1");
viewer.setPointCloudRenderingProperties (pcl::visualization::PCL_VISUALIZER_POINT_SIZE, , "target_cloud_v1");
//viewer.setPosition(800, 400); // Setting visualiser window position // Define R,G,B colors for the point cloud
pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> transformed_cloud_color_handler (transformed_cloud, , , ); //White
// We add the point cloud to the viewer and pass the color handler
viewer.addPointCloud (transformed_cloud, transformed_cloud_color_handler, "transformed_cloud_v2", v2);
viewer.addPointCloud (target_cloud, target_cloud_color_handler, "target_cloud_v2", v2);
viewer.setPointCloudRenderingProperties (pcl::visualization::PCL_VISUALIZER_POINT_SIZE, , "transformed_cloud_v2");
viewer.setPointCloudRenderingProperties (pcl::visualization::PCL_VISUALIZER_POINT_SIZE, , "target_cloud_v2"); viewer.registerKeyboardCallback (&keyboardEventOccurred, (void*) NULL); //触发回调函数,查询按键 while(!viewer.wasStopped())
{
viewer.spinOnce(); //窗口刷新
if(next_flag)
{
//std::cout << state << std::endl;
switch(state)
{
case : //状态1:只显示目标点云
viewer.removePointCloud("transformed_cloud_v2",v2);
std::cout << "Target Point Cloud" << std::endl;
break;
case : //状态2:将变换后点云加入到目标点云坐标系
viewer.addPointCloud (transformed_cloud, transformed_cloud_color_handler, "transformed_cloud_v2", v2);
viewer.setPointCloudRenderingProperties (pcl::visualization::PCL_VISUALIZER_POINT_SIZE, , "transformed_cloud_v2");
std::cout << "All Point Cloud" << std::endl;
break;
case : //状态3:移除目标点云,只显示变换后点云
viewer.removePointCloud("target_cloud_v2",v2);
std::cout << "Transformed Point Cloud" << std::endl;
break;
case : //状态0:全部显示
viewer.addPointCloud (target_cloud, target_cloud_color_handler, "target_cloud_v2", v2);
viewer.setPointCloudRenderingProperties (pcl::visualization::PCL_VISUALIZER_POINT_SIZE, , "target_cloud_v2");
std::cout << "All Point Cloud" << std::endl;
break;
default:
break;
}
next_flag = false; //禁止进行下一次变换
}
}
return ;
}
CMakeLists.txt
cmake_minimum_required(VERSION 2.6 FATAL_ERROR) project(Fusion_Project) find_package(PCL 1.6 REQUIRED) include_directories(${PCL_INCLUDE_DIRS})
link_directories(${PCL_LIBRARY_DIRS})
add_definitions(${PCL_DEFINITIONS}) add_executable (fusion fusion.cpp)
target_link_libraries (fusion ${PCL_LIBRARIES})
第二周02:Fusion ICP逐帧融合的更多相关文章
- 第二周:01 ICP迭代交互
本周主要任务01:利用PCL库函数,ICP融合两个角度的点云 任务时间:2014年9月8日-2014年9月14日 任务完成情况:可以使用键盘交互,显示每次ICP迭代结果 任务涉及基本方法: 1.PCL ...
- css3 实现逐帧动画
css3 实现逐帧动画 实现逐帧动画需要使用到的是Animation动画,该CSS3的Animation有八个属性:分别是如下:1: animation-name2: animation-durati ...
- 【Unity3D基础】让物体动起来②--UGUI鼠标点击逐帧移动
背景 上一篇通过鼠标移动的代码很简单,所以看的人也不多,但是还是要感谢“武装三藏”在博客园给出的评论和支持,希望他也能看到第二篇,其实可以很简单,而且是精灵自控制,关键是代码少是我喜欢的方式,也再次印 ...
- 《Java程序设计》第二周学习总结
20145224陈颢文<Java程序设计>第二周学习总结 教材学习内容总结 一.类型.变量与运算符 1.类型 整数: 可细分为为short整数(占2字节),int整数(占4字节),long ...
- animation中的steps()逐帧动画
在我们平时做宽高确定,需要背景图片切换的效果时,我如果用的是一张大的png图片.而且恰好是所有小图都是从左向右排列的,那么 我们只需测量出某一个小图距左侧有多少像素(x),然后我们banckgroun ...
- 利用css3-animation来制作逐帧动画
前言 趁着还没有元旦之前先码一篇文章,不然到时候估计又被各种虐了,所以趁现在还有力气先来一篇.今天来聊聊css3中的动画属性animation,对这个属性懵懂是在很早的时候有前辈用这个 animati ...
- window.requestAnimationFrame() ,做逐帧动画,你值得拥有
window.requestAnimationFrame() 方法告诉浏览器您希望执行动画,并请求浏览器调用指定的函数在下一次重绘之前更新动画.该方法使用一个回调函数作为参数,这个回调函数会在浏览器重 ...
- 20155306 2017-2018-1《信息安全系统设计》第二周课堂测试以及myod的实现
20155306 2017-2018-1<信息安全系统设计>第二周课堂测试以及myod的实现 第二周课堂测验: (注:前两项在课堂已提交,在此不做详解) 第一项: 每个.c一个文件,每个. ...
- 逐帧动画抖动、适配布局、SVG Sprites
笔者所在的前端团队主要从事移动端的H5页面开发,而团队使用的适配方案是: viewport units + rem.具体可以参见凹凸实验室的文章 – 利用视口单位实现适配布局 . 笔者目前(2017. ...
随机推荐
- ecshop 二次开发及模板标签
ecs_account_log // 用户账目日志表 ecs_activity // 活动表(代码,名称,开始,结束,描述) ecs_ad // 广告表(位置,类型,名称,链接,图片,开始,结 ...
- win7和centos双系统安装
几年之前为了安装xp和linux的双系统曾折腾了好多天,今天为了安装这个win7和centos双系统,也折腾了两天多,哦,我的天,安装个双系统,怎么这么麻烦呢? 没有来得及整理,先铺上草稿,供同志们参 ...
- C# chart控件绘制曲线
在.NET中以前经常用GDI去绘制,虽然效果也不错,自从.NET 4.0开始,专门为绘制图表而生的Chart控件出现了,有了它,就可以轻松的绘制你所需要的曲线图.柱状图什么的了. using Syst ...
- JAVA深复制(深克隆)与浅复制(浅克隆)
1.浅复制与深复制概念⑴浅复制(浅克隆)被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象.换言之,浅复制仅仅复制所考虑的对象,而不 复制它所引用的对象. 1. ...
- OpenGL超级宝典第5版&&glProvokingVertex
翻译:https://www.opengl.org/sdk/docs/man3/xhtml/glProvokingVertex.xml 方法原型:void glProvokingVertex(GLen ...
- 关于ShareSDK接入的各种问题,以及解决方案
随着社交网络的流行,游戏接入分享已经是必然.毕竟这是非常好的一种推广方式.ShareSDK是一个非常好的内分享提供商!但是接入后发生的各种问题,下面给大家提供几个本人遇到的问题,以及解决方法: 1)微 ...
- JAVA中的异常(异常处理流程、异常处理的缺陷)
异常处理流程 1)首先由try{...}catch(Exception e){ System.out.println(e); e.printStackTrace(); }finally{...}结构 ...
- UVa 307 - Sticks
Sticks [题目链接]:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category ...
- work_8
1.把程序编译通过, 跑起来. 读懂程序,在你觉得比较难懂的地方加上一些注释,这样大家就能比较容易地了解这些程序在干什么. 把正确的 playPrev(GoMove) 的方法给实现了. 如果大家不会下 ...
- linux@64 获取时间的性能评估
听人说gettimeofday 在64bit下有缓存,速度很快,测试下了,感觉不对啊.. #include <time.h> #include <sys/time.h> #in ...