示例#1
0
double estimateMI_ANN( const RV_1<P_V,P_M>& xRV,
           const RV_2<P_V,P_M>& yRV,
           const unsigned int xDimSel[], unsigned int dimX,
           const unsigned int yDimSel[], unsigned int dimY,
           unsigned int k, unsigned int N, double eps )
{
  ANNpointArray dataXY;
  double MI_est;

  unsigned int dimXY = dimX + dimY;

  // Allocate memory
  dataXY = annAllocPts(N,dimXY);

  // Copy samples in ANN data structure
  P_V smpRV_x( xRV.imageSet().vectorSpace().zeroVector() );
  P_V smpRV_y( yRV.imageSet().vectorSpace().zeroVector() );

  for( unsigned int i = 0; i < N; i++ ) {
    // get a sample from the distribution
    xRV.realizer().realization( smpRV_x );
    yRV.realizer().realization( smpRV_y );

    // copy the vector values in the ANN data structure
    for( unsigned int j = 0; j < dimX; j++ ) {
      dataXY[ i ][ j ] = smpRV_x[ xDimSel[j] ];
    }
    for( unsigned int j = 0; j < dimY; j++ ) {
      dataXY[ i ][ dimX + j ] = smpRV_y[ yDimSel[j] ];
    }
    // annPrintPt( dataXY[i], dimXY, std::cout ); std::cout << std::endl;
  }

  MI_est = computeMI_ANN( dataXY,
        dimX, dimY,
        k, N, eps );

  // Deallocate memory
  annDeallocPts( dataXY );

  return MI_est;
}
示例#2
0
void Slave::operator()() {
  ANNpointArray child_centers = annAllocPts(Globals::pow2dim, Globals::dim);
  int it;
  for (int i=0; i<Globals::pow2dim; i++) {
    it = 1;
    for (int j=0; j<Globals::dim; j++) {
      if ((i&it) != 0) {
        child_centers[i][j] = 0.75;
      } else {
        child_centers[i][j] = 0.25;
      }
      it = it << 1;
    }
    if (i%Globals::threads_num == id) {
      //TODO make this dynamically allocate pieces to threads
      std::cout << "Thread " << id << " gets branch " << i << std::endl;
      fil_in_reprs(Globals::qb->children[0]+i,&child_centers[i],0.5);
    }
  }
  annDeallocPts(child_centers);
}
示例#3
0
//process all that shit in vectors.... very gay
void fill_vectors(QNode* qb, ANNpoint* center, double side) {
  if (qb->children == 0) {
    Globals::qt_nodes.push_back(qb);
    Globals::qt_centers.push_back(center);
    Globals::qt_sides.push_back(side);
    //std::cout << side << std::endl;
  } else {
    int it;
    ANNpointArray child_centers = annAllocPts(Globals::pow2dim, 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_centers[i][j] = (*center)[j]+(side/4.0);
        } else {
          child_centers[i][j] = (*center)[j]-(side/4.0);
        }
        it = it << 1;
      }
      fill_vectors(qb->children[0]+i,&child_centers[i],side/2.0);
    }
    annDeallocPts(child_centers);
  }
}
示例#4
0
arlCore::ICP::ICP( arlCore::PointList::csptr model, arlCore::PointList::csptr cloud, bool justVisible ):
m_point2PointMode(true),
m_modelMesh(),
m_cloud(),
m_initialization(false),
m_justVisible(justVisible),
m_modelSize(0),
m_cloudSize(0),
m_modelPoints(0),
m_cloudPoints(0),
m_Pk(0),
m_Yk(0),
m_Pi(0),
m_ANNtree(0),
m_nn_idx(0),
m_squaredDists(0),
m_maxIterations(50),
m_nbIterations(0),
m_startError(-1),
m_endError(-1)
{
    m_solution.setIdentity();
#ifdef ANN
    const unsigned int m_dimension = model->getDimension();
    assert(m_dimension==cloud->getDimension());
    m_modelGravity.set_size(m_dimension);
    m_cloudGravity.set_size(m_dimension);
    unsigned int i, j, n;
    if(justVisible) m_modelSize = model->visibleSize();
    else m_modelSize = model->size();
    if(m_modelSize<1) return;
    m_modelPoints = annAllocPts( m_modelSize, m_dimension );
    for( i=0, n=0 ; i<m_modelSize ; ++i )
        if((*model)[i])
            if(!justVisible || (justVisible && (*model)[i]->isVisible()))
            {
                for( j=0 ; j<m_dimension ; ++j )
                    m_modelPoints[n][j]=(*model)[i]->get(j);
                ++n;
            }
    m_modelSize = n;
    if(justVisible) m_cloudSize = cloud->visibleSize();
    else m_cloudSize = cloud->size();
    if(m_modelSize<1 || m_cloudSize<1)
    {
        annDeallocPts( m_modelPoints );
        m_modelPoints = 0;
        return;
    }
    m_cloudPoints = annAllocPts( m_cloudSize, m_dimension );
    for( i=0, n=0 ; i<m_cloudSize ; ++i )
        if((*cloud)[i])
            if(!justVisible || (justVisible && (*cloud)[i]->isVisible()))
            {
                for( j=0 ; j<m_dimension ; ++j )
                    m_cloudPoints[n][j]=(*cloud)[i]->get(j);
                ++n;
            }
    m_cloudSize = n;
    if(m_cloudSize<1)
    {
        annDeallocPts( m_modelPoints );
        annDeallocPts( m_cloudPoints );
        m_modelPoints = 0;
        m_cloudPoints = 0;
        return;
    }
    m_Pk = annAllocPts( m_cloudSize, m_dimension );
    m_Yk = annAllocPts( m_cloudSize, m_dimension );
    m_Pi = annAllocPts( m_cloudSize, m_dimension );
    const int BucketSize = 1;
    m_ANNtree = new ANNkd_tree( m_modelPoints, m_modelSize, m_dimension, BucketSize, ANN_KD_SL_MIDPT );
    m_nbNN = 1;
    m_nn_idx = new ANNidx[m_nbNN];
    m_squaredDists = new ANNdist[m_nbNN];
#endif // ANN
}
示例#5
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
}
示例#6
0
void carveHole(GRegion *gr, int num, double distance, std::vector<int> &surfaces)
{
  Msg::Info("Carving hole %d from surface %d at distance %g", num, surfaces[0], distance);
  GModel *m = gr->model();

  // add all points from carving surfaces into kdtree
  int numnodes = 0;
  for(unsigned int i = 0; i < surfaces.size(); i++){
    GFace *gf = m->getFaceByTag(surfaces[i]);
    if(!gf){
      Msg::Error("Unknown carving surface %d", surfaces[i]);
      return;
    }
    numnodes += gf->mesh_vertices.size();
  }

  ANNpointArray kdnodes = annAllocPts(numnodes, 3);
  int k = 0;
  for(unsigned int i = 0; i < surfaces.size(); i++){
    GFace *gf = m->getFaceByTag(surfaces[i]);
    for(unsigned int j = 0; j < gf->mesh_vertices.size(); j++){
      kdnodes[k][0] = gf->mesh_vertices[j]->x();
      kdnodes[k][1] = gf->mesh_vertices[j]->y();
      kdnodes[k][2] = gf->mesh_vertices[j]->z();
      k++;
    }
  }
  ANNkd_tree *kdtree = new ANNkd_tree(kdnodes, numnodes, 3);

  // remove the volume elements that are within 'distance' of the
  // carved surface
  carveHole(gr->tetrahedra, distance, kdtree);
  carveHole(gr->hexahedra, distance, kdtree);
  carveHole(gr->prisms, distance, kdtree);
  carveHole(gr->pyramids, distance, kdtree);

  delete kdtree;
  annDeallocPts(kdnodes);

  // TODO: remove any interior elements left inside the carved surface
  // (could shoot a line from each element's barycenter and count
  // intersections o see who's inside)

  // generate discrete boundary mesh of the carved hole
  GFace *gf = m->getFaceByTag(num);
  if(!gf) return;
  std::set<MFace, Less_Face> faces;
  std::list<GFace*> f = gr->faces();
  for(std::list<GFace*>::iterator it = f.begin(); it != f.end(); it++){
    addFaces((*it)->triangles, faces);
    addFaces((*it)->quadrangles, faces);
  }
  addFaces(gr->tetrahedra, faces);
  addFaces(gr->hexahedra, faces);
  addFaces(gr->prisms, faces);
  addFaces(gr->pyramids, faces);

  std::set<MVertex*> verts;
  for(std::set<MFace, Less_Face>::iterator it = faces.begin(); it != faces.end(); it++){
    for(int i = 0; i < it->getNumVertices(); i++){
      it->getVertex(i)->setEntity(gf);
      verts.insert(it->getVertex(i));
    }
    if(it->getNumVertices() == 3)
      gf->triangles.push_back(new MTriangle(it->getVertex(0), it->getVertex(1),
                                            it->getVertex(2)));
    else if(it->getNumVertices() == 4)
      gf->quadrangles.push_back(new MQuadrangle(it->getVertex(0), it->getVertex(1),
                                                it->getVertex(2), it->getVertex(3)));
  }
}
示例#7
0
// cd L:\ann_mwrapper; Untitled2
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
   
	mwSize dims[3];
	char command[1024];
	int strlen = mxGetN(prhs[0]);
	strlen = strlen < mxGetM(prhs[0]) ? mxGetN(prhs[0]) : strlen;
	strlen += 1;
	mxGetString (prhs[0], command, strlen);

	// Initialize tree
	if (nrhs > 0 && !strcmp(command, "createKdTree")) {

		const mxArray *mxRefPts = prhs[1];
		const mxArray *mxOpts = prhs[2];
    
		// parse options    
		AnnBuildOptions opts_build;
	    
		parse_tree_building_options(mxOpts, opts_build);
	            
		// construct the tree
		int d = 0;
		int n = 0;
		ANNpointArray *pts = createPointArray(mxRefPts, d, n);
		ANNkd_tree *kd_tree = createKdTree(d, n, pts[0], opts_build);

		//mexPrintf("%lld\n", kd_tree);
		//mexPrintf("dim = %d\n", kd_tree->theDim());

		dims[0] = 2;
		dims[1] = 1;
		plhs[0] = mxCreateNumericArray(2,dims,mxUINT64_CLASS,mxREAL);
		((unsigned long long *)(mxGetData( plhs[0])))[0] = (unsigned long long)kd_tree;
		((unsigned long long *)(mxGetData( plhs[0])))[1] = (unsigned long long)pts;
//         mexPrintf("Creating:\n");
//         mexPrintf("Pts: ");
//         for (int i =0;i<MEX_DEBUG_WND;++i){
//             mexPrintf("%x",pts[i]);
//         }
//         mexPrintf("\n");
//         mexPrintf("kdTree: ");
//         for (int i =0;i<10;++i){
//             mexPrintf("%x",((char *)kd_tree)[i]);
//         }
//         mexPrintf("\n");
	}

	// Search
	else if (nrhs > 0 && !strcmp(command, "performAnnkSearch")) {

		// take inputs
		const mxArray *mxQuery = prhs[2];
		const mxArray *mxOpts = prhs[3];
	    
		// parse options    
		AnnSearchOptions opts_search;
	    
		parse_search_options(mxOpts, opts_search);
	            
		// get pointer to tree
		ANNkd_tree *kd_tree = (ANNkd_tree *)(((unsigned long long *)mxGetData( prhs[1]))[0]);

//		mexPrintf("%lld\n", kd_tree);
//		mexPrintf("dim = %d\n", kd_tree->theDim());
	    
		// perform the search
		mxArray *mxInds = NULL;
		mxArray *mxDists = NULL;
//         mexPrintf("Pts: ");
//         for (int i =0;i<MEX_DEBUG_WND;++i){
//             mexPrintf("%x",pts[i]);
//         }
//         mexPrintf("\n");
//         mexPrintf("kdTree: ");
//         for (int i =0;i<10;++i){
//             mexPrintf("%x",((char *)kd_tree)[i]);
//         }
//         mexPrintf("\n");
// 
        performAnnkSearch(kd_tree, mxQuery, opts_search, mxInds, mxDists);
	    
		// set outputs
	    plhs[0] = mxInds;
		plhs[1] = mxDists;

	}

	// Deinitialize tree
	else if (nrhs > 0 && !strcmp(command, "deleteKdTree")) {
	
		ANNkd_tree *kd_tree = (ANNkd_tree *)(((unsigned long long *)mxGetData( prhs[1]))[0]);
		ANNpointArray *pts  = (ANNpointArray *)(((unsigned long long *)mxGetData( prhs[1]))[1]);
//         mexPrintf("Deleting:\n");
//         mexPrintf("Pts: ");
//         for (int i =0;i<MEX_DEBUG_WND;++i){
//             mexPrintf("%x",pts[i]);
//         }
//         mexPrintf("\n");
//         mexPrintf("kdTree: ");
//         for (int i =0;i<10;++i){
//             mexPrintf("%x",((char *)kd_tree)[i]);
//         }
//         mexPrintf("\n");

		// release the kd-tree
	    delete kd_tree;
	    annDeallocPts(pts[0]);
		delete pts;

	}

	// Close
	else if (nrhs > 0 && !strcmp(command, "annClose")) {
	
		annClose();
		
	}

	else {

		mexPrintf("INVALID COMMAND %s\n", command);
		return;

	}
    
    
}
示例#8
0
double estimateCE_ANN( RV_1<P_V,P_M>& xRV,
           RV_2<P_V,P_M>& yRV,
           unsigned int xDimSel[], unsigned int dimX,
           unsigned int yDimSel[], unsigned int dimY,
           unsigned int xN, unsigned int yN,
           unsigned int k, double eps )
{
  ANNpointArray dataX;
  ANNpointArray dataY;
  double* distsXY;
  double CE_est;
  ANNkd_tree* kdTree;

  // sanity check
  if( dimX != dimY ) {
    queso_error_msg("Error-CE: the dimensions should agree");
  }

  // Allocate memory
  dataX = annAllocPts( xN, dimX );
  dataY = annAllocPts( yN, dimY );
  distsXY = new double[xN];
  kdTree = new ANNkd_tree( dataY, yN, dimY );

  // Copy X samples in ANN data structure
  P_V xSmpRV( xRV.imageSet().vectorSpace().zeroVector() );
  for( unsigned int i = 0; i < xN; i++ ) {
    // get a sample from the distribution
    xRV.realizer().realization( xSmpRV );
    // copy the vector values in the ANN data structure
    for( unsigned int j = 0; j < dimX; j++ ) {
      dataX[ i ][ j ] = xSmpRV[ xDimSel[j] ];
    }
  }

  // Copy Y samples in ANN data structure
  P_V ySmpRV( yRV.imageSet().vectorSpace().zeroVector() );
  for( unsigned int i = 0; i < yN; i++ ) {
    // get a sample from the distribution
    yRV.realizer().realization( ySmpRV );
    // copy the vector values in the ANN data structure
    for( unsigned int j = 0; j < dimY; j++ ) {
      dataY[ i ][ j ] = ySmpRV[ yDimSel[j] ];
    }
  }

  // Get distance to knn for each point
  distANN_XY( dataX, dataY, distsXY, dimX, dimY, xN, yN, k, eps );
  kdTree = new ANNkd_tree( dataY, yN, dimY );

  // Compute cross entropy estimate
  double sum_log = 0.0;
  for( unsigned int i = 0; i < xN; i++ )
    {
      sum_log += log( distsXY[i] );
    }
  CE_est = (double)dimX/(double)xN * sum_log + log( (double)yN ) - gsl_sf_psi_int( k );

  // Deallocate memory
  annDeallocPts( dataX );
  annDeallocPts( dataY );
  delete [] distsXY;

  return CE_est;
}
示例#9
0
double estimateKL_ANN( RV_1<P_V,P_M>& xRV,
           RV_2<P_V,P_M>& yRV,
           unsigned int xDimSel[], unsigned int dimX,
           unsigned int yDimSel[], unsigned int dimY,
           unsigned int xN, unsigned int yN,
           unsigned int k, double eps )
{
  ANNpointArray dataX;
  ANNpointArray dataY;
  double* distsX;
  double* distsXY;
  double KL_est;

  // sanity check
  if( dimX != dimY ) {
    queso_error_msg("Error-KL: the dimensions should agree");
  }

  // Allocate memory
  dataX = annAllocPts( xN, dimX );
  dataY = annAllocPts( yN, dimY );
  distsX = new double[xN];
  distsXY = new double[xN];

  // Copy X samples in ANN data structure
  P_V xSmpRV( xRV.imageSet().vectorSpace().zeroVector() );
  for( unsigned int i = 0; i < xN; i++ ) {
    // get a sample from the distribution
    xRV.realizer().realization( xSmpRV );
    // copy the vector values in the ANN data structure
    for( unsigned int j = 0; j < dimX; j++ ) {
      dataX[ i ][ j ] = xSmpRV[ xDimSel[j] ];
    }
  }

  // Copy Y samples in ANN data structure
  P_V ySmpRV( yRV.imageSet().vectorSpace().zeroVector() );
  for( unsigned int i = 0; i < yN; i++ ) {
    // get a sample from the distribution
    yRV.realizer().realization( ySmpRV );
    // copy the vector values in the ANN data structure
    for( unsigned int j = 0; j < dimY; j++ ) {
      dataY[ i ][ j ] = ySmpRV[ yDimSel[j] ];
    }
  }

  // Get distance to knn for each point
  distANN_XY( dataX, dataX, distsX, dimX, dimX, xN, xN, k+1, eps ); // k+1 because the 1st nn is itself
  distANN_XY( dataX, dataY, distsXY, dimX, dimY, xN, yN, k, eps );

  // Compute KL-divergence estimate
  double sum_log_ratio = 0.0;
  for( unsigned int i = 0; i < xN; i++ )
    {
      sum_log_ratio += log( distsXY[i] / distsX[i] );
    }
  KL_est = (double)dimX/(double)xN * sum_log_ratio + log( (double)yN / ((double)xN-1.0 ) );

  // Deallocate memory
  annDeallocPts( dataX );
  annDeallocPts( dataY );
  delete [] distsX;
  delete [] distsXY;

  return KL_est;
}
示例#10
0
	KNNClassifier::~KNNClassifier()
	{
		annDeallocPts(dataPts);
		delete kdTree;
		annClose();
	}
示例#11
0
// release the ANN point array allocated
void ReleaseANNPointArray(ANNpointArray pts)
{
    annDeallocPts(pts);
}
示例#12
0
  myset* Slave::fil_in_reprs(QNode* qb, ANNpoint* center, double side) {
    if ((qb->depth == 0) && (qb->children == 0)) {
      //time to fill in the reprs my dear!
      //if (qb->representatives != 0) {
      //}
      myset rs;
      rs.insert(kdtree->ann1Search(*center,asdf));

//      {boost::mutex::scoped_lock lock(thread_mutex);
      if (Globals::final_set.count(rs) == 0) {
        qb->representatives = new myset(rs);
        Globals::final_set[rs] = qb->representatives;
      } else {
        qb->representatives = Globals::final_set[rs];
      }
//      }
      return qb->representatives;
    } else {
      if (qb->depth != 0) {
        qb->bear_children();
        for (int i=0; i<Globals::pow2dim; i++) {
          qb->children[0][i].depth = qb->depth-1;
        }
        qb->depth=0;
      }
  
      myset union_reprs;
      int it;
      //A local container to consume the result of our recursive calls
      //std::vector<Globals::QLeaf*> new_children;
      myset* new_children[Globals::pow2dim];
      //recurse to children
      ANNpointArray child_centers = annAllocPts(Globals::pow2dim, 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_centers[i][j] = (*center)[j]+(side/4.0);
          } else {
            child_centers[i][j] = (*center)[j]-(side/4.0);
          }
          it = it << 1;
        }
        new_children[i] = fil_in_reprs(qb->children[0]+i,&child_centers[i],side/2.0);
      }
      annDeallocPts(child_centers);
      leaves_count = 0;
      //check every child and insert union all reprs 
      for (int i=0; i<Globals::pow2dim; i++) {
        if (new_children[i] != 0) {
          leaves_count++;
          //std::set doesn't have a [] operator. Instead we use the iterators
          for (myset::iterator it = (*new_children[i]).begin();
               it != (*new_children[i]).end();
               ++it) {
            union_reprs.insert(*it);
          }
        }
      }
      if ((leaves_count == Globals::pow2dim) && (union_reprs.size() <= Globals::reprs_num)) {
        //Create the leaf and transfer the new set of representatives

        //{boost::mutex::scoped_lock lock(thread_mutex);
        if (Globals::final_set.count(union_reprs) == 0) {
          //implies there are no reprs in this node.
          Globals::final_set[union_reprs] = new myset(union_reprs);
        }
        qb->representatives = Globals::final_set[union_reprs];
        //}
        qb->remove_children();
        return qb->representatives;
      } else {
        return 0;
      }
    }
  }
示例#13
0
//Should be a method inside Worker
myset* find_all_reprs(QNode* qb, ANNpoint* center, double side, ANNkd_tree* kdtree, ANNmin_k* asdf, int id) {
  if (qb->children == 0) {
    /* If the current node has no children, it's a leaf. Therefore we need
     * to calculate a number of representatives and return a QLeaf_tmp
     */
    if (qb->representatives == 0) {
      //std::cout << "UNOREPRS" << std::endl;
      //COPY
      myset rs;
      rs.insert(kdtree->ann1Search(*center,asdf));
      if (Globals::sets[id].count(rs) == 0) {
        qb->representatives = new myset(rs);
        Globals::sets[id][rs] = qb->representatives;
      } else {
        qb->representatives = Globals::sets[id][rs];
      }
      //exit(0);
    }
    return qb->representatives;
  } 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
     */
    myset union_reprs;
    int it;
    //A local container to consume the result of our recursive calls
    //std::vector<Globals::QLeaf*> new_children;
    myset* new_children[Globals::pow2dim];
    //Just a fancy array of arrays. We have pow2dim children and each one
    //needs dim coordinates to express its center
    ANNpointArray child_centers = annAllocPts(Globals::pow2dim, 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_centers[i][j] = (*center)[j]+(side/4.0);
        } else {
          child_centers[i][j] = (*center)[j]-(side/4.0);
        }
        it = it << 1;
      }
      new_children[i] = find_all_reprs(qb->children[0]+i,&child_centers[i],side/2.0, kdtree, asdf, id);
    }
    annDeallocPts(child_centers);
    //We now have a vector of size pow2dim, full of QNode and QLeaf_tmp
    //Count the leaves and at the same time take the union of their
    //representatives
    leaves_count = 0;
    //union_reprs.clear();
    //check every child and insert union all reprs 
    for (int i=0; i<Globals::pow2dim; i++) {
      if (new_children[i] != 0) {
        leaves_count++;
        //std::set doesn't have a [] operator. Instead we use the iterators
        for (myset::iterator it = (*new_children[i]).begin();
             it != (*new_children[i]).end();
             ++it) {
          union_reprs.insert(*it);
        }
      }
    }

    //if all children are leaves and the union of all representatives is not
    //bigger than max, I can merge all leaves into one and return that
    if ((leaves_count == Globals::pow2dim) && (union_reprs.size() <= Globals::reprs_num)) {
      //Create the leaf and transfer the new set of representatives
//      if (qb->representatives !=0) {
//      std::cout << "halp" << std::endl;
//      }
      if (Globals::sets[id].count(union_reprs) == 0) {
        //implies there are no reprs in this node.
        Globals::sets[id][union_reprs] = new myset(union_reprs);
      }
      qb->representatives = Globals::sets[id][union_reprs];
      qb->remove_children();
      return qb->representatives;
    } else {
      return 0;
    }
  }
}
void SymmetryDetection::detect_reflectional_symmetry(
    const Eigen::MatrixXd &_sparse_points,
    const Eigen::MatrixXd &_dense_points,
    const double &_inlier_dist, const double &_inlier_ratio,
    std::list<ReflectionPlane> &_reflection_planes)
{
    const unsigned int dimension = 3;
    assert(_sparse_points.rows() == dimension);
    assert(_dense_points.rows() == dimension);
    assert(_inlier_ratio > 0.0);
    assert(_inlier_ratio < 1.0);

    _reflection_planes.clear();
    const unsigned int num_sparse_points = _sparse_points.cols();
    const unsigned int num_dense_points = _dense_points.cols();

    ANNpointArray sparse_ann_points;
    ANNkd_tree* sparse_kd_tree = ICP::create_kd_tree(_sparse_points, sparse_ann_points);

    const unsigned int num_iteration = 1000;

    static SimpleRandomCong_t rng_cong;
    // seed = num_iteration.
    simplerandom_cong_seed(&rng_cong, num_iteration);

    for (unsigned int iteration = 0; iteration < num_iteration; ++iteration)
    {
        double sparse_index_1 = simplerandom_cong_next(&rng_cong) % num_sparse_points;
        double sparse_index_2 = simplerandom_cong_next(&rng_cong) % num_sparse_points;

        Eigen::VectorXd sparse_point_1 = _sparse_points.col(sparse_index_1);
        Eigen::VectorXd sparse_point_2 = _sparse_points.col(sparse_index_2);

        ReflectionPlane reflection_plane;

        reflection_plane.normal_ = sparse_point_2 - sparse_point_1;
        reflection_plane.normal_.normalize();
        reflection_plane.point_ = 0.5 * (sparse_point_1 + sparse_point_2);

        Eigen::MatrixXd symmetric_sparse_points = get_symmetric_point(
                    reflection_plane.normal_, reflection_plane.point_, _sparse_points);

        Eigen::VectorXd sparse_distances;
        ICP::get_closest_points(sparse_kd_tree, symmetric_sparse_points, sparse_distances);
        unsigned int num_sparse_inliers = (sparse_distances.array() <= _inlier_dist).count();

        if (static_cast<double>(num_sparse_inliers) / num_sparse_points >= _inlier_ratio)
        {
            reflection_plane.inlier_indices_.clear();
            for (unsigned int i = 0; i < num_sparse_points; ++i)
                if (sparse_distances[i] < _inlier_dist)
                    reflection_plane.inlier_indices_.push_back(i);

            _reflection_planes.push_back(reflection_plane);

            std::cout << "Reflection plane detected [" << _reflection_planes.size() << "]:" << std::endl;
            std::cout << " - # of inliers = (" << num_sparse_inliers << " / " << num_sparse_points << ")" << std::endl;
            std::cout << " - Normal = (" << reflection_plane.normal_.transpose() << ")" << std::endl;
            std::cout << " - Point = (" << reflection_plane.point_.transpose() << ")" << std::endl;
            std::cout << std::endl;
        }
    }

    annDeallocPts(sparse_ann_points);
    delete sparse_kd_tree;
}
示例#15
0
KMeans::~KMeans() {
    if (kd_tree_)
        delete kd_tree_;
	if (ann_points_)
		annDeallocPts( ann_points_ );
}
示例#16
0
FeatureSearch::~FeatureSearch()
{
    annDeallocPts( m_pointArray );
    delete m_tree;
}
示例#17
0
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;

}
示例#18
0
  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;
  }