注:本文是在学习了高翔博士的相关博客(http://www.cnblogs.com/gaoxiang12/p/4652478.html)后写成的,纯粹作为一个学习笔记
1.在上一节即http://blog.csdn.net/zhuquan945/article/details/52788278中讲到的 代码根目录/src/ 文件夹中,即在/slam/src中新建一个名字为generatePointCloud.cpp的文件:
zhuquan@zhuquan-HP-Z230-Tower-Workstation:~$ cd ~/slam
zhuquan@zhuquan-HP-Z230-Tower-Workstation:~/slam$ cd src
zhuquan@zhuquan-HP-Z230-Tower-Workstation:~/slam/src$ touch generatePointCloud.cpp
并在generatePointCloud.cpp中写入如下内容:
// C++ 标准库
#include #include using namespace std;
// OpenCV 库
#include #include // PCL 库
#include #include // 定义点云类型
typedef pcl::PointXYZRGBA PointT;
typedef pcl::PointCloudPointCloud;
// 相机内参
const double camera_factor = 1000;
const double camera_cx = 325.5;
const double camera_cy = 253.5;
const double camera_fx = 518.0;
const double camera_fy = 519.0;
// 主函数
int main( int argc, char** argv )
{
// 读取./data/rgb.png和./data/depth.png,并转化为点云
// 图像矩阵
cv::Mat rgb, depth;
// 使用cv::imread()来读取图像
// API: http://docs.opencv.org/modules/highgui/doc/reading_and_writing_images_and_video.html?highlight=imread#cv2.imread
rgb = cv::imread( "./data/162025180951762.png" );
// rgb 图像是8UC3的彩色图像
// depth 是16UC1的单通道图像,注意flags设置-1,表示读取原始数据不做任何修改
depth = cv::imread( "./data/162025372828732.png", -1 );
// 点云变量
// 使用智能指针,创建一个空点云。这种指针用完会自动释放。
PointCloud::Ptr cloud ( new PointCloud );
// 遍历深度图
for (int m = 0; m < depth.rows; m++)
for (int n=0; n < depth.cols; n++)
{
// 获取深度图中(m,n)处的值
ushort d = depth.ptr(m)[n];
// d 可能没有值,若如此,跳过此点
if (d == 0)
continue;
// d 存在值,则向点云增加一个点
PointT p;
// 计算这个点的空间坐标
p.z = double(d) / camera_factor;
p.x = (n - camera_cx) * p.z / camera_fx;
p.y = (m - camera_cy) * p.z / camera_fy;
// 从rgb图像中获取它的颜色
// rgb是三通道的BGR格式图,所以按下面的顺序获取颜色
p.b = rgb.ptr(m)[n*3];
p.g = rgb.ptr(m)[n*3+1];
p.r = rgb.ptr(m)[n*3+2];
// 把p加入到点云中
cloud->points.push_back( p );
}
// 设置并保存点云
cloud->height = 1;
cloud->width = cloud->points.size();
coutis_dense = false;
pcl::io::savePCDFile( "./data/pointcloud.pcd", *cloud );
// 清除数据并退出
cloud->points.clear();
cout< return 0;
}
程序运行时需要数据,故将162025180951762.png
以及
162025372828732.png
存放在源代码根目录下即存放在/slam/data中(如果没有的新建一个)。
然后将/slam/src/中的main.cpp删除
2.为了告诉编译器我们需要编译这个程序,故需要在/slam/src/中建立一个名字为CMakeLists.txt文件,并在CMakeLists.txt中写入如下内容:
# 增加PCL库的依赖
FIND_PACKAGE( PCL REQUIRED COMPONENTS common io )
# 增加opencv的依赖
FIND_PACKAGE( OpenCV REQUIRED )
# 添加头文件和库文件
ADD_DEFINITIONS( ${PCL_DEFINITIONS} )
INCLUDE_DIRECTORIES( ${PCL_INCLUDE_DIRS} )
LINK_LIBRARIES( ${PCL_LIBRARY_DIRS} )
ADD_EXECUTABLE( generate_pointcloud generatePointCloud.cpp )
TARGET_LINK_LIBRARIES( generate_pointcloud ${OpenCV_LIBS}
${PCL_LIBRARIES} )
3.编译新的工程
zhuquan@zhuquan-HP-Z230-Tower-Workstation:~/slam$ mkdir build
zhuquan@zhuquan-HP-Z230-Tower-Workstation:~/slam$ cd build
zhuquan@zhuquan-HP-Z230-Tower-Workstation:~/slam/build$ cmake ..
结果如下:
-- The C compiler identification is GNU 5.4.0
-- The CXX compiler identification is GNU 5.4.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Checking for module 'eigen3'
-- Found eigen3, version 3.2.92
-- Found eigen: /usr/include/eigen3
-- Looking for pthread.h
-- Looking for pthread.h - found
-- Looking for pthread_create
-- Looking for pthread_create - not found
-- Looking for pthread_create in pthreads
-- Looking for pthread_create in pthreads - not found
-- Looking for pthread_create in pthread
-- Looking for pthread_create in pthread - found
-- Found Threads: TRUE
-- Boost version: 1.58.0
-- Found the following Boost libraries:
-- system
-- filesystem
-- thread
-- date_time
-- iostreams
-- serialization
-- chrono
-- atomic
-- regex
-- Checking for module 'libopenni'
-- No package 'libopenni' found
-- Could NOT find openni (missing: OPENNI_LIBRARY OPENNI_INCLUDE_DIRS)
** WARNING ** io features related to openni will be disabled
-- Checking for module 'libopenni2'
-- No package 'libopenni2' found
-- Could NOT find OpenNI2 (missing: OPENNI2_LIBRARY OPENNI2_INCLUDE_DIRS)
** WARNING ** io features related to openni2 will be disabled
-- Could NOT find ensenso (missing: ENSENSO_LIBRARY ENSENSO_INCLUDE_DIR)
** WARNING ** io features related to ensenso will be disabled
-- Could NOT find DAVIDSDK (missing: DAVIDSDK_LIBRARY DAVIDSDK_INCLUDE_DIR)
** WARNING ** io features related to davidSDK will be disabled
-- Could NOT find DSSDK (missing: _DSSDK_LIBRARIES)
** WARNING ** io features related to dssdk will be disabled
** WARNING ** io features related to pcap will be disabled
** WARNING ** io features related to png will be disabled
-- Found libusb-1.0: /usr/include
** WARNING ** io features related to libusb-1.0 will be disabled
-- looking for PCL_COMMON
-- Found PCL_COMMON: /usr/local/lib/libpcl_common.so
-- looking for PCL_OCTREE
-- Found PCL_OCTREE: /usr/local/lib/libpcl_octree.so
-- looking for PCL_IO
-- Found PCL_IO: /usr/local/lib/libpcl_io.so
-- Found PCL: /usr/lib/x86_64-linux-gnu/libboost_system.so;/usr/lib/x86_64-linux-gnu/libboost_filesystem.so;/usr/lib/x86_64-linux-gnu/libboost_thread.so;/usr/lib/x86_64-linux-gnu/libboost_date_time.so;/usr/lib/x86_64-linux-gnu/libboost_iostreams.so;/usr/lib/x86_64-linux-gnu/libboost_serialization.so;/usr/lib/x86_64-linux-gnu/libboost_chrono.so;/usr/lib/x86_64-linux-gnu/libboost_atomic.so;/usr/lib/x86_64-linux-gnu/libboost_regex.so;/usr/lib/x86_64-linux-gnu/libpthread.so;optimized;/usr/local/lib/libpcl_common.so;debug;/usr/local/lib/libpcl_common.so;optimized;/usr/local/lib/libpcl_octree.so;debug;/usr/local/lib/libpcl_octree.so;vtkCommon;vtkFiltering;vtkImaging;vtkGraphics;vtkGenericFiltering;vtkIO;vtkRendering;vtkVolumeRendering;vtkHybrid;vtkWidgets;vtkParallel;vtkInfovis;vtkGeovis;vtkViews;vtkCharts;optimized;/usr/local/lib/libpcl_io.so;debug;/usr/local/lib/libpcl_io.so;/usr/lib/x86_64-linux-gnu/libboost_system.so;/usr/lib/x86_64-linux-gnu/libboost_filesystem.so;/usr/lib/x86_64-linux-gnu/libboost_thread.so;/usr/lib/x86_64-linux-gnu/libboost_date_time.so;/usr/lib/x86_64-linux-gnu/libboost_iostreams.so;/usr/lib/x86_64-linux-gnu/libboost_serialization.so;/usr/lib/x86_64-linux-gnu/libboost_chrono.so;/usr/lib/x86_64-linux-gnu/libboost_atomic.so;/usr/lib/x86_64-linux-gnu/libboost_regex.so;/usr/lib/x86_64-linux-gnu/libpthread.so;vtkCommon;vtkFiltering;vtkImaging;vtkGraphics;vtkGenericFiltering;vtkIO;vtkRendering;vtkVolumeRendering;vtkHybrid;vtkWidgets;vtkParallel;vtkInfovis;vtkGeovis;vtkViews;vtkCharts
-- Configuring done
WARNING: Target "generate_pointcloud" requests linking to directory "/usr/local/lib". Targets may link only to libraries. CMake is dropping the item.
-- Generating done
-- Build files have been written to: /home/zhuquan/slam/build
zhuquan@zhuquan-HP-Z230-Tower-Workstation:~/slam/build$ make
Scanning dependencies of target generate_pointcloud
[ 50%] Building CXX object src/CMakeFiles/generate_pointcloud.dir/generatePointCloud.cpp.o
[100%] Linking CXX executable ../../bin/generate_pointcloud
[100%] Built target generate_pointcloud
如果编译通过的话,就会在/slam/bin/中生成一个名为generate_pointcloud的可执行的二进制文件。
这时候可以执行这个程序:
zhuquan@zhuquan-HP-Z230-Tower-Workstation:~/slam/build$ cd ..
zhuquan@zhuquan-HP-Z230-Tower-Workstation:~/slam$ bin/generate_pointcloud
在终端显示结果如下:
point cloud size = 204186
Point cloud saved.
此时就可以在/slam/data/中生成一个名字为pointcloud.pcd的点云文件了。
此时如果安装了pcl,就可以通过
zhuquan@zhuquan-HP-Z230-Tower-Workstation:~/slam$ pcl_viewer data/pointcloud.pcd
查看生成的点云文件是个什么样子了。
终端结果显示为:
The viewer window provides interactive commands; for help, press 'h' or 'H' from within the window.
> Loading data/pointcloud.pcd [done, 1235 ms :204186 points]
Available dimensions: x y z rgba
在屏幕上就会弹出一个PCD viewer: