第二周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. ...
随机推荐
- 你所不知道的 URL
0.说明 第一幕 产品:大叔有用户反映账户不能绑定公众号.大叔:啊咧咧?怎么可能,我看看?大叔:恩?这也没问题啊,魏虾米.大叔:还是没问题啊,挖叉类.大叔:T T,话说产品姐姐是不是Java提供接口的 ...
- 定义页面的Dispose方法:[before]unload事件启示录
前言 最近实施的同事报障,说用户审批流程后直接关闭浏览器,操作十余次后系统就报用户会话数超过上限,咨询4A同事后得知登陆后需要显式调用登出API才能清理4A端,否则必然会超出会话上限. 即使在页面上增 ...
- mysql-5.6.15_winX64在win764位系统下的安装操作步骤总结
mysql 版权声明:本文为博主原创文章,未经博主允许不得转载. 自从换了新电脑win764位,支持的内存从原来的3G(2G机身+1G内存条)变到了现在的8G(机身4G+4G内存条),机子的速度是 ...
- codeforces 680E Bear and Square Grid 巧妙暴力
这个题是个想法题 先预处理连通块,然后需要用到一种巧妙暴力,即0变1,1变0,一列列添加删除 复杂度O(n^3) #include <cstdio> #include <iostre ...
- LoadRunner检查点实战
码农博客 即将到期,现将博客中部分文章转载到博客园.转载时略有删减. 一.为什么要使用检查点 为什么要使用检查点,那就要说明一下LR如何判断脚本是否执行成功. LR判断脚本是否执行成功是根据服务器返回 ...
- "_ITERATOR_DEBUG_LEVEL"的不匹配项: 值"0"不匹配值"2"
error: 1>vtkCommon.lib(vtkDebugLeaksManager.obj) : error LNK2038: 检测到“_ITERATOR_DEBUG_LEVEL”的不匹配项 ...
- VS2010下 LibVLC开发环境搭建
LibVLC环境的搭建 最近又 LIBVLC 做一个视频播放器,封装成ActiveX控件,之前做过一个基于OpenCV的播放器(只解码视频,音频不用,OpenCV也没有解码音频的功能). 到目前位置 ...
- 【跟我一起学Python吧】python with statement 进阶理解
由于之前有一个项目老是要打开文件,然后用pickle.load(file),再处理...最后要关闭文件,所以觉得有点繁琐,代码也不简洁.所以向python with statement寻求解决方法.以 ...
- C++容器学习
以前自学C++的时候就没怎么看容器,一直以来也没怎么编过C++程序,现在想用C++写点东西,突感容器类型有些生疏,故做此笔记.(参考<C++ primer> 容器:容纳特定类型对象的集合. ...
- iOS完结篇
从去年自己陆陆续续接触iOS开发,几个月过去了,对于苹果的体验,流程,以及规范都有了一定的认 识,还会定期关注iOS的发展. 即将要做win10系统了,为了纪念把自己的虚拟机截图留念吧.也希望微软能在 ...