예제 #1
0
bool ScalarFieldTools::applyScalarFieldGaussianFilter(PointCoordinateType sigma,
													  GenericIndexedCloudPersist* theCloud,
													  PointCoordinateType sigmaSF,
													  GenericProgressCallback* progressCb,
													  DgmOctree* theCloudOctree)
{
	if (!theCloud)
        return false;

	unsigned n = theCloud->size();
	if (n==0)
        return false;

	DgmOctree* theOctree = 0;
	if (theCloudOctree)
        theOctree = theCloudOctree;
	else
	{
		theOctree = new DgmOctree(theCloud);
		if (theOctree->build(progressCb)<1)
		{
			delete theOctree;
			return false;
		}
	}

    //best octree level
	unsigned char level = theOctree->findBestLevelForAGivenNeighbourhoodSizeExtraction(3.0f*sigma);

	//output scalar field should be different than input one
	theCloud->enableScalarField();

	if (progressCb)
	{
		progressCb->reset();
		progressCb->setMethodTitle("Gaussian filter");
		char infos[256];
		sprintf(infos,"Level: %i\n",level);
		progressCb->setInfo(infos);
	}

    void* additionalParameters[2] = {	reinterpret_cast<void*>(&sigma),
										reinterpret_cast<void*>(&sigmaSF)
	};

	bool success = true;

	if (theOctree->executeFunctionForAllCellsAtLevel(	level,
														computeCellGaussianFilter,
														additionalParameters,
														true,
														progressCb,
														"Gaussian Filter computation") == 0)
	{
		//something went wrong
		success = false;
	}

	return success;
}
예제 #2
0
SimpleCloud* CloudSamplingTools::resampleCloudWithOctreeAtLevel(GenericIndexedCloudPersist* theCloud, uchar octreeLevel, RESAMPLING_CELL_METHOD resamplingMethod, GenericProgressCallback* progressCb, DgmOctree* _theOctree)
{
	assert(theCloud);

	DgmOctree* theOctree = _theOctree;
	if (!theOctree)
	{
		theOctree = new DgmOctree(theCloud);
		if (theOctree->build(progressCb) < 1)
		{
			delete theOctree;
			return 0;
		}
	}

	SimpleCloud* cloud = new SimpleCloud();

	unsigned nCells = theOctree->getCellNumber(octreeLevel);
	if (!cloud->reserve(nCells))
	{
		if (!_theOctree)
			delete theOctree;
		delete cloud;
		return 0;
	}

	//structure contenant les parametres additionnels
	void* additionalParameters[2];
	additionalParameters[0] = (void*)cloud;
	additionalParameters[1] = (void*)&resamplingMethod;

	//The process is so simple that MT is slower!
	//#ifdef ENABLE_MT_OCTREE
	//theOctree->executeFunctionForAllCellsAtLevel_MT(octreeLevel,
	//#else
	if (theOctree->executeFunctionForAllCellsAtLevel(octreeLevel,
													&resampleCellAtLevel,
													additionalParameters,
													progressCb,
													"Cloud Resampling") == 0)
	{
		//something went wrong
		delete cloud;
		cloud=0;

	}

	if (!_theOctree)
        delete theOctree;

	return cloud;
}
예제 #3
0
SimpleCloud* CloudSamplingTools::resampleCloudWithOctreeAtLevel(GenericIndexedCloudPersist* inputCloud,
																unsigned char octreeLevel,
																RESAMPLING_CELL_METHOD resamplingMethod,
																GenericProgressCallback* progressCb/*=0*/,
																DgmOctree* inputOctree/*=0*/)
{
	assert(inputCloud);

	DgmOctree* octree = inputOctree;
	if (!octree)
	{
		octree = new DgmOctree(inputCloud);
		if (octree->build(progressCb) < 1)
		{
			delete octree;
			return 0;
		}
	}

	SimpleCloud* cloud = new SimpleCloud();

	unsigned nCells = octree->getCellNumber(octreeLevel);
	if (!cloud->reserve(nCells))
	{
		if (!inputOctree)
			delete octree;
		delete cloud;
		return 0;
	}

	//structure contenant les parametres additionnels
	void* additionalParameters[2] = {	reinterpret_cast<void*>(cloud),
										reinterpret_cast<void*>(&resamplingMethod) };

	if (octree->executeFunctionForAllCellsAtLevel(	octreeLevel,
														&resampleCellAtLevel,
														additionalParameters,
														false, //the process is so simple that MT is slower!
														progressCb,
														"Cloud Resampling") == 0)
	{
		//something went wrong
		delete cloud;
		cloud=0;

	}

	if (!inputOctree)
		delete octree;

	return cloud;
}
예제 #4
0
int GeometricalAnalysisTools::computeCurvature(	GenericIndexedCloudPersist* theCloud,
												Neighbourhood::CC_CURVATURE_TYPE cType,
												PointCoordinateType kernelRadius,
												GenericProgressCallback* progressCb/*=0*/,
												DgmOctree* inputOctree/*=0*/)
{
	if (!theCloud)
		return -1;

	unsigned numberOfPoints = theCloud->size();
	if (numberOfPoints < 5)
		return -2;

	DgmOctree* theOctree = inputOctree;
	if (!theOctree)
	{
		theOctree = new DgmOctree(theCloud);
		if (theOctree->build(progressCb) < 1)
		{
			delete theOctree;
			return -3;
		}
	}

	theCloud->enableScalarField();

	unsigned char level = theOctree->findBestLevelForAGivenNeighbourhoodSizeExtraction(kernelRadius);

	//parameters
	void* additionalParameters[2] = {	static_cast<void*>(&cType),
										static_cast<void*>(&kernelRadius) };

	int result = 0;

	if (theOctree->executeFunctionForAllCellsAtLevel(level,
													&computeCellCurvatureAtLevel,
													additionalParameters,
													true,
													progressCb,
													"Curvature Computation") == 0)
	{
		//something went wrong
		result = -4;
	}

	if (!inputOctree)
        delete theOctree;

	return result;
}
예제 #5
0
int GeometricalAnalysisTools::flagDuplicatePoints(	GenericIndexedCloudPersist* theCloud,
													double minDistanceBetweenPoints/*=1.0e-12*/,
													GenericProgressCallback* progressCb/*=0*/,
													DgmOctree* inputOctree/*=0*/)
{
	if (!theCloud)
		return -1;

	unsigned numberOfPoints = theCloud->size();
	if (numberOfPoints <= 1)
		return -2;

	DgmOctree* theOctree = inputOctree;
	if (!theOctree)
	{
		theOctree = new DgmOctree(theCloud);
		if (theOctree->build(progressCb) < 1)
		{
			delete theOctree;
			return -3;
		}
	}

	theCloud->enableScalarField();
	//set all flags to 0 by default
	theCloud->forEach(CCLib::ScalarFieldTools::SetScalarValueToZero);

	unsigned char level = theOctree->findBestLevelForAGivenNeighbourhoodSizeExtraction(static_cast<PointCoordinateType>(minDistanceBetweenPoints));

	//parameters
	void* additionalParameters[1] = { static_cast<void*>(&minDistanceBetweenPoints) };

	int result = 0;

	if (theOctree->executeFunctionForAllCellsAtLevel(	level,
														&flagDuplicatePointsInACellAtLevel,
														additionalParameters,
														false, //doesn't work in parallel!
														progressCb,
														"Flag duplicate points") == 0)
	{
		//something went wrong
		result = -4;
	}

	if (!inputOctree)
		delete theOctree;

	return result;
}
예제 #6
0
int GeometricalAnalysisTools::computeLocalDensityApprox(GenericIndexedCloudPersist* theCloud,
														Density densityType,
														GenericProgressCallback* progressCb/*=0*/,
														DgmOctree* inputOctree/*=0*/)
{
	if (!theCloud)
		return -1;

	unsigned numberOfPoints = theCloud->size();
	if (numberOfPoints < 3)
		return -2;

	DgmOctree* theOctree = inputOctree;
	if (!theOctree)
	{
		theOctree = new DgmOctree(theCloud);
		if (theOctree->build(progressCb) < 1)
		{
			delete theOctree;
			return -3;
		}
	}

	theCloud->enableScalarField();

	//determine best octree level to perform the computation
	unsigned char level = theOctree->findBestLevelForAGivenPopulationPerCell(3);

	//parameters
	void* additionalParameters[] = { static_cast<void*>(&densityType) };

	int result = 0;

	if (theOctree->executeFunctionForAllCellsAtLevel(	level,
														&computeApproxPointsDensityInACellAtLevel,
														additionalParameters,
														true,
														progressCb,
														"Approximate Local Density Computation") == 0)
	{
		//something went wrong
		result = -4;
	}

	if (!inputOctree)
		delete theOctree;

	return result;
}
예제 #7
0
ReferenceCloud* CloudSamplingTools::noiseFilter(GenericIndexedCloudPersist* inputCloud,
												PointCoordinateType kernelRadius,
												double nSigma,
												bool removeIsolatedPoints/*=false*/,
												bool useKnn/*=false*/,
												int knn/*=6*/,
												bool useAbsoluteError/*=true*/,
												double absoluteError/*=0.0*/,
												DgmOctree* inputOctree/*=0*/,
												GenericProgressCallback* progressCb/*=0*/)
{
	if (!inputCloud || inputCloud->size() < 2 || (useKnn && knn <= 0) || (!useKnn && kernelRadius <= 0))
	{
		//invalid input
		assert(false);
		return 0;
	}

	DgmOctree* octree = inputOctree;
	if (!octree)
	{
		octree = new DgmOctree(inputCloud);
		if (octree->build(progressCb) < 1)
		{
			delete octree;
			return 0;
		}
	}

	ReferenceCloud* filteredCloud = new ReferenceCloud(inputCloud);

	unsigned pointCount = inputCloud->size();
	if (!filteredCloud->reserve(pointCount))
	{
		//not enough memory
		if (!inputOctree)
			delete octree;
		delete filteredCloud;
		return 0;
	}

	//additional parameters
	void* additionalParameters[] = {reinterpret_cast<void*>(filteredCloud),
									reinterpret_cast<void*>(&kernelRadius),
									reinterpret_cast<void*>(&nSigma),
									reinterpret_cast<void*>(&removeIsolatedPoints),
									reinterpret_cast<void*>(&useKnn),
									reinterpret_cast<void*>(&knn),
									reinterpret_cast<void*>(&useAbsoluteError),
									reinterpret_cast<void*>(&absoluteError)
	};

	unsigned char octreeLevel = 0;
	if (useKnn)
		octreeLevel = octree->findBestLevelForAGivenNeighbourhoodSizeExtraction(kernelRadius);
	else
		octreeLevel = octree->findBestLevelForAGivenPopulationPerCell(knn);

	if (octree->executeFunctionForAllCellsAtLevel(	octreeLevel,
													&applyNoiseFilterAtLevel,
													additionalParameters,
													true,
													progressCb,
													"Noise filter" ) == 0)
	{
		//something went wrong
		delete filteredCloud;
		filteredCloud = 0;
	}

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

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

	return filteredCloud;
}
예제 #8
0
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 0;
	}

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

	//output
	ReferenceCloud* filteredCloud = 0;

	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, 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(fabs(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 = 0;
				break;
			}

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

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

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

	return filteredCloud;
}
예제 #9
0
int GeometricalAnalysisTools::computeLocalDensity(	GenericIndexedCloudPersist* theCloud,
													Density densityType,
													PointCoordinateType kernelRadius,
													GenericProgressCallback* progressCb/*=0*/,
													DgmOctree* inputOctree/*=0*/)
{
	if (!theCloud)
		return -1;

	unsigned numberOfPoints = theCloud->size();
	if (numberOfPoints < 3)
		return -2;

	//compute the right dimensional coef based on the expected output
	double dimensionalCoef = 1.0;
	switch (densityType)
	{
	case DENSITY_KNN:
		dimensionalCoef = 1.0;
		break;
	case DENSITY_2D:
		dimensionalCoef = M_PI * (static_cast<double>(kernelRadius) * kernelRadius);
		break;
	case DENSITY_3D:
		dimensionalCoef = s_UnitSphereVolume * ((static_cast<double>(kernelRadius) * kernelRadius) * kernelRadius);
		break;
	default:
		assert(false);
		return -5;
	}

	DgmOctree* theOctree = inputOctree;
	if (!theOctree)
	{
		theOctree = new DgmOctree(theCloud);
		if (theOctree->build(progressCb) < 1)
		{
			delete theOctree;
			return -3;
		}
	}

	theCloud->enableScalarField();

	//determine best octree level to perform the computation
	unsigned char level = theOctree->findBestLevelForAGivenNeighbourhoodSizeExtraction(kernelRadius);

	//parameters
	void* additionalParameters[] = {	static_cast<void*>(&kernelRadius),
										static_cast<void*>(&dimensionalCoef) };

	int result = 0;

	if (theOctree->executeFunctionForAllCellsAtLevel(	level,
														&computePointsDensityInACellAtLevel,
														additionalParameters,
														true,
														progressCb,
														"Local Density Computation") == 0)
	{
		//something went wrong
		result = -4;
	}

	if (!inputOctree)
        delete theOctree;

	return result;
}
예제 #10
0
int ScalarFieldTools::computeScalarFieldGradient(	GenericIndexedCloudPersist* theCloud,
													PointCoordinateType radius,
													bool euclideanDistances,
													bool sameInAndOutScalarField/*=false*/,
													GenericProgressCallback* progressCb/*=0*/,
													DgmOctree* theCloudOctree/*=0*/)
{
	if (!theCloud)
        return -1;

	DgmOctree* theOctree = theCloudOctree;
	if (!theOctree)
	{
		theOctree = new DgmOctree(theCloud);
		if (theOctree->build(progressCb)<1)
		{
			delete theOctree;
			return -2;
		}
	}

	unsigned char octreeLevel = 0;
	if (radius <= 0)
	{
		octreeLevel = theOctree->findBestLevelForAGivenPopulationPerCell(AVERAGE_NUMBER_OF_POINTS_FOR_GRADIENT_COMPUTATION);
		radius = theOctree->getCellSize(octreeLevel);
	}
	else
	{
		octreeLevel = theOctree->findBestLevelForAGivenNeighbourhoodSizeExtraction(radius);
	}

	ScalarField* theGradientNorms = new ScalarField("gradient norms");
	ScalarField* _theGradientNorms = 0;

	//mode champ scalaire "IN" et "OUT" identique
	if (sameInAndOutScalarField)
	{
		if (!theGradientNorms->reserve(theCloud->size())) //not enough memory
		{
			if (!theCloudOctree)
				delete theOctree;
			theGradientNorms->release();
			return -3;
		}
		_theGradientNorms = theGradientNorms;
	}
	else
	//mode champs scalaires "IN" et "OUT" dfferents (par defaut)
	{
		//on initialise les distances (IN - en ecriture) pour recevoir les normes du gradient
		if (!theCloud->enableScalarField())
		{
			if (!theCloudOctree)
				delete theOctree;
			theGradientNorms->release();
			return -4;
		}
	}

	//structure contenant les parametres additionnels
	void* additionalParameters[3] = {	static_cast<void*>(&euclideanDistances),
										static_cast<void*>(&radius),
										static_cast<void*>(_theGradientNorms)
	};

	int result = 0;

	if (theOctree->executeFunctionForAllCellsAtLevel(	octreeLevel,
														computeMeanGradientOnPatch,
														additionalParameters,
														true,
														progressCb,
														"Gradient Computation") == 0)
	{
		//something went wrong
		result = -5;
	}

	if (!theCloudOctree)
        delete theOctree;

	theGradientNorms->release();
	theGradientNorms=0;

    return result;
}