激光雷達(dá)作為自動(dòng)駕駛最常用的傳感器,經(jīng)常需要使用激光雷達(dá)來(lái)做建圖、定位和感知等任務(wù)。
而這時(shí)候使用降低點(diǎn)云規(guī)模的預(yù)處理方法,可以能夠去除無(wú)關(guān)區(qū)域的點(diǎn)以及降低點(diǎn)云規(guī)模。并能夠給后續(xù)的PCL點(diǎn)云分割帶來(lái)有效的收益。
點(diǎn)云預(yù)處理
1.1 指定區(qū)域獲取點(diǎn)云
在實(shí)際使用中,我們可以看出,雖然點(diǎn)云的分布范圍較廣,但大部分的點(diǎn)都集中的中間區(qū)域,距離越遠(yuǎn)點(diǎn)云越稀疏,相對(duì)的信息量也越小。
此外還能明顯看到一些離群點(diǎn),因此我們可以篩選掉一些較遠(yuǎn)的點(diǎn),只保留我們感興趣范圍內(nèi)的點(diǎn)。以下為保留 x 在 30m,y 在 15m,z 在 2m 范圍內(nèi)的點(diǎn)的效果:
template < class PointType >void removePointsOutsideRegion(boost::shared_ptr< pcl::PointCloud< PointType > >& src_cloud_ptr, boost::shared_ptr< pcl::PointCloud< PointType > >& dst_cloud_ptr, const std::pair< double, double >& x_range, const std::pair< double, double >& y_range, const std::pair< double, double >& z_range) { int num_points = src_cloud_ptr- >points.size(); boost::shared_ptr< pcl::PointCloud< PointType > > cloud_ptr(new pcl::PointCloud< PointType >()); cloud_ptr- >points.reserve(num_points); for (const auto& pt : src_cloud_ptr- >points) { bool inside = (pt.x >= x_range.first && pt.x < = x_range.second && pt.y >= y_range.first && pt.y < = y_range.second && pt.z >= z_range.first && pt.z < = z_range.second); if (inside) { cloud_ptr- >points.push_back(pt); } } dst_cloud_ptr = cloud_ptr;} // 或者使用CropBox來(lái)實(shí)現(xiàn)去除給定區(qū)域外的點(diǎn) pcl::CropBox< pcl::PointXYZ > box_filter; box_filter.setInputCloud(cloud_ptr); box_filter.setMin(Eigen::Vector4f(keep_x_range.first, keep_y_range.first, keep_z_range.first, 1.0)); box_filter.setMax(Eigen::Vector4f(keep_x_range.second, keep_y_range.second, keep_z_range.second, 1.0)); box_filter.filter(*temp_cloud_ptr);
1.2 去除給定區(qū)域的點(diǎn)
在某些情況下,我們也會(huì)需要去除給定區(qū)域內(nèi)部的點(diǎn),比如在自動(dòng)駕駛中激光掃描的區(qū)域有一部分來(lái)自搭載激光雷達(dá)的車(chē)子本身
template < class PointType >void filterPointsWithinRegion(boost::shared_ptr< pcl::PointCloud< PointType > >& src_cloud_ptr, boost::shared_ptr< pcl::PointCloud< PointType > >& dst_cloud_ptr, const std::pair< double, double >& x_range, const std::pair< double, double >& y_range, const std::pair< double, double >& z_range, bool remove) { int num_points = src_cloud_ptr- >points.size(); boost::shared_ptr< pcl::PointCloud< PointType > > cloud_ptr(new pcl::PointCloud< PointType >()); cloud_ptr- >points.reserve(num_points); for (const auto& pt : src_cloud_ptr- >points) { bool inside = (pt.x >= x_range.first && pt.x < = x_range.second && pt.y >= y_range.first && pt.y < = y_range.second && pt.z >= z_range.first && pt.z < = z_range.second); if (inside ^ remove) { cloud_ptr- >points.push_back(pt); } } dst_cloud_ptr = cloud_ptr;}// PassThrough: 可以指定點(diǎn)云中的點(diǎn)的某個(gè)字段進(jìn)行范圍限制,將其設(shè)為 true 時(shí)可以進(jìn)行給定只保留給定范圍內(nèi)的點(diǎn)的功能 pcl::PassThrough< pcl::PointXYZ > pass_filter; bool reverse_limits = true; pass_filter.setInputCloud(filtered_cloud_ptr); pass_filter.setFilterFieldName("x"); pass_filter.setFilterLimits(-5, 5); pass_filter.getFilterLimitsNegative(reverse_limits); // reverse the limits pass_filter.filter(*filtered_cloud_ptr); pass_filter.setFilterFieldName("y"); pass_filter.setFilterLimits(-2, 2); pass_filter.getFilterLimitsNegative(reverse_limits); // reverse the limits pass_filter.filter(*filtered_cloud_ptr); pass_filter.setFilterFieldName("z"); pass_filter.setFilterLimits(-2, 2); pass_filter.getFilterLimitsNegative(reverse_limits); // reverse the limits pass_filter.filter(*filtered_cloud_ptr);
1.3 點(diǎn)云下采樣
1.3.1 柵格化采樣
這里第一點(diǎn)介紹柵格化的下采樣,在 PCL 中對(duì)應(yīng)的函數(shù)為體素濾波。柵格化下采樣大致的思路是計(jì)算整體點(diǎn)云的中心。
通過(guò)計(jì)算每個(gè)點(diǎn)到中心的距離結(jié)合要求的分辨率計(jì)算柵格對(duì)應(yīng)的坐標(biāo),并入其中,最后遍歷每個(gè)包含點(diǎn)的柵格計(jì)算其中點(diǎn)的幾何中心或者取該柵格中心加入目標(biāo)點(diǎn)云即可。
pcl::VoxelGrid< pcl::PointXYZ > voxel_filter; voxel_filter.setLeafSize(0.1, 0.1, 0.1); voxel_filter.setInputCloud(cloud_ptr); voxel_filter.filter(*filtered_cloud_ptr);
1.3.2 點(diǎn)云所在區(qū)域密度規(guī)律濾波
該方法直接基于點(diǎn)云分布密度進(jìn)行去噪,直觀的感受是可以根據(jù)點(diǎn)云中每個(gè)點(diǎn)所在區(qū)域判斷其是否是噪聲,一般來(lái)說(shuō)噪聲點(diǎn)所在區(qū)域都比較稀疏。
pcl::RadiusOutlierRemoval< pcl::PointXYZ >::Ptr radius_outlier_removal( new pcl::RadiusOutlierRemoval< pcl::PointXYZ >(true)); radius_outlier_removal- >setInputCloud(cloud_ptr); radius_outlier_removal- >setRadiusSearch(1.0); radius_outlier_removal- >setMinNeighborsInRadius(10); radius_outlier_removal- >filter(*filtered_cloud_ptr);
1.3.3 點(diǎn)云所在區(qū)域分布規(guī)律濾波
除了根據(jù)稠密意以外還可以根據(jù)距離來(lái)篩選濾波,每個(gè)點(diǎn)計(jì)算其到周?chē)舾牲c(diǎn)的平均距離,如果這個(gè)平均距離相對(duì)于整體點(diǎn)云中所有點(diǎn)的平均距離較近,則認(rèn)為其不是噪點(diǎn)
// PCL built-in radius removal pcl::StatisticalOutlierRemoval<pcl::PointXYZ>::Ptr statistical_outlier_removal( new pcl::StatisticalOutlierRemoval<pcl::PointXYZ>(true)); // set to true if we want to extract removed indices statistical_outlier_removal->setInputCloud(cloud_ptr); statistical_outlier_removal->setMeanK(20); statistical_outlier_removal->setStddevMulThresh(2.0); statistical_outlier_removal->filter(*filtered_cloud_ptr);
1.3.4 根據(jù)點(diǎn)云是否可以被穩(wěn)定觀察到篩選
LOAM 中對(duì)點(diǎn)云中的點(diǎn)是否能形成可靠特征的一個(gè)判斷標(biāo)準(zhǔn)是它能否被穩(wěn)定觀察到。
LOAM 中著重提了這兩種情況的點(diǎn)是不穩(wěn)定的:
- 特征成平面和掃描線(xiàn)近乎平行
- 特征掃描到的其中一端被另一個(gè)平面擋住,這部分的點(diǎn)也不穩(wěn)定
template < typename PointType >void filter_occuluded_points(boost::s
-
傳感器
+關(guān)注
關(guān)注
2566文章
53008瀏覽量
767672 -
激光雷達(dá)
+關(guān)注
關(guān)注
971文章
4236瀏覽量
192908 -
自動(dòng)駕駛
+關(guān)注
關(guān)注
790文章
14323瀏覽量
170713 -
點(diǎn)云
+關(guān)注
關(guān)注
0文章
58瀏覽量
3961
發(fā)布評(píng)論請(qǐng)先 登錄
激光雷達(dá)是自動(dòng)駕駛不可或缺的傳感器
激光雷達(dá)分類(lèi)以及應(yīng)用
常見(jiàn)激光雷達(dá)種類(lèi)
激光雷達(dá)面臨的機(jī)遇與挑戰(zhàn)
固態(tài)激光雷達(dá)
激光雷達(dá)
固態(tài)設(shè)計(jì)激光雷達(dá)
激光雷達(dá)除了可以激光測(cè)距外,還可以怎么應(yīng)用?
激光雷達(dá)知多少:從技術(shù)上講講未來(lái)前景
激光雷達(dá)點(diǎn)云數(shù)據(jù)分割算法的嵌入式平臺(tái)上的部署實(shí)現(xiàn)
詳解激光雷達(dá)點(diǎn)云數(shù)據(jù)的處理過(guò)程
激光雷達(dá)點(diǎn)云處理中遇到的問(wèn)題及對(duì)策
自動(dòng)駕駛之激光雷達(dá)預(yù)處理/特征提取

評(píng)論