首先貼一下大佬的github鏈接:https://github.com/williamhyin/SFND_Lidar_Obstacle_Detection
知乎專欄:https://www.zhihu.com/people/william.hyin
CSDN博客:https://blog.csdn.net/williamhyin/article/details/105159842
先呈現一個完整的視頻流結果:
靜置畫面截圖:
開始一步步分析這個代碼:
第一步:首先我們需要流式載入激光點雲數據(以下是要讀入的數據)。
流式載入激光點雲數據(疑問:每兩個pcd文件之間是不是在幀上本來就是相連的,就是一幀一幀?如果不是那麼如果多個pcd文件兩兩之間在視角方位或者時間上不存在連續性可以形成視頻嗎?)
原始函數聲明在processPointCloud.h
原始函數定義在processPointCloud.cpp
函數調用在environment.cpp中(main函數中)
這裏只是捋一下代碼每一步在哪裏在做什麼的思路具體代碼註釋見下上傳的完整代碼版本。
本部分涉及到的知識:(1)模板:http://c.biancheng.net/view/2317.html
(2)Boost 智能指針。(也就是說 用了智能指針 你就不用擔心 什麼釋放內存的問題了)
boost::shared_ptr 這句一般加在下圖箭頭前面其中shared_ptr 主要功能是,管理動態創建的對象的銷燬。他的基本原理是記錄對象被引用的次數,當引用次數爲0的時候,也就是最後一個指向某對象的指針析構的時候,共享指針的析構函數就會把指向的內存區域釋放掉。
上圖使用new給指針指向的對象開闢一個空間,new後邊的pcl::PointCloud<PointT>是指名對象的類型,並返回一個地址。
講解鏈接:https://www.jianshu.com/p/f9eea3610637
http://blog.sina.com.cn/s/blog_1705e3fc10102xe28.html
https://blog.csdn.net/aishuirenjia/article/details/91986961
一般使用 ptr 定義 cloud 就是調用了boost庫裏面的共享指針,
(3)PCL的Ptr與非Ptr類型(點雲對象的兩種定義方式pcl::PointCloud::Ptr和pcl::PointCloud是可以相互轉換的)
(2.1)創建與訪問:
第一種,是一種vector的賦值方式,將point數據push_back到pcl::PointXYZ類型的模板中。
pcl::PointCloud<pcl::PointXYZ> pointCloud;
pcl::PointXYZ point;
point.x = 2.0f - y;
point.y = y;
point.z = z;
pointCloud.points.push_back(point);
第二種,指針型類模板,採用“->points[i]”方式賦值。
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZ>);
for (int i = 0; i < cloud->points.size (); ++i)
{
cloud->points[i].x = 1024 * rand () / (RAND_MAX + 1.0f);
cloud->points[i].y = 1024 * rand () / (RAND_MAX + 1.0f);
cloud->points[i].z = 1024 * rand () / (RAND_MAX + 1.0f);
}
(2.2) pcl::PointCloud::Ptr和pcl::PointCloud可以相互轉換
pcl::PointCloud<pcl::PointXYZ>::Ptr cloudPtr(new pcl::PointCloud<pcl::PointXYZ>);
pcl::PointCloud<pcl::PointXYZ> cloud;
cloud = *cloudPtr;//由Ptr轉變爲另一種類型
cloudPtr = cloud.makeShared();//轉變爲Ptr類型
(2.3)pcl::PointCloud::Ptr和pcl::PointCloud兩種對象,在操作是會有所不同
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
pcl::io::loadPCDFile("F:\\PCL\\2.pcd",*cloud) == -1)
pcl::PointCloud<pcl::PointXYZ> cloud;
pcl::io::loadPCDFile("F:\\PCL\\2.pcd",cloud) == -1)
PS: kdtree和octree類中的setInputCloud()函數只支持Ptr類型,如果點雲對象不是Ptr類型,需要進行類型轉換。
(4)boost文件目錄操作:https://www.cnblogs.com/milanleon/p/10756869.html
使用到的容器vector知識:
//通過存儲元素類型相同的其它 vector 容器,也可以創建新的 vector 容器
std::vector<char>value1(5, 'c');
std::vector<char>value2(value1);//value2 容器中也具有 5 個字符 'c'
....省略代碼
//在此基礎上,如果不想複製其它容器中所有的元素,可以用一對指針或者迭代器來指定初始值的範圍,例如:
int array[]={1,2,3};
std::vector<int>values(array, array+2);//values 將保存{1,2}
std::vector<int>value1{1,2,3,4,5};
std::vector<int>value2(std::begin(value1),std::begin(value1)+3);//value2保存{1,2,3}