Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifndef VCG_TRI_OUTLIERS__H
00024 #define VCG_TRI_OUTLIERS__H
00025
00026 #include <vcg/space/index/kdtree/kdtree.h>
00027
00028
00029 namespace vcg
00030 {
00031
00032 namespace tri
00033 {
00034
00035 template <class MeshType>
00036 class OutlierRemoval
00037 {
00038 public:
00039
00040 typedef typename MeshType::ScalarType ScalarType;
00041 typedef typename vcg::KdTree<ScalarType> KdTreeType;
00042 typedef typename vcg::KdTree<ScalarType>::PriorityQueue PriorityQueue;
00043
00044
00053 static void ComputeLoOPScore(MeshType& mesh, KdTreeType& kdTree, int kNearest)
00054 {
00055 vcg::tri::RequireCompactness(mesh);
00056 typename MeshType::template PerVertexAttributeHandle<ScalarType> outlierScore = tri::Allocator<MeshType>:: template GetPerVertexAttribute<ScalarType>(mesh, std::string("outlierScore"));
00057 typename MeshType::template PerVertexAttributeHandle<ScalarType> sigma = tri::Allocator<MeshType>:: template GetPerVertexAttribute<ScalarType>(mesh, std::string("sigma"));
00058 typename MeshType::template PerVertexAttributeHandle<ScalarType> plof = tri::Allocator<MeshType>:: template GetPerVertexAttribute<ScalarType>(mesh, std::string("plof"));
00059
00060 #pragma omp parallel for schedule(dynamic, 10)
00061 for (size_t i = 0; i < mesh.vert.size(); i++)
00062 {
00063 PriorityQueue queue;
00064 kdTree.doQueryK(mesh.vert[i].cP(), kNearest, queue);
00065 ScalarType sum = 0;
00066 for (int j = 0; j < queue.getNofElements(); j++)
00067 sum += queue.getWeight(j);
00068 sum /= (queue.getNofElements());
00069 sigma[i] = sqrt(sum);
00070 }
00071
00072 float mean = 0;
00073 #pragma omp parallel for reduction(+: mean) schedule(dynamic, 10)
00074 for (size_t i = 0; i < mesh.vert.size(); i++)
00075 {
00076 PriorityQueue queue;
00077 kdTree.doQueryK(mesh.vert[i].cP(), kNearest, queue);
00078 ScalarType sum = 0;
00079 for (int j = 0; j < queue.getNofElements(); j++)
00080 sum += sigma[queue.getIndex(j)];
00081 sum /= (queue.getNofElements());
00082 plof[i] = sigma[i] / sum - 1.0f;
00083 mean += plof[i] * plof[i];
00084 }
00085
00086 mean /= mesh.vert.size();
00087 mean = sqrt(mean);
00088
00089 #pragma omp parallel for schedule(dynamic, 10)
00090 for (size_t i = 0; i < mesh.vert.size(); i++)
00091 {
00092 ScalarType value = plof[i] / (mean * sqrt(2.0f));
00093 double dem = 1.0 + 0.278393 * value;
00094 dem += 0.230389 * value * value;
00095 dem += 0.000972 * value * value * value;
00096 dem += 0.078108 * value * value * value * value;
00097 ScalarType op = max(0.0, 1.0 - 1.0 / dem);
00098 outlierScore[i] = op;
00099 }
00100
00101 tri::Allocator<MeshType>::DeletePerVertexAttribute(mesh, std::string("sigma"));
00102 tri::Allocator<MeshType>::DeletePerVertexAttribute(mesh, std::string("plof"));
00103 };
00104
00108 static int SelectLoOPOutliers(MeshType& mesh, KdTreeType& kdTree, int kNearest, float threshold)
00109 {
00110 ComputeLoOPScore(mesh, kdTree, kNearest);
00111 int count = 0;
00112 typename MeshType:: template PerVertexAttributeHandle<ScalarType> outlierScore = tri::Allocator<MeshType>::template GetPerVertexAttribute<ScalarType>(mesh, std::string("outlierScore"));
00113 for (int i = 0; i < mesh.vert.size(); i++)
00114 {
00115 if (outlierScore[i] > threshold)
00116 {
00117 mesh.vert[i].SetS();
00118 count++;
00119 }
00120 }
00121 return count;
00122 }
00123
00124
00125
00129 static int DeleteLoOPOutliers(MeshType& m, KdTreeType& kdTree, int kNearest, float threshold)
00130 {
00131 SelectLoOPOutliers(m,kdTree,kNearest,threshold);
00132 int ovn = m.vn;
00133
00134 for(typename MeshType::VertexIterator vi=m.vert.begin();vi!=m.vert.end();++vi)
00135 if((*vi).IsS() ) tri::Allocator<MeshType>::DeleteVertex(m,*vi);
00136 tri::Allocator<MeshType>::CompactVertexVector(m);
00137 tri::Allocator<MeshType>::DeletePerVertexAttribute(m, std::string("outlierScore"));
00138 return m.vn - ovn;
00139 }
00140 };
00141
00142 }
00143
00144 }
00145
00146 #endif // VCG_TRI_OUTLIERS_H