StatisticalOutlierRemoval源码
源代码
*
* Software License Agreement (BSD License)
*
* Point Cloud Library (PCL) - www.pointclouds.org
* Copyright (c) -, Willow Garage, Inc.
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of the copyright holder(s) nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* $Id$
*
*/ #ifndef PCL_FILTERS_IMPL_STATISTICAL_OUTLIER_REMOVAL_H_
#define PCL_FILTERS_IMPL_STATISTICAL_OUTLIER_REMOVAL_H_ #include <pcl/filters/statistical_outlier_removal.h>
#include <pcl/common/io.h> ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT> void
pcl::StatisticalOutlierRemoval<PointT>::applyFilter (PointCloud &output)
{
std::vector<int> indices;
if (keep_organized_)
{
bool temp = extract_removed_indices_;
extract_removed_indices_ = true;
applyFilterIndices (indices);
extract_removed_indices_ = temp; output = *input_;
for (int rii = ; rii < static_cast<int> (removed_indices_->size ()); ++rii) // rii = removed indices iterator
output.points[(*removed_indices_)[rii]].x = output.points[(*removed_indices_)[rii]].y = output.points[(*removed_indices_)[rii]].z = user_filter_value_;
if (!pcl_isfinite (user_filter_value_))
output.is_dense = false;
}
else
{
applyFilterIndices (indices);
copyPointCloud (*input_, indices, output);
}
} ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT> void
pcl::StatisticalOutlierRemoval<PointT>::applyFilterIndices (std::vector<int> &indices)
{
// Initialize the search class
if (!searcher_)
{
if (input_->isOrganized ())
searcher_.reset (new pcl::search::OrganizedNeighbor<PointT> ());
else
searcher_.reset (new pcl::search::KdTree<PointT> (false));
}
searcher_->setInputCloud (input_); // The arrays to be used
std::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 = , rii = ; // oii = output indices iterator, rii = removed indices iterator // First pass: Compute the mean distances for all points with respect to their k nearest neighbors
int valid_distances = ;
for (int iii = ; 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 search
if (searcher_->nearestKSearch ((*indices_)[iii], mean_k_ + , nn_indices, nn_dists) == )
{
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 neighbors
double dist_sum = 0.0;
for (int k = ; k < mean_k_ + ; ++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 vector
double sum = , sq_sum = ;
for (size_t i = ; 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) - );
double stddev = sqrt (variance);
//getMeanStd (distances, mean, stddev); double distance_threshold = mean + std_mul_ * stddev; // Second pass: Classify the points on the computed distance threshold
for (int iii = ; 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 condition
if ((!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 arrays
indices.resize (oii);
removed_indices_->resize (rii);
} #define PCL_INSTANTIATE_StatisticalOutlierRemoval(T) template class PCL_EXPORTS pcl::StatisticalOutlierRemoval<T>; #endif // PCL_FILTERS_IMPL_STATISTICAL_OUTLIER_REMOVAL_H_
最终会执行
template <typename PointT> void
pcl::StatisticalOutlierRemoval<PointT>::applyFilterIndices (std::vector<int> &indices)
1、进行一些简单Initialize
// Initialize the search class
if (!searcher_)
{
if (input_->isOrganized ())
searcher_.reset (new pcl::search::OrganizedNeighbor<PointT> ());
else
searcher_.reset (new pcl::search::KdTree<PointT> (false));
}
searcher_->setInputCloud (input_);
2、定义一些变量
// The arrays to be used
std::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
3、求每个点的k邻域的均值
// First pass: Compute the mean distances for all points with respect to their k nearest neighbors
int valid_distances = ;
for (int iii = ; 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 search
if (searcher_->nearestKSearch ((*indices_)[iii], mean_k_ + , nn_indices, nn_dists) == )
{
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 neighbors
double dist_sum = 0.0;
for (int k = ; k < mean_k_ + ; ++k) // k = 0 is the query point
dist_sum += sqrt (nn_dists[k]);
distances[iii] = static_cast<float> (dist_sum / mean_k_);//每个点都对应了一个距离变量
valid_distances++;
}
4、估计距离的均值和标准差 不是邻域 ,是根据整个数据中的点均值和标准差
// Estimate the mean and the standard deviation of the distance vector
double sum = , sq_sum = ;
for (size_t i = ; 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);
5、根据设定的距离阈值与distances[iii]比较 ,超出设定阈值则该点被标记为离群点,并将其移除。
double distance_threshold = mean + std_mul_ * stddev; // Second pass: Classify the points on the computed distance threshold
for (int iii = ; 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 condition
if ((!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];
}
indices.resize (oii);
removed_indices_->resize (rii);// Resize the output arrays
StatisticalOutlierRemoval源码的更多相关文章
- 【原】Android热更新开源项目Tinker源码解析系列之三:so热更新
本系列将从以下三个方面对Tinker进行源码解析: Android热更新开源项目Tinker源码解析系列之一:Dex热更新 Android热更新开源项目Tinker源码解析系列之二:资源文件热更新 A ...
- C# ini文件操作【源码下载】
介绍C#如何对ini文件进行读写操作,C#可以通过调用[kernel32.dll]文件中的 WritePrivateProfileString()和GetPrivateProfileString()函 ...
- 【原】FMDB源码阅读(三)
[原]FMDB源码阅读(三) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 FMDB比较优秀的地方就在于对多线程的处理.所以这一篇主要是研究FMDB的多线程处理的实现.而 ...
- 从源码看Azkaban作业流下发过程
上一篇零散地罗列了看源码时记录的一些类的信息,这篇完整介绍一个作业流在Azkaban中的执行过程,希望可以帮助刚刚接手Azkaban相关工作的开发.测试. 一.Azkaban简介 Azkaban作为开 ...
- 【原】Android热更新开源项目Tinker源码解析系列之一:Dex热更新
[原]Android热更新开源项目Tinker源码解析系列之一:Dex热更新 Tinker是微信的第一个开源项目,主要用于安卓应用bug的热修复和功能的迭代. Tinker github地址:http ...
- 【原】Android热更新开源项目Tinker源码解析系列之二:资源文件热更新
上一篇文章介绍了Dex文件的热更新流程,本文将会分析Tinker中对资源文件的热更新流程. 同Dex,资源文件的热更新同样包括三个部分:资源补丁生成,资源补丁合成及资源补丁加载. 本系列将从以下三个方 ...
- 多线程爬坑之路-Thread和Runable源码解析之基本方法的运用实例
前面的文章:多线程爬坑之路-学习多线程需要来了解哪些东西?(concurrent并发包的数据结构和线程池,Locks锁,Atomic原子类) 多线程爬坑之路-Thread和Runable源码解析 前面 ...
- SDWebImage源码解读之SDWebImageDownloaderOperation
第七篇 前言 本篇文章主要讲解下载操作的相关知识,SDWebImageDownloaderOperation的主要任务是把一张图片从服务器下载到内存中.下载数据并不难,如何对下载这一系列的任务进行设计 ...
- 【深入浅出jQuery】源码浅析--整体架构
最近一直在研读 jQuery 源码,初看源码一头雾水毫无头绪,真正静下心来细看写的真是精妙,让你感叹代码之美. 其结构明晰,高内聚.低耦合,兼具优秀的性能与便利的扩展性,在浏览器的兼容性(功能缺陷.渐 ...
随机推荐
- SQL SERVER建库&用户赋权限
create database ServiceDB on primary ( name='ServiceDB_data', -- 主数据文件的逻辑名称 filename='D:\WebRoot\DB\ ...
- Beginning Windows Azure Development Guide
目 录 一 初始化Windows Azure 二 云应用程序的编写. 2.1云应用程序的创建. 2.2一个简单的云应用程序. 2.3 托管云程序. 三 云程序的数据库操作. 3.1通过Cloud平台 ...
- FormData、Blob、File、ArrayBuffer数据类型
XMLHttpRequest 1.0 1.0 中xmlhttpRequest有2个重要的返回属性,reposeText,reposeXml.下面的数据类型都是2.0新增的 FormData对象 我们应 ...
- JavaScript学习笔记及知识点整理_3
1.js的事件冒泡及阻止方法:事件冒泡的概念:在一个对象上触发某类事件(比如单击onclick事件),如果此对象定义了此事件的处理程序,那么此事件就会调用这个处理程序,如果没有定义此事件处理程序或者事 ...
- MFC编程入门之十(对话框:设置对话框控件的Tab顺序)
前面几节为大家演示了加法计算器程序完整的编写过程,本节主要讲对话框上控件的Tab顺序如何调整. 上一讲为"计算"按钮添加了消息处理函数后,加法计算器已经能够进行浮点数的加法运算.但 ...
- Add two numbers [LeetCode]
You are given two linked lists representing two non-negative numbers. The digits are stored in rever ...
- 最短路径——Floyd算法
如何求一张图中任意两顶点之间的最短路径长度,这里写一种最简单的算法——Floyd算法: #include<stdio.h> #define inf 9999 int main() { ][ ...
- "struct"类型重定义解决办法
#ifndef 在头文件中的作用 在一个大的软件工程里面,可能会有多个文件同时包含一个头文件,当这些文件编译链接成一个可执行文件时,就会出现大量 “重定义”的错误. 在头文件中使用#ifndef #d ...
- 读javascript高级程序设计03-函数表达式、闭包、私有变量
一.函数声明和函数表达式 定义函数有两种方式:函数声明和函数表达式.它们之间一个重要的区别是函数提升. 1.函数声明会进行函数提升,所以函数调用在函数声明之前也不会报错: test(); functi ...
- ShopNC小实例
shopnc 之模式: shopnc一般的url访问为:http://localhost/shopnc1/admin/index.php?act=sui&op=hello Controller ...