利用统计滤波方法去除空中漂浮物 以及去噪
生活随笔
收集整理的這篇文章主要介紹了
利用统计滤波方法去除空中漂浮物 以及去噪
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
//統計濾波
//#include "pch.h"
//#include <iostream>
//#include <pcl/io/pcd_io.h>
//#include <pcl/point_types.h>
//#include <pcl/filters/statistical_outlier_removal.h>
//int
//main (int argc, char** argv)
//{
// pcl::PointCloud<pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZ>);
// pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filtered (new pcl::PointCloud<pcl::PointXYZ>); // 定義讀取對象
// pcl::PCDReader reader; // 讀取點云文件
// reader.read<pcl::PointXYZ> ("F://cout-saved//back_1.pcd", *cloud);
// std::cerr << "Cloud before filtering: " << std::endl;
// std::cerr << *cloud << std::endl;
// // 創建濾波器,對每個點分析的臨近點的個數設置為50 ,并將標準差的倍數設置為1 這意味著如果一
// //個點的距離超出了平均距離一個標準差以上,則該點被標記為離群點,并將它移除,存儲起來
// pcl::StatisticalOutlierRemoval<pcl::PointXYZ> sor; //創建濾波器對象
// sor.setInputCloud (cloud); //設置待濾波的點云
// //sor.setMeanK (100); //設置在進行統計時考慮查詢點臨近點數
// //sor.setStddevMulThresh (1.0); //back_1_inliers.pcd //設置判斷是否為離群點的閥值
//
// sor.setMeanK (250); //設置在進行統計時考慮查詢點臨近點數
// //sor.setStddevMulThresh (1.0); //2
// //sor.setStddevMulThresh(2.0);//3
// //sor.setStddevMulThresh(0.6);//4
// sor.setStddevMulThresh(0.3);//4
// sor.filter (*cloud_filtered); //存儲
// std::cerr << "Cloud after filtering: " << std::endl;
// std::cerr << *cloud_filtered << std::endl;
// pcl::PCDWriter writer; writer.write<pcl::PointXYZ> ("F://cout-saved//back_1_inliers5.pcd", *cloud_filtered, false);
// sor.setNegative (true);
// sor.filter (*cloud_filtered);
// writer.write<pcl::PointXYZ> ("F://cout-saved//back_1_outliers5.pcd", *cloud_filtered, false);
// return (0);
//}
StatisticalOutlierRemoval濾波器主要可以用來剔除離群點,或者測量誤差導致的粗差點。
濾波思想為:對每一個點的鄰域進行一個統計分析,計算它到所有臨近點的平均距離。假設得到的結果是一個高斯分布,其形狀是由均值和標準差決定,那么平均距離在標準范圍(由全局距離平均值和方差定義)之外的點,可以被定義為離群點并從數據中去除。
// The arrays to be usedstd::vector<int> nn_indices (mean_k_);std::vector<float> nn_dists (mean_k_);std::vector<float> distances (indices_->size ());//存儲每個點的距離indices.resize (indices_->size ());removed_indices_->resize (indices_->size ());int oii = 0, rii = 0; // oii = output indices iterator, rii = removed indices iterator
//第一 計算每個點到所有K鄰域點的平均距離。//First pass: Compute the mean distances for all points with respect to their k nearest neighborsint valid_distances = 0;for (int iii = 0; iii < static_cast<int> (indices_->size ()); ++iii) // iii = input indices iterator{if (!pcl_isfinite (input_->points[(*indices_)[iii]].x) ||!pcl_isfinite (input_->points[(*indices_)[iii]].y) ||!pcl_isfinite (input_->points[(*indices_)[iii]].z)){distances[iii] = 0.0;continue;}// Perform the nearest k searchif (searcher_->nearestKSearch ((*indices_)[iii], mean_k_ + 1, nn_indices, nn_dists) == 0){distances[iii] = 0.0;PCL_WARN ("[pcl::%s::applyFilter] Searching for the closest %d neighbors failed.\n", getClassName ().c_str (), mean_k_);continue;}// Calculate the mean distance to its neighborsdouble dist_sum = 0.0;for (int k = 1; k < mean_k_ + 1; ++k) // k = 0 is the query point 查詢點dist_sum += sqrt (nn_dists[k]);distances[iii] = static_cast<float> (dist_sum / mean_k_);valid_distances++;}
//計算整個點集距離容器的平均值和樣本標準差//Estimate the mean and the standard deviation of the distance vectordouble sum = 0, sq_sum = 0;for (size_t i = 0; i < distances.size (); ++i){sum += distances[i];sq_sum += distances[i] * distances[i];}double mean = sum / static_cast<double>(valid_distances); //距離平均值double variance = (sq_sum - sum * sum / static_cast<double>(valid_distances)) / (static_cast<double>(valid_distances) - 1); //樣本方差double stddev = sqrt (variance); //樣本標準差//getMeanStd (distances, mean, stddev);//距離閾值等于平均距離加上標準差倍數double distance_threshold = mean + std_mul_ * stddev;
//依次將距離閾值與每個點的distances[iii]比較 ,超出閾值的點被標記為離群點,并將其移除。// Second pass: Classify the points on the computed distance thresholdfor (int iii = 0; iii < static_cast<int> (indices_->size ()); ++iii) // iii = input indices iterator{// Points having a too high average distance are outliers and are passed to removed indices// Unless negative was set, then it's the opposite conditionif ((!negative_ && distances[iii] > distance_threshold) || (negative_ && distances[iii] <= distance_threshold)){if (extract_removed_indices_)(*removed_indices_)[rii++] = (*indices_)[iii];continue;}// Otherwise it was a normal point for output (inlier)indices[oii++] = (*indices_)[iii];}// Resize the output arraysindices.resize (oii);removed_indices_->resize (rii);
}
結果顯示:
總結
以上是生活随笔為你收集整理的利用统计滤波方法去除空中漂浮物 以及去噪的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 点云滤波
- 下一篇: 记录PCLVisualizer问题