连接两个点云中的字段或数据形成新点云以及Opennni Grabber初识
生活随笔
收集整理的這篇文章主要介紹了
连接两个点云中的字段或数据形成新点云以及Opennni Grabber初识
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
(1)學(xué)習(xí)如何連接兩個不同點云為一個點云,進行操作前要確保兩個數(shù)據(jù)集中字段的類型相同和維度相等,同時了解如何連接兩個不同點云的字段(例如顏色 法線)這種操作的強制約束條件是兩個數(shù)據(jù)集中點的數(shù)目必須一樣,例如:點云A是N個點XYZ點,點云B是N個點的RGB點,則連接兩個字段形成點云C是N個點xyzrgb類型
新建文件concatenate_clouds.cpp? CMakeLists.txt
concatenate_clouds.cpp :
?
#include <iostream> #include <pcl/io/pcd_io.h> //io模塊 #include <pcl/point_types.h> //數(shù)據(jù)類型intmain (int argc, char** argv) {if (argc != 2) //提示如果執(zhí)行可執(zhí)行文件輸入兩個參數(shù) -f 或者-p {std::cerr << "please specify command line arg '-f' or '-p'" << std::endl;exit(0);}//申明三個pcl::PointXYZ點云數(shù)據(jù)類型,分別為cloud_a, cloud_b, cloud_cpcl::PointCloud<pcl::PointXYZ> cloud_a, cloud_b, cloud_c;//存儲進行連接時需要的Normal點云,Normal (float n_x, float n_y, float n_z)pcl::PointCloud<pcl::Normal> n_cloud_b;//存儲連接XYZ與normal后的點云pcl::PointCloud<pcl::PointNormal> p_n_cloud_c;// 創(chuàng)建點云數(shù)據(jù)//設(shè)置cloud_a的個數(shù)為5cloud_a.width = 5;cloud_a.height = cloud_b.height = n_cloud_b.height = 1; //設(shè)置都為無序點云cloud_a.points.resize (cloud_a.width * cloud_a.height); //總數(shù)if (strcmp(argv[1], "-p") == 0) //判斷是否為連接a+b=c(點云連接) {cloud_b.width = 3;cloud_b.points.resize (cloud_b.width * cloud_b.height);}else{n_cloud_b.width = 5; //如果是連接XYZ與normal則生成5個法線(字段間連接)n_cloud_b.points.resize (n_cloud_b.width * n_cloud_b.height);} //以下循環(huán)生成無序點云填充上面定義的兩種類型的點云數(shù)據(jù)for (size_t i = 0; i < cloud_a.points.size (); ++i){ //cloud_a產(chǎn)生三個點(每個點都有X Y Z 三個隨機填充的值)cloud_a.points[i].x = 1024 * rand () / (RAND_MAX + 1.0f);cloud_a.points[i].y = 1024 * rand () / (RAND_MAX + 1.0f);cloud_a.points[i].z = 1024 * rand () / (RAND_MAX + 1.0f);}if (strcmp(argv[1], "-p") == 0)for (size_t i = 0; i < cloud_b.points.size (); ++i){ //如果連接a+b=c,則cloud_b用三個點作為xyz的數(shù)據(jù)cloud_b.points[i].x = 1024 * rand () / (RAND_MAX + 1.0f);cloud_b.points[i].y = 1024 * rand () / (RAND_MAX + 1.0f);cloud_b.points[i].z = 1024 * rand () / (RAND_MAX + 1.0f);}elsefor (size_t i = 0; i < n_cloud_b.points.size (); ++i){ //如果連接xyz+normal=xyznormal則n_cloud_b用5個點作為normal數(shù)據(jù)n_cloud_b.points[i].normal[0] = 1024 * rand () / (RAND_MAX + 1.0f);n_cloud_b.points[i].normal[1] = 1024 * rand () / (RAND_MAX + 1.0f);n_cloud_b.points[i].normal[2] = 1024 * rand () / (RAND_MAX + 1.0f);} /******************************************************************* 定義了連接點云會用到的5個點云對象:3個輸入(cloud_a cloud_b 和n_cloud_b) 兩個輸出(cloud_c n_cloud_c)然后就是為兩個輸入點云cloud_a和 cloud_b或者cloud_a 和n_cloud_b填充數(shù)據(jù) ********************************************************************/ //輸出Cloud Astd::cerr << "Cloud A: " << std::endl;for (size_t i = 0; i < cloud_a.points.size (); ++i)std::cerr << " " << cloud_a.points[i].x << " " << cloud_a.points[i].y << " " << cloud_a.points[i].z << std::endl; //輸出Cloud Bstd::cerr << "Cloud B: " << std::endl;if (strcmp(argv[1], "-p") == 0)for (size_t i = 0; i < cloud_b.points.size (); ++i)std::cerr << " " << cloud_b.points[i].x << " " << cloud_b.points[i].y << " " << cloud_b.points[i].z << std::endl;else//輸出n_Cloud_bfor (size_t i = 0; i < n_cloud_b.points.size (); ++i)std::cerr << " " << n_cloud_b.points[i].normal[0] << " " << n_cloud_b.points[i].normal[1] << " " << n_cloud_b.points[i].normal[2] << std::endl;// Copy the point cloud dataif (strcmp(argv[1], "-p") == 0){cloud_c = cloud_a;cloud_c += cloud_b;//把cloud_a和cloud_b連接一起創(chuàng)建cloud_c 后輸出std::cerr << "Cloud C: " << std::endl;for (size_t i = 0; i < cloud_c.points.size (); ++i)std::cerr << " " << cloud_c.points[i].x << " " << cloud_c.points[i].y << " " << cloud_c.points[i].z << " " << std::endl;}else{ //連接字段 把cloud_a和 n_cloud_b字段連接 一起創(chuàng)建 p_n_cloud_c) pcl::concatenateFields (cloud_a, n_cloud_b, p_n_cloud_c);std::cerr << "Cloud C: " << std::endl;for (size_t i = 0; i < p_n_cloud_c.points.size (); ++i)std::cerr << " " <<p_n_cloud_c.points[i].x << " " << p_n_cloud_c.points[i].y << " " << p_n_cloud_c.points[i].z << " " <<p_n_cloud_c.points[i].normal[0] << " " << p_n_cloud_c.points[i].normal[1] << " " << p_n_cloud_c.points[i].normal[2] << std::endl;}return (0); }
?
CMakeLists.txt:
cmake_minimum_required(VERSION 2.8 FATAL_ERROR)project(ch2_2)find_package(PCL 1.2 REQUIRED)include_directories(${PCL_INCLUDE_DIRS}) link_directories(${PCL_LIBRARY_DIRS}) add_definitions(${PCL_DEFINITIONS})add_executable (concatenate_clouds concatenate_clouds.cpp) target_link_libraries (concatenate_clouds ${PCL_LIBRARIES})
編譯執(zhí)行后的結(jié)果,仔細研究看一下就可以看出點云連接和字段間連接的區(qū)別,字段間連接是在行的基礎(chǔ)后連接,而點云連接是在列的下方連接,最重要的就是要考慮維度問題,同時每個點云都有XYZ三個數(shù)據(jù)值
?
字段間連接:
?點云連接
(2)對于獲取傳感器的深度信息可以使用OpenNI Grabber類,(其中涉及到如何安裝傳感器的驅(qū)動等問題,比如我使用的是kinect 1.0 可能會遇到一些安裝問題,但是網(wǎng)上還是有很多的解決辦法的,在這里不對于敘述)
新建文件openni_grabber.cpp
#include <pcl/point_cloud.h> //點云類定義頭文件 #include <pcl/point_types.h> //點 類型定義頭文件 #include <pcl/io/openni_grabber.h> //OpenNI數(shù)據(jù)流獲取頭文件 #include <pcl/common/time.h> //時間頭文件//類SimpleOpenNIProcessor 的回調(diào)函數(shù),作為在獲取數(shù)據(jù)時,對數(shù)據(jù)進行處理的回調(diào)函數(shù)的封裝,在本例中并沒有什么處理,只是實時的在標準輸出設(shè)備打印處信息。 class SimpleOpenNIProcessor { public:void cloud_cb_ (const pcl::PointCloud<pcl::PointXYZRGBA>::ConstPtr &cloud){static unsigned count = 0;static double last = pcl::getTime (); //獲取當前時間if (++count == 30) //每30ms一次輸出 {double now = pcl::getTime ();// >>右移std::cout << "distance of center pixel :" << cloud->points [(cloud->width >> 1) * (cloud->height + 1)].z << " mm. Average framerate: " << double(count)/double(now - last) << " Hz" << std::endl;count = 0;last = now;}}void run (){pcl::Grabber* interface = new pcl::OpenNIGrabber(); //創(chuàng)建OpenNI采集對象// 定義回調(diào)函數(shù)boost::function<void (const pcl::PointCloud<pcl::PointXYZRGBA>::ConstPtr&)> f =boost::bind (&SimpleOpenNIProcessor::cloud_cb_, this, _1);boost::signals2::connection c = interface->registerCallback (f);//注冊回調(diào)函數(shù)interface->start (); //開始接受點云數(shù)據(jù)//直到用戶按下Ctrl -cwhile (true)boost::this_thread::sleep (boost::posix_time::seconds (1));// 停止采集interface->stop ();} };int main () {SimpleOpenNIProcessor v;v.run ();return (0); }
CMakeLists.txt
cmake_minimum_required(VERSION 2.8 FATAL_ERROR)project(openni_grabber)find_package(PCL 1.2 REQUIRED)include_directories(${PCL_INCLUDE_DIRS}) link_directories(${PCL_LIBRARY_DIRS}) add_definitions(${PCL_DEFINITIONS})add_executable (openni_grabber openni_grabber.cpp) target_link_libraries (openni_grabber ${PCL_LIBRARIES})
編譯后執(zhí)行可執(zhí)行文件的結(jié)果如下
微信公眾號號可掃描二維碼一起共同學(xué)習(xí)交流
未完待續(xù)*******************************************8
總結(jié)
以上是生活随笔為你收集整理的连接两个点云中的字段或数据形成新点云以及Opennni Grabber初识的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 从PCD文件写入和读取点云数据
- 下一篇: kd-tree理论以及在PCL 中的代码