Corrected missing template and typename keyword and added function to just select the points

This commit is contained in:
Paolo Cignoni 2015-10-25 23:24:23 +00:00
parent 12c1495bb0
commit d15745b128
1 changed files with 96 additions and 82 deletions

View File

@ -21,7 +21,7 @@
* * * *
****************************************************************************/ ****************************************************************************/
#ifndef VCG_TRI_OUTLIERS__H #ifndef VCG_TRI_OUTLIERS__H
#define VCG_TRI_OUTLIERS_H #define VCG_TRI_OUTLIERS__H
#include <vcg/space/index/kdtree/kdtree.h> #include <vcg/space/index/kdtree/kdtree.h>
@ -37,92 +37,106 @@ class OutlierRemoval
{ {
public: public:
typedef typename MeshType::ScalarType ScalarType; typedef typename MeshType::ScalarType ScalarType;
typedef typename vcg::KdTree<ScalarType> KdTreeType; typedef typename vcg::KdTree<ScalarType> KdTreeType;
typedef typename vcg::KdTree<ScalarType>::PriorityQueue PriorityQueue; typedef typename vcg::KdTree<ScalarType>::PriorityQueue PriorityQueue;
/** /**
Compute an outlier probability value for each vertex of the mesh using the approch Compute an outlier probability value for each vertex of the mesh using the approch
in the paper "LoOP: Local Outlier Probabilities". The outlier probability is stored in the in the paper "LoOP: Local Outlier Probabilities". The outlier probability is stored in the
vertex attribute "outlierScore". It use the input kdtree to find the kNearest of each vertex. vertex attribute "outlierScore". It use the input kdtree to find the kNearest of each vertex.
"LoOP: local outlier probabilities" by Hans-Peter Kriegel et al. "LoOP: local outlier probabilities" by Hans-Peter Kriegel et al.
Proceedings of the 18th ACM conference on Information and knowledge management Proceedings of the 18th ACM conference on Information and knowledge management
*/ */
static void ComputeLoOPScore(MeshType& mesh, KdTreeType& kdTree, int kNearest) static void ComputeLoOPScore(MeshType& mesh, KdTreeType& kdTree, int kNearest)
{ {
vcg::tri::RequireCompactness(mesh); vcg::tri::RequireCompactness(mesh);
CMesh::PerVertexAttributeHandle<ScalarType> outlierScore = vcg::tri::Allocator<MeshType>::GetPerVertexAttribute<ScalarType>(mesh, std::string("outlierScore")); typename MeshType::template PerVertexAttributeHandle<ScalarType> outlierScore = tri::Allocator<MeshType>:: template GetPerVertexAttribute<ScalarType>(mesh, std::string("outlierScore"));
CMesh::PerVertexAttributeHandle<ScalarType> sigma = vcg::tri::Allocator<MeshType>::GetPerVertexAttribute<ScalarType>(mesh, std::string("sigma")); typename MeshType::template PerVertexAttributeHandle<ScalarType> sigma = tri::Allocator<MeshType>:: template GetPerVertexAttribute<ScalarType>(mesh, std::string("sigma"));
CMesh::PerVertexAttributeHandle<ScalarType> plof = vcg::tri::Allocator<MeshType>::GetPerVertexAttribute<ScalarType>(mesh, std::string("plof")); typename MeshType::template PerVertexAttributeHandle<ScalarType> plof = tri::Allocator<MeshType>:: template GetPerVertexAttribute<ScalarType>(mesh, std::string("plof"));
#pragma omp parallel for schedule(dynamic, 10) #pragma omp parallel for schedule(dynamic, 10)
for (int i = 0; i < mesh.vert.size(); i++) for (int i = 0; i < mesh.vert.size(); i++)
{ {
PriorityQueue queue; PriorityQueue queue;
kdTree.doQueryK(mesh.vert[i].cP(), kNearest, queue); kdTree.doQueryK(mesh.vert[i].cP(), kNearest, queue);
ScalarType sum = 0; ScalarType sum = 0;
for (int j = 0; j < queue.getNofElements(); j++) for (int j = 0; j < queue.getNofElements(); j++)
sum += queue.getWeight(j); sum += queue.getWeight(j);
sum /= (queue.getNofElements()); sum /= (queue.getNofElements());
sigma[i] = sqrt(sum); sigma[i] = sqrt(sum);
} }
float mean = 0; float mean = 0;
#pragma omp parallel for reduction(+: mean) schedule(dynamic, 10) #pragma omp parallel for reduction(+: mean) schedule(dynamic, 10)
for (int i = 0; i < mesh.vert.size(); i++) for (int i = 0; i < mesh.vert.size(); i++)
{ {
PriorityQueue queue; PriorityQueue queue;
kdTree.doQueryK(mesh.vert[i].cP(), kNearest, queue); kdTree.doQueryK(mesh.vert[i].cP(), kNearest, queue);
ScalarType sum = 0; ScalarType sum = 0;
for (int j = 0; j < queue.getNofElements(); j++) for (int j = 0; j < queue.getNofElements(); j++)
sum += sigma[queue.getIndex(j)]; sum += sigma[queue.getIndex(j)];
sum /= (queue.getNofElements()); sum /= (queue.getNofElements());
plof[i] = sigma[i] / sum - 1.0f; plof[i] = sigma[i] / sum - 1.0f;
mean += plof[i] * plof[i]; mean += plof[i] * plof[i];
} }
mean /= mesh.vert.size(); mean /= mesh.vert.size();
mean = sqrt(mean); mean = sqrt(mean);
#pragma omp parallel for schedule(dynamic, 10) #pragma omp parallel for schedule(dynamic, 10)
for (int i = 0; i < mesh.vert.size(); i++) for (int i = 0; i < mesh.vert.size(); i++)
{ {
ScalarType value = plof[i] / (mean * sqrt(2.0f)); ScalarType value = plof[i] / (mean * sqrt(2.0f));
double dem = 1.0 + 0.278393 * value; double dem = 1.0 + 0.278393 * value;
dem += 0.230389 * value * value; dem += 0.230389 * value * value;
dem += 0.000972 * value * value * value; dem += 0.000972 * value * value * value;
dem += 0.078108 * value * value * value * value; dem += 0.078108 * value * value * value * value;
ScalarType op = max(0.0, 1.0 - 1.0 / dem); ScalarType op = max(0.0, 1.0 - 1.0 / dem);
outlierScore[i] = op; outlierScore[i] = op;
} }
vcg::tri::Allocator<CMesh>::DeletePerVertexAttribute(mesh, std::string("sigma")); tri::Allocator<MeshType>::DeletePerVertexAttribute(mesh, std::string("sigma"));
vcg::tri::Allocator<CMesh>::DeletePerVertexAttribute(mesh, std::string("plof")); tri::Allocator<MeshType>::DeletePerVertexAttribute(mesh, std::string("plof"));
}; };
/**
Select all the vertex of the mesh with an outlier probability above the input threshold [0.0, 1.0].
*/
static int SelectLoOPOutliers(MeshType& mesh, KdTreeType& kdTree, int kNearest, float threshold)
{
ComputeLoOPScore(mesh, kdTree, kNearest);
int count = 0;
typename MeshType:: template PerVertexAttributeHandle<ScalarType> outlierScore = tri::Allocator<MeshType>::template GetPerVertexAttribute<ScalarType>(mesh, std::string("outlierScore"));
for (int i = 0; i < mesh.vert.size(); i++)
{
if (outlierScore[i] > threshold)
{
mesh.vert[i].SetS();
count++;
}
}
return count;
}
/**
Delete all the vertex of the mesh with an outlier probability above the input threshold [0.0, 1.0]. /**
*/ Delete all the vertex of the mesh with an outlier probability above the input threshold [0.0, 1.0].
static int DeleteLoOPOutliers(MeshType& mesh, KdTreeType& kdTree, int kNearest, float threshold) */
{ static int DeleteLoOPOutliers(MeshType& m, KdTreeType& kdTree, int kNearest, float threshold)
ComputeLoOPScore(mesh, kdTree, kNearest); {
int count = 0; SelectLoOPOutliers(m,kdTree,kNearest,threshold);
CMesh::PerVertexAttributeHandle<ScalarType> outlierScore = vcg::tri::Allocator<MeshType>::GetPerVertexAttribute<ScalarType>(mesh, std::string("outlierScore")); int ovn = m.vn;
for (int i = 0; i < mesh.vert.size(); i++)
{ for(typename MeshType::VertexIterator vi=m.vert.begin();vi!=m.vert.end();++vi)
if (outlierScore[i] > threshold) if((*vi).IsS() ) tri::Allocator<MeshType>::DeleteVertex(m,*vi);
{ tri::Allocator<MeshType>::CompactVertexVector(m);
vcg::tri::Allocator<CMesh>::DeleteVertex(mesh, mesh.vert[i]); tri::Allocator<MeshType>::DeletePerVertexAttribute(m, std::string("outlierScore"));
count++; return m.vn - ovn;
} }
}
vcg::tri::Allocator<CMesh>::CompactVertexVector(mesh);
vcg::tri::Allocator<CMesh>::DeletePerVertexAttribute(mesh, std::string("outlierScore"));
return count;
};
}; };
} // end namespace tri } // end namespace tri