CloudCompare——统计滤波

在这里插入图片描述

本文由CSDN点云侠原创,CloudCompare——统计滤波,爬虫自重。如果你不是在点云侠的博客中看到该文章,那么此处便是不要脸的爬虫。

1.统计滤波

  算法原理见:PCL 统计滤波器

2.软件实现

参数设置
在这里插入图片描述

3.完整操作

在这里插入图片描述

4.算法源码

ReferenceCloud* CloudSamplingTools::sorFilter(	GenericIndexedCloudPersist* inputCloud,
												int knn/*=6*/,
												double nSigma/*=1.0*/,
												DgmOctree* inputOctree/*=0*/,
												GenericProgressCallback* progressCb/*=0*/)
{
    
    
	if (!inputCloud || knn <= 0 || inputCloud->size() <= static_cast<unsigned>(knn))
	{
    
    
		//invalid input
		assert(false);
		return nullptr;
	}

	DgmOctree* octree = inputOctree;
	if (!octree)
	{
    
    
		//compute the octree if necessary
		octree = new DgmOctree(inputCloud);
		if (octree->build(progressCb) < 1)
		{
    
    
			delete octree;
			return nullptr;
		}
	}

	//output
	ReferenceCloud* filteredCloud = nullptr;

	for (unsigned step = 0; step < 1; ++step) //fake loop for easy break
	{
    
    
		unsigned pointCount = inputCloud->size();

		std::vector<PointCoordinateType> meanDistances;
		try
		{
    
    
			meanDistances.resize(pointCount, 0);
		}
		catch (const std::bad_alloc&)
		{
    
    
			//not enough memory
			break;
		}
		
		double avgDist = 0;
		double stdDev = 0;

		//1st step: compute the average distance to the neighbors
		{
    
    
			//additional parameters
			void* additionalParameters[] = {
    
    reinterpret_cast<void*>(&knn),
											reinterpret_cast<void*>(&meanDistances)
			};

			unsigned char octreeLevel = octree->findBestLevelForAGivenPopulationPerCell(knn);

			if (octree->executeFunctionForAllCellsAtLevel(	octreeLevel,
															&applySORFilterAtLevel,
															additionalParameters,
															true,
															progressCb,
															"SOR filter") == 0)
			{
    
    
				//something went wrong
				break;
			}

			//deduce the average distance and std. dev.
			double sumDist = 0;
			double sumSquareDist = 0;
			for (unsigned i = 0; i < pointCount; ++i)
			{
    
    
				sumDist += meanDistances[i];
				sumSquareDist += meanDistances[i] * meanDistances[i];
			}
			avgDist = sumDist / pointCount;
			stdDev = sqrt(std::abs(sumSquareDist / pointCount - avgDist*avgDist));
		}

		//2nd step: remove the farthest points 
		{
    
    
			//deduce the max distance
			double maxDist = avgDist + nSigma * stdDev;

			filteredCloud = new ReferenceCloud(inputCloud);
			if (!filteredCloud->reserve(pointCount))
			{
    
    
				//not enough memory
				delete filteredCloud;
				filteredCloud = nullptr;
				break;
			}

			for (unsigned i = 0; i < pointCount; ++i)
			{
    
    
				if (meanDistances[i] <= maxDist)
				{
    
    
					filteredCloud->addPointIndex(i);
				}
			}

			filteredCloud->resize(filteredCloud->size());
		}
	}

	if (!inputOctree)
	{
    
    
		delete octree;
		octree = nullptr;
	}

	return filteredCloud;
}

5.相关代码

猜你喜欢

转载自blog.csdn.net/qq_36686437/article/details/132133443