第二周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 seo修改建议
ECSHOP是一个非常优秀的商城程序,以丰富的模板.稳定开源.非常快的执行速度赢得广大网店主的青眯.可是新建站30多天,目前百度只收录了首页,而google收录正常.我检查了他的网站一切正常,没有任何 ...
- Android中GridView滚动到底部加载数据终极版
之前在项目中有一个需求是需要GridView控件,滚动到底部自动加载.但是呢GridView控件并不提供诸如ListView监听滚动到底部的onScrollListener方法,为了实现这样一个效果, ...
- Android功能模块化之生成验证码Bitmap
Android生成验证码Bitmap,主要使用Canvas绘制,实现的步骤如下: 1.生成验证码.主要采用java的随机函数生成序号,然后对应获取预设的Char数组的值,生成长度固定的验证码: 2.C ...
- 马上着手开发Mac应用程序
你是否想要开发 Mac 应用程序却又不知道从哪里入手?本路线图提供了 Mac 应用程序开发的绝佳起点,即使你已经是一个 iOS 开发专家,本路线图对你依然适用.Apple让开发应用程序和提交应用程序到 ...
- 关于CCSprite改变box2d刚体位置以及角度。
同事今天在讨论一个事情,box2d中,body不可以直接设置位置,这样是不合理的,因为在物理的世界,你去左右它的物理检测.它就没有存在的必要了.但是,有人就想直接用box2d的碰撞.不用物理模拟.怎么 ...
- wuzhicms水印的设置
- bzoj 1109 [POI2007]堆积木Klo(LIS)
[题意] n个数的序列,删除一个数后序列左移,求最后满足i==a[i]的最大个数. [思路] 设最终得到a[i]==i的序列为s,则s应满足: i<j,a[i]<a[j],i-a[i]&l ...
- append some buttons to the standard datagrid pager bar
<script type="text/javascript"> $(function(){ var pager = $('#dg').datagrid('getP ...
- 07 java main方法
1.问题:Java main方法为什么是 public static void main(String[] args)??? 序号 场景 编译 运行 解释 1 public修改为private pr ...
- 【转】你真的了解iOS代理设计模式吗?
转自:http://www.cocoachina.com/ios/20160317/15696.html 在项目中我们经常会用到代理的设计模式,这是iOS中一种消息传递的方式,也可以通过这种方式来传递 ...