ANNkd_tree::~ANNkd_tree() // tree destructor { if (root != NULL) delete root; if (pidx != NULL) delete [] pidx; if (bnd_box_lo != NULL) annDeallocPt(bnd_box_lo); if (bnd_box_hi != NULL) annDeallocPt(bnd_box_hi); }
ANNkd_tree::~ANNkd_tree() // tree destructor { if (root != NULL) delete root; if (pidx != NULL) delete [] pidx; if (bnd_box_lo != NULL) annDeallocPt(bnd_box_lo); if (bnd_box_hi != NULL) annDeallocPt(bnd_box_hi); if (Topology != NULL) delete [] Topology; if (Scale != NULL) delete [] Scale; }
void KDTree3::FreeMemory() { if(nnIdx) { delete[] nnIdx; nnIdx = NULL; } if(dists) { delete[] dists; dists = NULL; } if(kdTree) { delete kdTree; kdTree = NULL; } if(queryPt) { annDeallocPt(queryPt); queryPt = NULL; } if(dataPts) { annDeallocPts(dataPts); dataPts = NULL; } }
ANN::~ANN() { annDeallocPts(data_pts); // deallocate data points annDeallocPt(query_pt); // deallocate query points delete [] node_indices; // deallocate point indices delete(nn_idx); // deallocate the near neighbors indices delete(dists); // deallocate the near neighbors distances delete(the_tree); // deastroy the ANN tree }
ERMsg CKNearestNeighbor::Search(const CMDPoint& pt, long nbPoint, CSearchResultVector& result, double eps)const { ERMsg msg; if (m_pTreeRoot == NULL) { msg = Init(); if (!msg) return msg; } //Find point event if they have not enough points int nbPointSearch = (int)min(nbPoint, (long)size()); ASSERT(nbPointSearch <= (int)size()); result.clear(); if (size() > 0) { ASSERT(pt.GetNbDimension() == GetNbDimension()); result.resize(nbPointSearch); try { ANNidxArray nn_idx = new ANNidx[nbPointSearch]; // allocate near neighbor indices ANNdistArray dd = new ANNdist[nbPointSearch]; // allocate near neighbor distance ANNpoint q = m_X.GetANNpoint(pt, m_in); m_pTreeRoot->annPkSearch(q, nbPointSearch, nn_idx, dd, eps); for (int i = 0; i < nbPointSearch; i++) { result[i].m_index = nn_idx[i]; dd[i] = sqrt(dd[i]); // un-squared distance result[i].m_distance = dd[i]; } //caller must free memory annDeallocPt(q); delete[] nn_idx; delete[] dd; ASSERT(result.size() == nbPointSearch); } catch (...) { msg.ajoute("Exception in ANN search"); } } if (result.size() != nbPoint) msg.ajoute("Searching error: not enough points"); return msg; }
void operator()( tbb::blocked_range<int> rng ) const{ ANNidx id; ANNdist d; ANNpoint pt = annAllocPt( feature_size ); for( int i=rng.begin(); i<rng.end(); i++ ){ for( int j=0; j<feature_size; j++ ) pt[j] = features[i*feature_size+j]; kd_tree->annkSearch(pt, 1, &id, &d ); res[i] = id; } annDeallocPt( pt ); }
void mitk::PointLocator::DestroyANN() { m_SearchTreeInitialized = false; if (m_ANNQueryPoint != nullptr) annDeallocPt(m_ANNQueryPoint); if (m_ANNDataPoints != nullptr) annDeallocPts(m_ANNDataPoints); if (m_ANNPointIndexes != nullptr) delete[] m_ANNPointIndexes; if (m_ANNDistances != nullptr) delete[] m_ANNDistances; if (m_ANNTree != nullptr) delete m_ANNTree; }
short KMeans::evaluate(const float * feature, int feature_size) const { if (!kd_tree_) initAnn(); ANNidx id; ANNdist d; ANNpoint pt = annAllocPt( feature_size ); for( int i=0; i<feature_size; i++ ) pt[i] = feature[i]; kd_tree_->annkSearch( pt, 1, &id, &d ); annDeallocPt( pt ); return id; }
void KMeans::evaluateMany( const float * features, int feature_size, int N, short * res ) const{ if (!kd_tree_) initAnn(); // Our patched version of ANN works with TBB ANNidx id; ANNdist d; ANNpoint pt = annAllocPt( feature_size ); for( int i=0; i<N; i++ ){ for( int j=0; j<feature_size; j++ ) pt[j] = features[i*feature_size+j]; kd_tree_->annkSearch(pt, 1, &id, &d ); res[i] = id; } annDeallocPt( pt ); }
bool arlCore::Mesh::simplify( void ) { #ifndef ANN return false; #else // ANN unsigned int i, j; const unsigned int Size = m_pointList->visibleSize(); const unsigned int Dimension = m_pointList->getDimension(); ANNpointArray ANNPoints = annAllocPts( Size, Dimension ); for( i=0 ; i<m_pointList->size() ; ++i ) for( j=0 ; j<Dimension ; ++j ) ANNPoints[i][j]=(*m_pointList)[i]->get(j); const int BucketSize = 1; ANNkd_tree* ANNtree = new ANNkd_tree( ANNPoints, Size, Dimension, BucketSize, ANN_KD_SL_MIDPT ); const double Epsilon = 1e-8;// Error bound const double SquaredEpsilon = Epsilon*Epsilon; ANNpoint ANNPt = annAllocPt(Dimension); // Query point const unsigned int NbNeighbors = 20; ANNidxArray Nn_idx = new ANNidx[NbNeighbors]; // near neighbor indices ANNdistArray SquaredDists = new ANNdist[NbNeighbors]; // near neighbor distances for( i=0 ; i<m_pointList->size() ; ++i ) if((*m_pointList)[i]->isVisible()) { std::vector<unsigned int> oldIndex; for( j=0 ; j<Dimension; ++j ) ANNPt[j] = (*m_pointList)[i]->get(j); ANNtree->annkSearch( ANNPt, NbNeighbors, Nn_idx, SquaredDists, Epsilon ); // Cherche points les plus proches for( j=0 ; j<NbNeighbors ; ++j ) if(SquaredDists[j]<=SquaredEpsilon) { releasePoint(Nn_idx[j]); oldIndex.push_back(Nn_idx[j]); } replacePointIndex(oldIndex, i); } delete ANNtree; annDeallocPt( ANNPt ); annDeallocPts( ANNPoints ); delete[] Nn_idx; delete[] SquaredDists; annClose(); return true; #endif // ANN }
//retourne le point de p correspondant au point q des images B et Bp dans A et Ap //au niveau l Point* annUse::bestApproximateMatch(Image* B, Image* Bp,int l, Point* q,Image* A, FeatureType Type) { int marge; if(gk==0 && pk==0) marge=2; else marge=(gk>=pk*2)?gk*3:pk*4+2; //construction de l'ANNpoint correspondant à q et son voisinnage ANNpoint queryPt = annAllocPt(dim); makeANNPoint(B,Bp,l,q->getX(),q->getY(), Type, queryPt); //recherche du point correspondant dans A et Ap kdTree->annkSearch(queryPt, 1, nnIdx, dists, eps); //calcul et retour des coordonnées du point uint32 x=nnIdx[0]%(A->getLargeur(l)-marge); uint32 y=nnIdx[0]/(A->getLargeur(l)-marge); //libération de l'ANNpoint annDeallocPt(queryPt); return new Point(x+gk,y+gk); }
int CANNObject::GetNdxFromVector(std::vector<int>& point) { // allocate query point ANNpoint queryPt = annAllocPt(point.size()); // read query point ReadPointFromVector(point, queryPt); // echo query point if (DEBUG_ANN) { printf("Query point: "); PrintPt(std::cout, queryPt); } // search kdTree->annkSearch( queryPt, // query point k, // number of near neighbors nnIdx, // nearest neighbors (returned) dists, // distance (returned) eps); // error bound // print summary if (DEBUG_ANN) { std::cout << "\tNN:\tIndex\tDistance\n"; for (int i = 0; i < k; i++) { // unsquare distance dists[i] = sqrt(dists[i]); std::cout << "\t" << i << "\t" << nnIdx[i] << "\t" << dists[i] << std::endl; } } annDeallocPt(queryPt); return nnIdx[0]; }
void ANNCluster::doCluster(mat_f& data, grpEle_vect& grpVect, float radius) { // int ptCnt = data.size().height; int dim = data.size().width; //this is ANN implementation, but it is changed to FLANN now, please refer the updated block below float *ptWeight = new float[ptCnt]; std::vector<bool> mFlag(ptCnt,false); #ifdef __USE_ANN__ ANNpointArray ptArray = annAllocPts(ptCnt, dim); //assign point values for (int i=0; i<ptCnt; i++) { ANNpoint ptPtr = ptArray[i]; for(int j = 0; j < dim; j++){ float tmp = data(i,j); ptPtr[j] = data(i , j); } } /// ANNkd_tree kdt(ptArray, ptCnt, dim); ANNpoint queryPt = annAllocPt(dim); ANNidxArray nnIdx = new ANNidx[ptCnt]; ANNdistArray nnDist = new ANNdist[ptCnt]; int grpCounter = 0; for (int i=0; i<ptCnt; i++) { if(mFlag[i]) continue; //skip matched point for(int j = 0; j < dim; j++){ queryPt[j] = data(i,j); } int resultCnt = kdt.annkFRSearch(queryPt, radius, ptCnt, nnIdx, nnDist); std::vector<cv::Vec3f> nnPt; GrpEle ge; ge.m_gID = grpCounter++ ; for (int j=0; j < resultCnt; j++) { ANNidx idx = nnIdx[j]; mFlag[idx] = true; ANNpoint tmpNNPt = ptArray[idx]; cv::Vec3f cvPt(tmpNNPt[0], tmpNNPt[1], tmpNNPt[2]); ptWeight[j] = exp(-nnDist[j]/radius); ge.m_eMember.push_back(Element(idx,ptWeight[j])); } grpVect.push_back(ge); } annDeallocPt(queryPt); annDeallocPts(ptArray); delete [] nnDist; delete [] nnIdx; delete [] ptWeight; #else cv::flann::KDTreeIndexParams idxParams(4); cv::flann::SearchParams scParams(32); cv::flann::Index indexer(data,idxParams); std::vector<float> nnDists(dim); std::vector<int> nnInds(dim); std::vector<float> queryPt(dim); for(int i = 0; i < ptCnt; i++){ if(mFlag[i]) continue; for(int j = 0; j < dim; j++) queryPt[j] = data(i,j); int nnCnt = indexer.radiusSearch(queryPt,nnInds,nnDists,radius,scParams); GrpEle ge; for(int k = 0; k < nnCnt; k++){ int tmpIdx = nnInds[k]; float tmpDist = nnDists[k]; float tmpWeight = exp(-tmpDist/radius); ge.m_eMember.push_back(Element(tmpIdx,tmpWeight)); } grpVect.push_back(ge); } #endif }
//Should be a method inside Worker //this one both fills out the leaves and also merges all reprs in one map void replace_reprs(QNode* qb, ANNpoint* center, double side, ANNidxArray nnIdx, ANNdistArray dists) { if (qb->children == 0) { myset rs(qb->representatives[0]); if (Globals::fill) { if (rs.size() < Globals::reprs_num) { Globals::kdtree->annkSearch(center[0], Globals::reprs_num, nnIdx, dists, 0.0); for (unsigned int i=0; i<Globals::reprs_num; i++) { if ((!repr_exists(&rs, nnIdx[i])) && (rs.size()<Globals::reprs_num)) { rs.insert(nnIdx[i]); } } } } //if (qb->representatives==0) { // std::cout << "err" << std::endl; //} //This really doesn't work as expected mmm /* qb->bear_children(); for (int i=0; i<Globals::pow2dim; i++) { qb->children[0][i].representatives = qb->representatives; } qb->remove_representatives(); int it; int new_repr; ANNpoint child_center = annAllocPt(Globals::dim); for (int i=0; i<Globals::pow2dim; i++) { it = 1; for (int j=0; j<Globals::dim; j++) { if ((i&it) != 0) { child_center[j] = (*center)[j]+(side/4.0); } else { child_center[j] = (*center)[j]-(side/4.0); } it = it << 1; } //new_repr=kdtree->ann1Search(child_center,asdf); //new_repr = Globals::kdtree->annkSearch(child_center, 1, nnIdx, dists, 0.0); Globals::kdtree->annkSearch(child_center, 1, nnIdx, dists, 0.0); new_repr=nnIdx[0]; myset rs(qb->children[0][i].representatives[0]); if (rs.size() == Globals::reprs_num-1) { //remove the furthest away double mdist=0.0; double tmp_dist; myset::iterator it_rem; for (myset::iterator it = rs.begin(); it != rs.end(); it++) { tmp_dist = annDist(Globals::dim,child_center,Globals::points[*it]); if (tmp_dist > mdist) { mdist=tmp_dist; it_rem=it; } } rs.erase(it_rem); } rs.insert(new_repr); if (Globals::final_set.count(rs) == 0) Globals::final_set[rs] = new myset(rs); qb->children[0][i].representatives = Globals::final_set[rs]; }*/ if (Globals::final_set.count(rs) == 0) Globals::final_set[rs]=new myset(rs); qb->representatives = Globals::final_set[rs]; /*if (Globals::final_set.count(qb->representatives[0]) == 0) Globals::final_set[qb->representatives[0]] = new myset(qb->representatives[0]); qb->representatives = Globals::final_set[qb->representatives[0]];*/ // annDeallocPt(child_center); } else { /* This is an inner node. First we recurse to each leaf. * Notice that we need to compute the coordinates of the centers * of each child, since that information is not stored in QNode */ int it; //A local container to consume the result of our recursive calls //std::vector<Globals::QLeaf*> new_children; //Just a fancy array of arrays. We have pow2dim children and each one //needs dim coordinates to express its center ANNpoint child_center = annAllocPt(Globals::dim); for (int i=0; i<Globals::pow2dim; i++) { it = 1; for (int j=0; j<Globals::dim; j++) { if ((i&it) != 0) { child_center[j] = (*center)[j]+(side/4.0); } else { child_center[j] = (*center)[j]-(side/4.0); } it = it << 1; } replace_reprs(qb->children[0]+i, &child_center, side/2.0, nnIdx, dists); } annDeallocPt(child_center); } }
double arlCore::ICP::computeCriterion( const arlCore::vnl_rigid_matrix &M, vnl_vector< double > &fx ) { vnl_vector<double> RMS(1, 0.0), nbPoints(1, 0.0); const arlCore::vnl_rigid_matrix InvM = M.computeInverse(); unsigned int i, j, noTriangle; double n = 0.0, result = 0.0; if(m_point2PointMode) { // Points to points #ifdef ANN const unsigned int Dimension = 3; vnl_vector_fixed<double,3> traInit = InvM.getTranslation(); vnl_matrix_fixed<double,3,3> rotInit = InvM.getRotation(); const double Epsilon = 0.0;// Error bound ANNpoint Pt = annAllocPt(Dimension); // Query point for( i=0 ; i<m_cloudSize ; ++i ) { // Search the matching point for every point of cloud for( j=0 ; j<3; ++j ) Pt[j] = rotInit[j][0]*m_cloudPoints[i][0]+rotInit[j][1]*m_cloudPoints[i][1]+rotInit[j][2]*m_cloudPoints[i][2]+traInit[j]; m_ANNtree->annkSearch( Pt, m_nbNN, m_nn_idx, m_squaredDists, Epsilon ); if(fx.size()>i) fx[i] = m_squaredDists[0]; RMS[0] += m_squaredDists[0]; } annDeallocPt(Pt); n = (double)m_cloudSize; #endif // ANN }else { // Point to mesh assert(m_cloud!=0 && m_modelMesh!=0); RMS.set_size((unsigned int)m_modelMesh->getTriangles().size()); RMS.fill(0.0); nbPoints.set_size(RMS.size()); nbPoints.fill(0.0); unsigned int i; arlCore::Point::sptr point = arlCore::Point::New(3); for( i=0 ; i<m_cloud->size() ; ++i ) if(m_cloud->get(i)) if(!m_justVisible || m_cloud->get(i)->isVisible()) { InvM.trf(m_cloud->get(i), point); const double SquaredDist = m_modelMesh->computeDistance2(point, noTriangle); if(SquaredDist>0.0) { RMS[noTriangle] += SquaredDist; if(fx.size()>i) fx[i] = SquaredDist; nbPoints[noTriangle] += 1; } } } assert(nbPoints.size()==RMS.size()); if(RMS.size()==1) { if(nbPoints[0]>0) return sqrt(RMS[i]/nbPoints[i]); else return -1.0; } for( i=0 ; i<RMS.size() ; ++i ) if(nbPoints[i]>0) { result += sqrt(RMS[i]/nbPoints[i]); n += 1.0; } if(n>0) return result/n; else return -1; }
void NormalEstimator::fitNormal(){ // //compute surface normal int ptCnt = m_pt.size(); if (ptCnt <= 0) { std::cout << "no point set provided" << std::endl; return; } ANNpointArray ptArray = annAllocPts(ptCnt, 3); //assign point values for (int i=0; i<ptCnt; i++) { cv::Vec3f pt = m_pt[i]; ANNpoint ptPtr = ptArray[i]; ptPtr[0] = pt[0]; ptPtr[1] = pt[1]; ptPtr[2] = pt[2]; } /// ANNkd_tree kdt(ptArray, ptCnt, 3); ANNpoint queryPt = annAllocPt(3); int nnCnt = 100; ANNidxArray nnIdx = new ANNidx[nnCnt]; ANNdistArray nnDist = new ANNdist[nnCnt]; float sigma = -1; float evalRatio = 0.05; //estimate sigma for (int i=0; i < ptCnt; i++) { cv::Vec3f pt = m_pt[i]; queryPt[0] = pt[0]; queryPt[1] = pt[1]; queryPt[2] = pt[2]; //kdt.annkSearch(queryPt,nnCnt, nnIdx, nnDist); kdt.annkSearch(queryPt,50, nnIdx, nnDist); if (nnDist[49] < sigma ||sigma == -1 ) { sigma = nnDist[49]; } } sigma = 0.001; std::cout << "search radius:" << sigma << std::endl; std::cout << "estimating normals for point set by PCA, be patient..." << std::endl; for (int i=0; i < ptCnt; i++) { cv::Vec3f pt = m_pt[i]; queryPt[0] = pt[0]; queryPt[1] = pt[1]; queryPt[2] = pt[2]; //kdt.annkSearch(queryPt,nnCnt, nnIdx, nnDist); kdt.annkFRSearch(queryPt, sigma, nnCnt, nnIdx, nnDist); int validCnt = 0; for (int j = 0; j < nnCnt; j++) { if (nnIdx[j] == ANN_NULL_IDX) { break; } validCnt++; } //std::cout << validCnt << std::endl; if (validCnt < 3) { continue; } cv::Mat pcaVec(validCnt,3,CV_64FC1); cv::Mat pcaMean(1,3,CV_64FC1); for (int j = 0; j < validCnt; j++) { pcaVec.at<double>(j,0) = m_pt[nnIdx[j]][0]; pcaVec.at<double>(j,1) = m_pt[nnIdx[j]][1]; pcaVec.at<double>(j,2) = m_pt[nnIdx[j]][2]; } cv::PCA pca(pcaVec,cv::Mat(),CV_PCA_DATA_AS_ROW); if (pca.eigenvalues.at<double>(2,0) / pca.eigenvalues.at<double>(1,0) > evalRatio) { continue; } m_ptNorm[i] = cv::Vec3f(pca.eigenvectors.at<double>(2,0),pca.eigenvectors.at<double>(2,1),pca.eigenvectors.at<double>(2,2)); float nr = cv::norm(m_ptNorm[i]); m_ptNorm[i][0] /= nr; m_ptNorm[i][1] /= nr; m_ptNorm[i][2] /= nr; //std::cout << m_ptNorm[i][0] << " " << m_ptNorm[i][1] << " " << m_ptNorm[i][2] << std::endl; m_ptNormFlag[i] = true; } // std::cout << "done..." << std::endl; ////////////////////////////////////////////////////////////////////////// //std::cout << "correct normal direction..." << std::endl; //sigma *= 1; // //nnCnt *= 1; // ////reallocate the space for nn idx and nn dist array //delete [] nnDist; //delete [] nnIdx; //nnIdx = new ANNidx[nnCnt]; //nnDist = new ANNdist[nnCnt]; //int invertCnt = 0; //for (int i = 0; i < ptCnt; i++) //{ // if (!m_ptNormFlag[i]) // { // continue; // } // // cv::Vec3f pt = m_pt[i]; // queryPt[0] = pt[0]; // queryPt[1] = pt[1]; // queryPt[2] = pt[2]; // kdt.annkFRSearch(queryPt, sigma, nnCnt, nnIdx, nnDist); // int validCnt = 0, normConsCnt = 0, distConsCnt = 0; // for (int j = 0; j < nnCnt; j++) // { // if (nnIdx[j] == ANN_NULL_IDX) // { // break; // } // else{ // //check the direction // cv::Vec3f v1 = m_ptNorm[i]; // cv::Vec3f v2 = m_ptNorm[nnIdx[j]]; // // if (!m_ptNormFlag[nnIdx[j]]) // { // continue; // }else{ // // // validCnt++; // if( v2.ddot(v1) > 0 ) // normConsCnt++; // } // } // } // //inconsistency detected, invert the direction // if (normConsCnt / validCnt < 0.9) // { // //std::cout << "invert" << std::endl; // invertCnt++; // m_ptNorm[i] = cv::Vec3f(0,0,0) - m_ptNorm[i]; // } //} //std::cout << "# of inverted vertex:" << invertCnt << std::endl; //////////////////////////////////////////////////////////////////////////// annDeallocPt(queryPt); annDeallocPts(ptArray); delete [] nnDist; delete [] nnIdx; }
void Worker::operator()() { for (private_index=get_index(); private_index!=-1; private_index=get_index()) { {boost::mutex::scoped_lock lock(io_mutex); std::cout << "THREAD " << id << " GOT " << private_index+1 << "/" << Globals::wspd_centers.size() << std::endl;} //Find the side length, radius, radius squared and center of circle/ring for //each one of the circle/rings that I'm going to draw for (int j=0; j<=Globals::wspd_circs_num[private_index]; j++) { //1 as argument because I insert parents of leaves //This means that when I do find a square with this side, I'm going to call //bear_children method again. This essentially reduces processing time by 3/4 sides.push_back(side_discr(pow(2,j)*Globals::wspd_distances[private_index]/denominator,3));//1 // sides.push_back(side_discr(pow(2,j)*Globals::wspd_distances[private_index]/denominator,0)); //make radius an exact multiple of side radiuses.push_back(radius_discr(pow(2,j)*Globals::wspd_distances[private_index], sides[j])); radiuses_sqr.push_back(radiuses[j]*radiuses[j]); //Center of circle should fall neatly on the center of a grid square ANNpoint center = annAllocPt(Globals::dim); for (int k=0; k<Globals::dim; k++) { center[k] = center_discr(Globals::wspd_centers[private_index][k], sides[j], 0.5); } centers.push_back(center); } //first iteration is for the core, the inner circle which is completely filled //the rest of the iteration are rings, essentially 2 concentric cirles where I fill //the difference core=true; for (int circ=0; circ<=Globals::wspd_circs_num[private_index]; circ++) { //Generate all the possible values of a coordinate, based on side and radius //for example if radius is 8 and side is 2 this is going to be 0,2,4,6,8 for (ANNcoord v=0.0; v<=radiuses[circ]; v+=sides[circ]) { all_values.push_back(v); } //cart_prod_counter=0; cart_product(all_values, result, circ); if (Globals::qbs[id]->children!=0) depth_all_reprs(Globals::qbs[id]); // find_all_reprs(Globals::qbs[id], &Globals::hypercube_center, 1.0, kdtree, asdf, id); //CLEANUP all_values.clear(); core=false; } //CLEANUP radiuses.clear(); radiuses_sqr.clear(); sides.clear(); for (unsigned int d=0; d<centers.size(); d++) annDeallocPt(centers[d]); centers.clear(); } std::cout << "THREAD " << id << " DIES" << std::endl; annDeallocPt(qb_center); annDeallocPts(leaf_centers); delete[] leaf_reprs; pos_neg_result.clear(); pos_neg_final.clear(); vd1.clear(); vd2.clear(); delete asdf; delete kdtree; // delete qb; return; }