本周主要任务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逐帧融合的更多相关文章

  1. 第二周:01 ICP迭代交互

    本周主要任务01:利用PCL库函数,ICP融合两个角度的点云 任务时间:2014年9月8日-2014年9月14日 任务完成情况:可以使用键盘交互,显示每次ICP迭代结果 任务涉及基本方法: 1.PCL ...

  2. css3 实现逐帧动画

    css3 实现逐帧动画 实现逐帧动画需要使用到的是Animation动画,该CSS3的Animation有八个属性:分别是如下:1: animation-name2: animation-durati ...

  3. 【Unity3D基础】让物体动起来②--UGUI鼠标点击逐帧移动

    背景 上一篇通过鼠标移动的代码很简单,所以看的人也不多,但是还是要感谢“武装三藏”在博客园给出的评论和支持,希望他也能看到第二篇,其实可以很简单,而且是精灵自控制,关键是代码少是我喜欢的方式,也再次印 ...

  4. 《Java程序设计》第二周学习总结

    20145224陈颢文<Java程序设计>第二周学习总结 教材学习内容总结 一.类型.变量与运算符 1.类型 整数: 可细分为为short整数(占2字节),int整数(占4字节),long ...

  5. animation中的steps()逐帧动画

    在我们平时做宽高确定,需要背景图片切换的效果时,我如果用的是一张大的png图片.而且恰好是所有小图都是从左向右排列的,那么 我们只需测量出某一个小图距左侧有多少像素(x),然后我们banckgroun ...

  6. 利用css3-animation来制作逐帧动画

    前言 趁着还没有元旦之前先码一篇文章,不然到时候估计又被各种虐了,所以趁现在还有力气先来一篇.今天来聊聊css3中的动画属性animation,对这个属性懵懂是在很早的时候有前辈用这个 animati ...

  7. window.requestAnimationFrame() ,做逐帧动画,你值得拥有

    window.requestAnimationFrame() 方法告诉浏览器您希望执行动画,并请求浏览器调用指定的函数在下一次重绘之前更新动画.该方法使用一个回调函数作为参数,这个回调函数会在浏览器重 ...

  8. 20155306 2017-2018-1《信息安全系统设计》第二周课堂测试以及myod的实现

    20155306 2017-2018-1<信息安全系统设计>第二周课堂测试以及myod的实现 第二周课堂测验: (注:前两项在课堂已提交,在此不做详解) 第一项: 每个.c一个文件,每个. ...

  9. 逐帧动画抖动、适配布局、SVG Sprites

    笔者所在的前端团队主要从事移动端的H5页面开发,而团队使用的适配方案是: viewport units + rem.具体可以参见凹凸实验室的文章 – 利用视口单位实现适配布局 . 笔者目前(2017. ...

随机推荐

  1. ArcMap自定义脚本工具制作

    原文 ArcMap自定义脚本工具制作 在制图的前期,一般需要做一些数据的整理,如图层合并.裁剪等工作.虽然在ArcMap中也有提供对应的工具,但使用起来需要点技巧.如批量裁剪,虽然可以实现,但出来的结 ...

  2. Devexpress GridControl中combobox级联显示 z

    http://minmin86121.blog.163.com/blog/static/4968115720143163533356/ 在 使用GridControl时,可能会有需求要求某2列显示co ...

  3. Apriori学习笔记

    Apriori算法是一种挖掘关联规则的频繁项集算法,是由Rakesh Agrawal和Ramakrishnan Srikant两位在1994年提出的布尔关联规则的频繁项集挖掘算法.算法的名字" ...

  4. Python 笔记 : 类和继承

    # -*- coding=  utf-8 -*- # 文件编码定义的语法规则是: coding[:=]/s*([-/w.]+) # 未指定编码将默认为 : ASCII # 同时要注意物理文件的编码也要 ...

  5. C#冒泡排序详解

    今天写一简单的冒泡排序,带有详细的中文注释,新手一定要看看! 因为这是找工作面试时经常 笔试 要考的题目. using System; using System.Collections.Generic ...

  6. 转】Maven学习总结(四)——Maven核心概念

    原博文出自于: http://www.cnblogs.com/xdp-gacl/p/4051819.html 感谢! 一.Maven坐标 1.1.什么是坐标? 在平面几何中坐标(x,y)可以标识平面中 ...

  7. Maven学习总结(一)——Maven入门

    原博文出自于:http://www.cnblogs.com/xdp-gacl/p/3498271.html 感谢! 一.Maven的基本概念 Maven(翻译为"专家"," ...

  8. Spark生态之Spark Core

  9. JAVA中“==”与equals()方法区别

    equals 方法是 java.lang.Object 类的方法 有两种用法说明: ()对于字符串变量来说,使用"=="和"equals()"方法比较字符串时, ...

  10. Spring入门(3)-Spring命名空间与Bean作用域

    Spring入门(3)-Spring命名空间与Bean作用域 这篇文章主要介绍Spring的命名空间和Bean作用域 0. 目录 Spring命名空间 Bean作用域 1. Spring命名空间 在前 ...