连接两个点云中的字段或数据形成新点云以及Opennni Grabber初识
生活随笔
收集整理的這篇文章主要介紹了
连接两个点云中的字段或数据形成新点云以及Opennni Grabber初识
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
(1)學習如何連接兩個不同點云為一個點云,進行操作前要確保兩個數據集中字段的類型相同和維度相等,同時了解如何連接兩個不同點云的字段(例如顏色 法線)這種操作的強制約束條件是兩個數據集中點的數目必須一樣,例如:點云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> //數據類型intmain (int argc, char** argv) {if (argc != 2) //提示如果執行可執行文件輸入兩個參數 -f 或者-p {std::cerr << "please specify command line arg '-f' or '-p'" << std::endl;exit(0);}//申明三個pcl::PointXYZ點云數據類型,分別為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;// 創建點云數據//設置cloud_a的個數為5cloud_a.width = 5;cloud_a.height = cloud_b.height = n_cloud_b.height = 1; //設置都為無序點云cloud_a.points.resize (cloud_a.width * cloud_a.height); //總數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);} //以下循環生成無序點云填充上面定義的兩種類型的點云數據for (size_t i = 0; i < cloud_a.points.size (); ++i){ //cloud_a產生三個點(每個點都有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的數據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數據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填充數據 ********************************************************************/ //輸出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連接一起創建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字段連接 一起創建 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})
編譯執行后的結果,仔細研究看一下就可以看出點云連接和字段間連接的區別,字段間連接是在行的基礎后連接,而點云連接是在列的下方連接,最重要的就是要考慮維度問題,同時每個點云都有XYZ三個數據值
?
字段間連接:
?點云連接
(2)對于獲取傳感器的深度信息可以使用OpenNI Grabber類,(其中涉及到如何安裝傳感器的驅動等問題,比如我使用的是kinect 1.0 可能會遇到一些安裝問題,但是網上還是有很多的解決辦法的,在這里不對于敘述)
新建文件openni_grabber.cpp
#include <pcl/point_cloud.h> //點云類定義頭文件 #include <pcl/point_types.h> //點 類型定義頭文件 #include <pcl/io/openni_grabber.h> //OpenNI數據流獲取頭文件 #include <pcl/common/time.h> //時間頭文件//類SimpleOpenNIProcessor 的回調函數,作為在獲取數據時,對數據進行處理的回調函數的封裝,在本例中并沒有什么處理,只是實時的在標準輸出設備打印處信息。 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(); //創建OpenNI采集對象// 定義回調函數boost::function<void (const pcl::PointCloud<pcl::PointXYZRGBA>::ConstPtr&)> f =boost::bind (&SimpleOpenNIProcessor::cloud_cb_, this, _1);boost::signals2::connection c = interface->registerCallback (f);//注冊回調函數interface->start (); //開始接受點云數據//直到用戶按下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})
編譯后執行可執行文件的結果如下
微信公眾號號可掃描二維碼一起共同學習交流
未完待續*******************************************8
總結
以上是生活随笔為你收集整理的连接两个点云中的字段或数据形成新点云以及Opennni Grabber初识的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 从PCD文件写入和读取点云数据
- 下一篇: kd-tree理论以及在PCL 中的代码