//
//	Find k Nearest Centroid Neighbors 
//
//	Input: list of precomputed distances for given sample
//	Output: list of k nearest centroid neighbors
//
//	sorted list of k NNs (ascending, smallest first)
//	initialize with max float
//	first kNCN (is equal to kNN)
//	instead of comparing current kNCN candidate to already chosen kNCNs
//	distsSize times in loop, 
//	we set the distance to FLT_MAX for chosen kNCN sample in distances once
//	this excludes first kNCN from being chosen again
//	this action will be repeated for the rest 
//	distances[nndists[0].sampleIndex].distValue = FLT_MAX;
//	check if given sample is not kNCN already
//
void Parallel_kNCN::findkNCN(const SampleSet& trainSet, const Sample& testSample,
	Distance* testSampleDists, Distance* testSampleNNdists, const int k) {
	int trainSetNrDims = trainSet.nrDims;

	SampleSet centroids(trainSet.nrClasses, trainSetNrDims, k);
	for (int centroidIndex = 0; centroidIndex < k; centroidIndex++) {
		centroids[centroidIndex].nrDims = trainSetNrDims;
		centroids[centroidIndex].dims = allocateSampleDimsMemory(trainSetNrDims, __FILE__, __LINE__);
	}
#if defined SSE
	int registersNumber = ((trainSet.nrDims-1) >> 2) + 1;
	union xmmregister
	{
		__m128 m;
		DistanceValue f[4];
	} result;
Example #2
0
CollOfVector EquelleRuntimeCPU::centroid(const CollOfCell& cells) const
{
    const int n = cells.size();
    const int dim = grid_.dimensions;
    Eigen::Array<double, Eigen::Dynamic, Eigen::Dynamic, Eigen::ColMajor> c(n, dim);
    for (int i = 0; i < n; ++i) {
        const double* fc = grid_.cell_centroids + dim * cells[i].index;
        for (int d = 0; d < dim; ++d) {
            c(i, d) = fc[d];
        }
    }
    CollOfVector centroids(dim);
    for (int d = 0; d < dim; ++d) {
        centroids.col(d) = CollOfScalar(c.col(d));
    }
    return centroids;
}
    void ConvexConnectedVoxels::cloud_cb(
       const sensor_msgs::PointCloud2::ConstPtr &cloud_msg)
    {
       // JSK_ROS_INFO("PROCESSING CLOUD CALLBACK");
       
       // boost::mutex::scoped_lock lock(this->mutex_);
       // vital_checker_->poke();
       pcl::PointCloud<PointT>::Ptr cloud (new pcl::PointCloud<PointT>);
       pcl::fromROSMsg(*cloud_msg, *cloud);
       std::vector<pcl::PointCloud<PointT>::Ptr> cloud_clusters;
       std::vector<pcl::PointCloud<pcl::Normal>::Ptr> normal_clusters;
       pcl::PointCloud<pcl::PointXYZ>::Ptr centroids(
          new pcl::PointCloud<pcl::PointXYZ>);
       this->segmentCloud(
          cloud, this->indices_, cloud_clusters, normal_clusters, centroids);
       std::vector<std::vector<int> > neigbour_idx;
       this->nearestNeigborSearch(centroids, neigbour_idx, 4);
       boost::shared_ptr<jsk_pcl_ros::RegionAdjacencyGraph> rag(
          new jsk_pcl_ros::RegionAdjacencyGraph);
       rag->generateRAG(
          cloud_clusters,
          normal_clusters,
          centroids,
          neigbour_idx,
          rag->RAG_EDGE_WEIGHT_CONVEX_CRITERIA);
       rag->splitMergeRAG(0.0);
       std::vector<int> labelMD;
       rag->getCloudClusterLabels(labelMD);
       std::map<int, pcl::PointIndices> _indices;
       this->getConvexLabelCloudIndices(
          cloud_clusters, cloud, labelMD, _indices);
       std::vector<pcl::PointIndices> all_indices;
       for (std::map<int, pcl::PointIndices>::iterator it = _indices.begin();
            it != _indices.end(); it++) {
          all_indices.push_back((*it).second);
       }

       // JSK_ROS_INFO("Size: %ld", _indices.size());

       jsk_recognition_msgs::ClusterPointIndices ros_indices;
       ros_indices.cluster_indices = pcl_conversions::convertToROSPointIndices(
          all_indices, cloud_msg->header);
       ros_indices.header = cloud_msg->header;
       pub_indices_.publish(ros_indices);
    }
Example #4
0
	bool CNearestCentroid::train_machine(CFeatures* data)
	{
		ASSERT(m_labels);
		ASSERT(distance);
		ASSERT( data->get_feature_class() == C_DENSE)
		if (data)
		{
			if (m_labels->get_num_labels() != data->get_num_vectors())
				SG_ERROR("Number of training vectors does not match number of labels\n");
			distance->init(data, data);
		}
		else
		{
			data = distance->get_lhs();
		}
		int32_t num_vectors = data->get_num_vectors();
		int32_t num_classes = m_labels->get_num_classes();
		int32_t num_feats = ((CDenseFeatures<float64_t>*)data)->get_num_features();
		SGMatrix<float64_t> centroids(num_feats,num_classes);
		centroids.zero();

		m_centroids->set_num_features(num_feats);
		m_centroids->set_num_vectors(num_classes);
		
		int64_t* num_per_class = new int64_t[num_classes];
		for(int32_t i=0 ; i<num_classes ; i++)
		{
			num_per_class[i]=0;
		}
		
		for(int32_t idx=0 ; idx<num_vectors ; idx++)
		{
			int32_t current_len;
			bool current_free;
			int32_t current_class = m_labels->get_label(idx);
			float64_t* target = centroids.matrix + num_feats*current_class;
			float64_t* current = ((CDenseFeatures<float64_t>*)data)->get_feature_vector(idx,current_len,current_free);
			CMath::add(target,1.0,target,1.0,current,current_len);
			num_per_class[current_class]++;
			((CDenseFeatures<float64_t>*)data)->free_feature_vector(current, current_len, current_free);
		}


		for(int32_t i=0 ; i<num_classes ; i++)
		{
			float64_t* target = centroids.matrix + num_feats*i;
			int32_t total = num_per_class[i];
			float64_t scale = 0;
			if(total>1)
				scale = 1.0/((float64_t)(total-1));
			else
				scale = 1.0/(float64_t)total;
				
			CMath::scale_vector(scale,target,num_feats);
		}
				
		m_centroids->free_feature_matrix();
		m_centroids->set_feature_matrix(centroids);
		
		
		m_is_trained=true;
		distance->init(m_centroids,distance->get_rhs());
		
		delete [] num_per_class;
		
		return true;
	}
double PellegMooreKMeansRules<MetricType, TreeType>::Score(
    const size_t /* queryIndex */,
    TreeType& referenceNode)
{
  // Obtain the parent's blacklist.  If this is the root node, we'll start with
  // an empty blacklist.  This means that after each iteration, we don't need to
  // reset any statistics.
  if (referenceNode.Parent() == NULL ||
      referenceNode.Parent()->Stat().Blacklist().n_elem == 0)
    referenceNode.Stat().Blacklist().zeros(centroids.n_cols);
  else
    referenceNode.Stat().Blacklist() =
        referenceNode.Parent()->Stat().Blacklist();

  // The query index is a fake index that we won't use, and the reference node
  // holds all of the points in the dataset.  Our goal is to determine whether
  // or not this node is dominated by a single cluster.
  const size_t whitelisted = centroids.n_cols -
      arma::accu(referenceNode.Stat().Blacklist());

  distanceCalculations += whitelisted;

  // Which cluster has minimum distance to the node?
  size_t closestCluster = centroids.n_cols;
  double minMinDistance = DBL_MAX;
  for (size_t i = 0; i < centroids.n_cols; ++i)
  {
    if (referenceNode.Stat().Blacklist()[i] == 0)
    {
      const double minDistance = referenceNode.MinDistance(centroids.col(i));
      if (minDistance < minMinDistance)
      {
        minMinDistance = minDistance;
        closestCluster = i;
      }
    }
  }

  // Now, for every other whitelisted cluster, determine if the closest cluster
  // owns the point.  This calculation is specific to hyperrectangle trees (but,
  // this implementation is specific to kd-trees, so that's okay).  For
  // circular-bound trees, the condition should be simpler and can probably be
  // expressed as a comparison between minimum and maximum distances.
  size_t newBlacklisted = 0;
  for (size_t c = 0; c < centroids.n_cols; ++c)
  {
    if (referenceNode.Stat().Blacklist()[c] == 1 || c == closestCluster)
      continue;

    // This algorithm comes from the proof of Lemma 4 in the extended version
    // of the Pelleg-Moore paper (the CMU tech report, that is).  It has been
    // adapted for speed.
    arma::vec cornerPoint(centroids.n_rows);
    for (size_t d = 0; d < referenceNode.Bound().Dim(); ++d)
    {
      if (centroids(d, c) > centroids(d, closestCluster))
        cornerPoint(d) = referenceNode.Bound()[d].Hi();
      else
        cornerPoint(d) = referenceNode.Bound()[d].Lo();
    }

    const double closestDist = metric.Evaluate(cornerPoint,
        centroids.col(closestCluster));
    const double otherDist = metric.Evaluate(cornerPoint, centroids.col(c));

    distanceCalculations += 3; // One for cornerPoint, then two distances.

    if (closestDist < otherDist)
    {
      // The closest cluster dominates the node with respect to the cluster c.
      // So we can blacklist c.
      referenceNode.Stat().Blacklist()[c] = 1;
      ++newBlacklisted;
    }
  }

  if (whitelisted - newBlacklisted == 1)
  {
    // This node is dominated by the closest cluster.
    counts[closestCluster] += referenceNode.NumDescendants();
    newCentroids.col(closestCluster) += referenceNode.NumDescendants() *
        referenceNode.Stat().Centroid();

    return DBL_MAX;
  }

  // Perform the base case here.
  for (size_t i = 0; i < referenceNode.NumPoints(); ++i)
  {
    size_t bestCluster = centroids.n_cols;
    double bestDistance = DBL_MAX;
    for (size_t c = 0; c < centroids.n_cols; ++c)
    {
      if (referenceNode.Stat().Blacklist()[c] == 1)
        continue;

      ++distanceCalculations;

      // The reference index is the index of the data point.
      const double distance = metric.Evaluate(centroids.col(c),
          dataset.col(referenceNode.Point(i)));

      if (distance < bestDistance)
      {
        bestDistance = distance;
        bestCluster = c;
      }
    }

    // Add to resulting centroid.
    newCentroids.col(bestCluster) += dataset.col(referenceNode.Point(i));
    ++counts(bestCluster);
  }

  // Otherwise, we're not sure, so we can't prune.  Recursion order doesn't make
  // a difference, so we'll just return a score of 0.
  return 0.0;
}
Example #6
0
template <template <typename> class Storage> bool
pcl_cuda::MultiRandomSampleConsensus<Storage>::computeModel (int debug_verbosity_level)
{
  // Warn and exit if no threshold was set
  if (threshold_ == DBL_MAX)
  {
    std::cerr << "[pcl_cuda::MultiRandomSampleConsensus::computeModel] No threshold set!" << std::endl;
    return (false);
  }

  // compute number of points
  int nr_points = sac_model_->getIndices ()->size ();
  int nr_remaining_points = nr_points;
  //std::cerr << "nr_points = " << nr_points << std::endl;
  // number of total iterations
  unsigned int cur_iteration = 0;
  // number of valid iterations
  int valid_iterations = 0;
  // each batch has a vector of plane coefficients (float4)
  std::vector<Hypotheses> h(max_batches_);
  std::vector<typename Storage<int>::type> h_samples (max_batches_);
  std::vector<float3> centroids (max_batches_ * iterations_per_batch_);
  // current batch number
  int cur_batch = 0;
  //// stencil vector that holds the current inliers
  std::vector<IndicesPtr> hypotheses_inliers_stencils (max_batches_ * iterations_per_batch_);
  std::vector<int> hypotheses_inlier_count (max_batches_ * iterations_per_batch_);
  // initialize some things
  all_inliers_.clear ();
  all_model_coefficients_.clear ();
  all_model_centroids_.clear ();
  int n_inliers_count = 0;
  int n_best_inliers_count = 0;
  int good_coeff = -1;
  float k = max_batches_ * iterations_per_batch_;

    //thrust::host_vector<float3> host_points = sac_model_->getInputCloud()->points;
    //std::cerr << "Input Points:" << std::endl;
    //for (unsigned int print_iter = 0; print_iter < nr_points; ++print_iter)
    //{
    //  std::cerr << print_iter << " : [ " 
    //    << host_points[print_iter].x << ", "
    //    << host_points[print_iter].y << ", "
    //    << host_points[print_iter].z << " ]" << std::endl;
    //}

  ScopeTime t ("ALLLLLLLLLLL");
  do  // multiple models ..
  {
    thrust::host_vector<int> host_samples;
    thrust::host_vector<float4> host_coeffs;
    // make sure that sac_model_->indices_ only contains remaining point indices
    sac_model_->getIndices ();

    // generate a new batch of hypotheses
    {
      ScopeTime t ("generateModelHypotheses");
      sac_model_->generateModelHypotheses (h[cur_batch], h_samples[cur_batch], iterations_per_batch_);
    }
    host_samples = h_samples[cur_batch];
    host_coeffs = h[cur_batch];

    if (debug_verbosity_level > 1)
    {
      std::cerr << "Samples / Coefficients:" << std::endl;
      for (unsigned int print_iter = 0; print_iter < iterations_per_batch_; ++print_iter)
      {
        std::cerr << host_samples[print_iter] << " : [ " 
          << host_coeffs[print_iter].x << ", "
          << host_coeffs[print_iter].y << ", "
          << host_coeffs[print_iter].z << ", "
          << host_coeffs[print_iter].w << std::endl;
      }
    }

    std::vector<bool> hypothesis_valid (max_batches_ * iterations_per_batch_, true);

    // evaluate each hypothesis in this batch
    {
      ScopeTime t ("evaluate");
    for (unsigned int i = 0; i < iterations_per_batch_; i++, cur_iteration ++, valid_iterations ++)
    {
      // hypothesis could be invalid because it's initial sample point was inlier previously
      if (!hypothesis_valid[cur_batch * iterations_per_batch_ + i])
      {
        hypotheses_inlier_count[cur_iteration] = 0;
        valid_iterations --;
        continue;
      }

      // compute inliers for each model
      IndicesPtr inl_stencil;
      {
        ScopeTime t ("selectWithinDistance");
		int d_cur_penalty = 0;
        n_inliers_count = sac_model_->selectWithinDistance (h[cur_batch], i, threshold_, inl_stencil, centroids[cur_iteration], d_cur_penalty);
      }
      // store inliers and inlier count
      if (n_inliers_count < min_nr_in_shape)
      {
        n_inliers_count = 0;
        inl_stencil.reset (); // release stencil
        hypothesis_valid[cur_batch * iterations_per_batch_ + i] = false;
      }
      
      hypotheses_inliers_stencils[cur_iteration] = inl_stencil;
      hypotheses_inlier_count[cur_iteration] = n_inliers_count;
      
      // Better match ?
      if (n_inliers_count > n_best_inliers_count)
      {
        n_best_inliers_count = n_inliers_count;
        good_coeff = cur_iteration;

        // Compute the k parameter (k=log(z)/log(1-w^n))
        float w = (float)((float)n_best_inliers_count / (float)nr_remaining_points);
        float p_no_outliers = 1.0f - pow (w, 1.0f);
        p_no_outliers = (std::max) (std::numeric_limits<float>::epsilon (), p_no_outliers);       // Avoid division by -Inf
        p_no_outliers = (std::min) (1.0f - std::numeric_limits<float>::epsilon (), p_no_outliers);   // Avoid division by 0.
        if (p_no_outliers == 1.0f)
          k++;
        else
          k = log (1.0f - probability_) / log (p_no_outliers);
      }

      //fprintf (stderr, "[pcl_cuda::MultiRandomSampleConsensus::computeModel] Trial %d out of %f: %d inliers (best is: %d so far).\n",
          //cur_iteration, k, n_inliers_count, n_best_inliers_count);
      // check if we found a valid model

      {
        ScopeTime t("extracmodel");

      if (valid_iterations >= k)
      {
        unsigned int extracted_model = good_coeff;
        //int nr_remaining_points_before_delete = nr_remaining_points;
        bool find_no_better = false;
        nr_remaining_points = sac_model_->deleteIndices (hypotheses_inliers_stencils[extracted_model]);
        //if (nr_remaining_points != nr_remaining_points_before_delete)
        {

          // Compute the k parameter (k=log(z)/log(1-w^n))
          float w = (float)((float)min_nr_in_shape / (float)nr_remaining_points);
          float p_no_outliers = 1.0f - pow (w, 1.0f);
          p_no_outliers = (std::max) (std::numeric_limits<float>::epsilon (), p_no_outliers);       // Avoid division by -Inf
          p_no_outliers = (std::min) (1.0f - std::numeric_limits<float>::epsilon (), p_no_outliers);   // Avoid division by 0.
          if (p_no_outliers != 1.0f)
          {
            if (log (1.0f - probability_) / log (p_no_outliers) < valid_iterations) // we won't find a model with min_nr_in_shape points anymore...
              find_no_better = true;
            else
              if (debug_verbosity_level > 1)
                std::cerr << "------->" << log (1.0f - probability_) / log (p_no_outliers) << "  -vs-  " << valid_iterations << std::endl;
          }
        }

        std::cerr << "found model: " << n_best_inliers_count << ", points remaining: " << nr_remaining_points << " after " << valid_iterations << " / " << cur_iteration << " iterations" << std::endl;

        all_inliers_.push_back (hypotheses_inliers_stencils[extracted_model]);
        all_inlier_counts_.push_back (n_best_inliers_count);
        all_model_centroids_.push_back (centroids [extracted_model]);
        thrust::host_vector<float4> host_coeffs_extracted_model = h [extracted_model / iterations_per_batch_];
        all_model_coefficients_.push_back (host_coeffs_extracted_model [extracted_model % iterations_per_batch_]);
       
        //float4 model_coeff = h[extracted_model/iterations_per_batch_][extracted_model%iterations_per_batch_];
        //std::cerr << "MODEL COEFFICIENTS: " << model_coeff.x << " " << model_coeff.y << " " << model_coeff.z << " " << model_coeff.w << std::endl;

        // so we only get it once:
        hypothesis_valid[extracted_model] = false;

        if (nr_remaining_points < (1.0-min_coverage_percent_) * nr_points)
        {
          std::cerr << "batches: " << cur_batch << ", valid iterations: " << valid_iterations << ", remaining points:" << nr_remaining_points << std::endl;
          return true;
        }
        if (find_no_better)
        {
          std::cerr << "will find no better model! batches: " << cur_batch << ", valid iterations: " << valid_iterations << ", remaining points:" << nr_remaining_points << std::endl;
          return true;
        }

        n_best_inliers_count = 0;
        k = max_batches_ * iterations_per_batch_;
        // go through all other models, invalidating those whose samples are inliers to the best one
        int counter_invalid = 0;
        int counter_inliers = 0;

        //for (unsigned int b = 0; b <= cur_batch; b++)
        unsigned int b = cur_batch;  
        for (unsigned int j = 0; j < iterations_per_batch_; j++)
        {
          // todo: precheck for very similar models
          // if (h[best_coeff] - h[]) // <---- copies from device! slow!
          //   continue;
          if (!hypothesis_valid[b * iterations_per_batch_ + j])
          {
            //std::cerr << "model " << j << " in batch " << b <<" is an invalid model" << std::endl;
            counter_invalid ++;
            continue;
          }
          if ((b*iterations_per_batch_ + j) == extracted_model)
          {
            if (debug_verbosity_level > 1)
              std::cerr << "model " << j << " in batch " << b <<" is being extracted..." << std::endl;
            continue;
          }
          if (sac_model_->isSampleInlier (hypotheses_inliers_stencils[extracted_model], h_samples[b], j))
          {
            //std::cerr << "sample point for model " << j << " in batch " << b <<" is inlier to best model " << extracted_model << std::endl;
            counter_inliers ++;
            hypothesis_valid[b * iterations_per_batch_ + j] = false;
            hypotheses_inlier_count[b*iterations_per_batch_ + j] = 0;
            if (j <= i)
              valid_iterations --;
          }
          else if (j <= i) // if it is not inlier to the best model, we subtract the inliers of the extracted model
          {
            //todo: recompute inliers... / deleteindices
            // ... determine best remaining model
            int old_score = hypotheses_inlier_count[b*iterations_per_batch_ + j]; 
            if (old_score != 0)
            {
      //std::cerr << "inliers for model " << b*iterations_per_batch_ + j << " : " << old_score;
              n_inliers_count = sac_model_->deleteIndices (h[b], j,
                  hypotheses_inliers_stencils[b*iterations_per_batch_ + j], hypotheses_inliers_stencils[extracted_model]);
              hypotheses_inlier_count[b*iterations_per_batch_ + j] = n_inliers_count;
      //std::cerr << " ---> " << hypotheses_inlier_count[b * iterations_per_batch_ + j] << std::endl;
            }
      
            // Better match ?
            if (n_inliers_count > n_best_inliers_count)
            {
              n_best_inliers_count = n_inliers_count;
              good_coeff = b * iterations_per_batch_ + j;

              // Compute the k parameter (k=log(z)/log(1-w^n))
              float w = (float)((float)n_best_inliers_count / (float)nr_remaining_points);
              float p_no_outliers = 1.0f - pow (w, 1.0f);
              p_no_outliers = (std::max) (std::numeric_limits<float>::epsilon (), p_no_outliers);       // Avoid division by -Inf
              p_no_outliers = (std::min) (1.0f - std::numeric_limits<float>::epsilon (), p_no_outliers);   // Avoid division by 0.
              if (p_no_outliers == 1.0f)
                k++;
              else
                k = log (1.0f - probability_) / log (p_no_outliers);
            }
            
          }
        }
        //std::cerr << "invalid models: " << counter_invalid << " , inlier models: " << counter_inliers << std::endl;
      }
      }
    }
    }

    // one batch done, go to next
    cur_batch ++;

  } while (cur_iteration < max_batches_ * iterations_per_batch_);

  return (false);
}
Example #7
0
int main(int argc, char *argv[])
{
    /* variables */
    DCELL *data_buf;
    CELL *clump_buf;
    CELL i, max;

    int row, col, rows, cols;
    int out_mode, use_MASK, *n, *e;
    long int *count;
    int fd_data, fd_clump;

    const char *datamap, *clumpmap, *centroidsmap;
    
    double avg, vol, total_vol, east, north, *sum;

    struct Cell_head window;

    struct Map_info *fd_centroids;
    struct line_pnts *Points;
    struct line_cats *Cats;
    struct field_info *Fi;

    char buf[DB_SQL_MAX];
    dbString sql;
    dbDriver *driver;

    struct GModule *module;
    struct {
        struct Option *input, *clump, *centroids, *output;
    } opt;
    struct {
        struct Flag *report;
    } flag;

    /* define parameters and flags */
    G_gisinit(argv[0]);

    module = G_define_module();
    G_add_keyword(_("raster"));
    G_add_keyword(_("volume"));
    G_add_keyword(_("clumps"));
    module->label =
	_("Calculates the volume of data \"clumps\".");
    module->description = _("Optionally produces a GRASS vector points map "
                            "containing the calculated centroids of these clumps.");

    opt.input = G_define_standard_option(G_OPT_R_INPUT);
    opt.input->description =
	_("Name of input raster map representing data that will be summed within clumps");

    opt.clump = G_define_standard_option(G_OPT_R_INPUT);
    opt.clump->key = "clump";
    opt.clump->required = NO;
    opt.clump->label =
        _("Name of input clump raster map");
    opt.clump->description = _("Preferably the output of r.clump. "
                               "If no clump map is given than MASK is used.");

    opt.centroids = G_define_standard_option(G_OPT_V_OUTPUT);
    opt.centroids->key = "centroids";
    opt.centroids->required = NO;
    opt.centroids->description = _("Name for output vector points map to contain clump centroids");

    opt.output = G_define_standard_option(G_OPT_F_OUTPUT);
    opt.output->required = NO;
    opt.output->label =
	_("Name for output file to hold the report");
    opt.output->description =
	_("If no output file given report is printed to standard output");

    flag.report = G_define_flag();
    flag.report->key = 'f';
    flag.report->description = _("Generate unformatted report (items separated by colon)");

    if (G_parser(argc, argv))
	exit(EXIT_FAILURE);

    /* get arguments */
    datamap = opt.input->answer;
    
    clumpmap = NULL;
    if (opt.clump->answer)
	clumpmap = opt.clump->answer;
    
    centroidsmap = NULL;
    fd_centroids = NULL;
    Points = NULL;
    Cats = NULL;
    driver = NULL;
    if (opt.centroids->answer) {
	centroidsmap = opt.centroids->answer;
        fd_centroids = G_malloc(sizeof(struct Map_info));
    }
    
    out_mode = (!flag.report->answer);

    /*
     * see if MASK or a separate "clumpmap" raster map is to be used
     * -- it must(!) be one of those two choices.
     */
    use_MASK = 0;
    if (!clumpmap) {
	clumpmap = "MASK";
	use_MASK = 1;
        if (!G_find_raster2(clumpmap, G_mapset()))
            G_fatal_error(_("No MASK found. If no clump map is given than the MASK is required. "
                            "You need to define a clump raster map or create a MASK by r.mask command."));
        G_important_message(_("No clump map given, using MASK"));
    }
    
    /* open input and clump raster maps */
    fd_data = Rast_open_old(datamap, "");
    fd_clump = Rast_open_old(clumpmap, use_MASK ? G_mapset() : "");
    
    /* initialize vector map (for centroids) if needed */
    if (centroidsmap) {
	if (Vect_open_new(fd_centroids, centroidsmap, WITHOUT_Z) < 0)
	    G_fatal_error(_("Unable to create vector map <%s>"), centroidsmap);
        
        Points = Vect_new_line_struct();
        Cats = Vect_new_cats_struct();
        
        /* initialize data structures */
        Vect_append_point(Points, 0., 0., 0.);
        Vect_cat_set(Cats, 1, 1);
    }
    
    /* initialize output file */
    if (opt.output->answer && strcmp(opt.output->answer, "-") != 0) {
	if (freopen(opt.output->answer, "w", stdout) == NULL) {
	    perror(opt.output->answer);
	    exit(EXIT_FAILURE);
	}
    }

    /* initialize data accumulation arrays */
    max = Rast_get_max_c_cat(clumpmap, use_MASK ? G_mapset() : "");

    sum = (double *)G_malloc((max + 1) * sizeof(double));
    count = (long int *)G_malloc((max + 1) * sizeof(long int));

    G_zero(sum, (max + 1) * sizeof(double));
    G_zero(count, (max + 1) * sizeof(long int));
    
    data_buf = Rast_allocate_d_buf();
    clump_buf = Rast_allocate_c_buf();
    
    /* get window size */
    G_get_window(&window);
    rows = window.rows;
    cols = window.cols;

    /* now get the data -- first pass */
    for (row = 0; row < rows; row++) {
	G_percent(row, rows, 2);
	Rast_get_d_row(fd_data, data_buf, row);
	Rast_get_c_row(fd_clump, clump_buf, row);
	for (col = 0; col < cols; col++) {
	    i = clump_buf[col];
	    if (i > max)
		G_fatal_error(_("Invalid category value %d (max=%d): row=%d col=%d"),
                              i, max, row, col);
	    if (i < 1) {
                G_debug(3, "row=%d col=%d: zero or negs ignored", row, col);
		continue;	/* ignore zeros and negs */
            }
	    if (Rast_is_d_null_value(&data_buf[col])) {
                G_debug(3, "row=%d col=%d: NULL ignored", row, col);
		continue;
            }
            
	    sum[i] += data_buf[col];
	    count[i]++;
	}
    }
    G_percent(1, 1, 1);
    
    /* free some buffer space */
    G_free(data_buf);
    G_free(clump_buf);

    /* data lists for centroids of clumps */
    e = (int *)G_malloc((max + 1) * sizeof(int));
    n = (int *)G_malloc((max + 1) * sizeof(int));

    i = centroids(fd_clump, e, n, 1, max);

    /* close raster maps */
    Rast_close(fd_data);
    Rast_close(fd_clump);
    
    /* got everything, now do output */
    if (centroidsmap) {
        G_message(_("Creating vector point map <%s>..."), centroidsmap);
        /* set comment */
	sprintf(buf, _("From '%s' on raster map <%s> using clumps from <%s>"),
                argv[0], datamap, clumpmap);
        Vect_set_comment(fd_centroids, buf);

        /* create attribute table */        
        Fi = Vect_default_field_info(fd_centroids, 1, NULL, GV_1TABLE);
        
        driver = db_start_driver_open_database(Fi->driver,
                                               Vect_subst_var(Fi->database, fd_centroids));
	if (driver == NULL) {
	    G_fatal_error(_("Unable to open database <%s> by driver <%s>"),
			  Vect_subst_var(Fi->database, fd_centroids), Fi->driver);
	}
        db_set_error_handler_driver(driver);
        
	db_begin_transaction(driver);
        
        db_init_string(&sql);
	sprintf(buf, "create table %s (cat integer, volume double precision, "
                "average double precision, sum double precision, count integer)",
                Fi->table);
	db_set_string(&sql, buf);
	Vect_map_add_dblink(fd_centroids, 1, NULL, Fi->table, GV_KEY_COLUMN, Fi->database,
			    Fi->driver);

	G_debug(3, "%s", db_get_string(&sql));
	if (db_execute_immediate(driver, &sql) != DB_OK) {
	    G_fatal_error(_("Unable to create table: %s"), db_get_string(&sql));
	}
    }

    /* print header */
    if (out_mode) {
	fprintf(stdout, _("\nVolume report on data from <%s> using clumps on <%s> raster map"),
                datamap, clumpmap);
        fprintf(stdout, "\n\n");
	fprintf(stdout,
		_("Category   Average   Data   # Cells        Centroid             Total\n"));
	fprintf(stdout,
		_("Number     in clump  Total  in clump   Easting     Northing     Volume"));
        fprintf(stdout, "\n%s\n", SEP);
    }
    total_vol = 0.0;

    /* print output, write centroids */
    for (i = 1; i <= max; i++) {
	if (count[i]) {
	    avg = sum[i] / (double)count[i];
	    vol = sum[i] * window.ew_res * window.ns_res;
	    total_vol += vol;
	    east = window.west + (e[i] + 0.5) * window.ew_res;
	    north = window.north - (n[i] + 0.5) * window.ns_res;
	    if (fd_centroids) { /* write centroids if requested */
                Points->x[0] = east;
                Points->y[0] = north;
                Cats->cat[0] = i;
                Vect_write_line(fd_centroids, GV_POINT, Points, Cats);
	
                sprintf(buf, "insert into %s values (%d, %f, %f, %f, %ld)",
                        Fi->table, i, vol, avg, sum[i], count[i]);
                db_set_string(&sql, buf);

                if (db_execute_immediate(driver, &sql) != DB_OK)
                    G_fatal_error(_("Cannot insert new row: %s"),
                                  db_get_string(&sql));
	    }
	    if (out_mode)
		fprintf(stdout,
			"%8d%10.2f%10.0f %7ld  %10.2f  %10.2f %16.2f\n", i,
			avg, sum[i], count[i], east, north, vol);
	    else
		fprintf(stdout, "%d:%.2f:%.0f:%ld:%.2f:%.2f:%.2f\n",
			i, avg, sum[i], count[i], east, north, vol);
	}
    }

    /* write centroid attributes and close the map*/
    if (fd_centroids) {
        db_commit_transaction(driver);
        Vect_close(fd_centroids);
    }
    
    /* print total value */
    if (total_vol > 0.0 && out_mode) {
        fprintf(stdout, "%s\n", SEP);
	fprintf(stdout, "%60s = %14.2f", _("Total Volume"), total_vol);
        fprintf(stdout, "\n");
    }

    exit(EXIT_SUCCESS);
} 
Example #8
0
int main(int argc, char *argv[])
{
    /* variables   */
    CELL *data_buf, *clump_buf;
    CELL i, max;
    int row, col, rows, cols;
    int out_mode, use_MASK, *n, *e;
    long int *count;
    int fd_data, fd_clump;
    const char *datamap, *clumpmap, *site_list;
    const char *clump_mapset;
    double avg, vol, total_vol, east, north, *sum;
    struct Cell_head window;
    struct Map_info *fd_sites = NULL;
    Site *mysite;
    Site_head site_info;
    struct GModule *module;
    struct Option *opt1, *opt2, *opt3;
    struct Flag *flag1;

    /* Initialize GIS */
    G_gisinit(argv[0]);

    module = G_define_module();
    G_add_keyword(_("raster"));
    G_add_keyword(_("volume"));
    module->description =
	_("Calculates the volume of data \"clumps\", "
	  "and (optionally) produces a GRASS vector points map "
	  "containing the calculated centroids of these clumps.");

    opt1 = G_define_standard_option(G_OPT_R_INPUT);
    opt1->description =
	_("Existing raster map representing data that will be summed within clumps");

    opt2 = G_define_standard_option(G_OPT_R_INPUT);
    opt2->key = "clump";
    opt2->required = NO;
    opt2->description =
	_("Existing raster map, preferably the output of r.clump");

    opt3 = G_define_standard_option(G_OPT_V_OUTPUT);
    opt3->key = "centroids";
    opt3->required = NO;
    opt3->description = _("Vector points map to contain clump centroids");

    flag1 = G_define_flag();
    flag1->key = 'f';
    flag1->description = _("Generate unformatted report");

    if (G_parser(argc, argv))
	exit(EXIT_FAILURE);

    /* get current window */
    G_get_window(&window);

    /* initialize */
    out_mode = 1;		/* assume full output text */
    mysite = G_site_new_struct(CELL_TYPE, 2, 0, 4);

    /* get arguments */
    datamap = opt1->answer;

    if (opt2->answer)
	clumpmap = opt2->answer;
    else
	clumpmap = "";

    if (opt3->answer)
	site_list = opt3->answer;
    else
	site_list = "";

    out_mode = (!flag1->answer);

    if (*datamap == 0)
	G_fatal_error(_("No data map specified"));

    /*
     * See if MASK or a separate "clumpmap" layer is to be used-- it must(!)
     * be one of those two choices.
     */
    use_MASK = 0;
    if (*clumpmap == '\0') {
	clumpmap = "MASK";
	use_MASK = 1;
    }
    fd_data = Rast_open_old(datamap, "");
    if (use_MASK)
	clump_mapset = G_mapset();
    else
	clump_mapset = "";

    fd_clump = Rast_open_old(clumpmap, clump_mapset);

    /* initialize sites file (for centroids) if needed */
    if (*site_list) {
	fd_sites = G_fopen_sites_new(site_list);
	if (fd_sites == NULL)
	    G_fatal_error(_("Unable to open centroids vector points map"));
    }

    /* initialize data accumulation arrays */
    max = Rast_get_max_c_cat(clumpmap, clump_mapset);

    sum = (double *)G_malloc((max + 1) * sizeof(double));
    count = (long int *)G_malloc((max + 1) * sizeof(long int));

    for (i = 0; i <= max; i++) {
	sum[i] = 0;
	count[i] = 0;
    }

    data_buf = Rast_allocate_c_buf();
    clump_buf = Rast_allocate_c_buf();

    /* get window size */
    rows = window.rows;
    cols = window.cols;

    /* now get the data -- first pass */
    G_message("Complete ...");
    for (row = 0; row < rows; row++) {
	G_percent(row, rows, 2);
	Rast_get_c_row(fd_data, data_buf, row);
	Rast_get_c_row(fd_clump, clump_buf, row);
	for (col = 0; col < cols; col++) {
	    i = clump_buf[col];
	    if (i > max)
		G_fatal_error(
		    "Row=%d Col=%d Cat=%d in clump map [%s]; max=%d.\n"
		    "Cat value > max returned by Rast_get_max_c_cat.",
		    row, col, i, clumpmap, max);
	    if (i < 1)
		continue;	/* ignore zeros and negs */
	    count[i]++;
	    sum[i] += data_buf[col];
	}
    }
    G_percent(row, rows, 2);
    /* free some buffer space */
    G_free(data_buf);
    G_free(clump_buf);

    /* data lists for centroids of clumps */
    e = (int *)G_malloc((max + 1) * sizeof(int));
    n = (int *)G_malloc((max + 1) * sizeof(int));

    i = centroids(fd_clump, e, n, 1, max);

    /* got everything, now do output */
    if (*site_list) {
	char desc[GNAME_MAX * 2 + 40];

	site_info.form = NULL;
	site_info.time = NULL;
	site_info.stime = NULL;
	sprintf(desc, "from %s on map %s using clumps from %s",
		argv[0], datamap, clumpmap);
	site_info.desc = G_store(desc);
	site_info.name = G_store(site_list);
	site_info.labels =
	    G_store("centroid east|centroid north|#cat vol avg t n");
	G_site_put_head(fd_sites, &site_info);
    }
    if (out_mode) {
	fprintf(stdout, "Volume report on data from %s", datamap);
	fprintf(stdout, " using clumps on %s map\n\n", clumpmap);
	fprintf(stdout,
		" Cat    Average   Data   # Cells        Centroid             Total\n");
	fprintf(stdout,
		"Number  in clump  Total  in clump   Easting   Northing       Volume\n\n");
    }
    total_vol = 0.0;

    for (i = 1; i <= max; i++) {
	if (count[i]) {
	    avg = sum[i] / (double)count[i];
	    vol = sum[i] * window.ew_res * window.ns_res;
	    total_vol += vol;
	    east = window.west + (e[i] + 0.5) * window.ew_res;
	    north = window.north - (n[i] + 0.5) * window.ns_res;
	    if (*site_list) {
		mysite->east = east;
		mysite->north = north;
		mysite->ccat = i;
		mysite->dbl_att[0] = vol;
		mysite->dbl_att[1] = avg;
		mysite->dbl_att[2] = sum[i];
		mysite->dbl_att[3] = (double)count[i];
		/*       "%-1.2f|%-1.2f|#%5d v=%-1.2f a=%-1.2f t=%-1.0f n=%ld\n", */
		/* east, north, i, vol, avg, sum[i], count[i]); */
		G_site_put(fd_sites, mysite);
	    }
	    if (out_mode)
		fprintf(stdout,
			"%5d%10.2f%10.0f %7ld  %10.2f  %10.2f %16.2f\n", i,
			avg, sum[i], count[i], east, north, vol);
	    else
		fprintf(stdout, "%d:%.2f:%.0f:%ld:%.2f:%.2f:%.2f\n",
			i, avg, sum[i], count[i], east, north, vol);
	}
    }
    if (total_vol > 0.0 && out_mode)
	fprintf(stdout, "%58s %14.2f", "Total Volume =", total_vol);
    fprintf(stdout, "\n");
    exit(EXIT_SUCCESS);
}				/* end of main() */
Example #9
0
bool Connectome::generate(s16_cube label, const FiberTracts &fibers,
                          bool isFreesurfer, MyProgressDialog *progress)
{
    if (label.is_empty() || fibers.isEmpty())
        return false;
    // prepare progress bar
    progress->setLabelText("Generating Connectome ... ");
    progress->setRange(0,fibers.size()+100);
    progress->setFixedSize(progress->sizeHint());
    progress->setModal(true);
    progress->setValue(0);
    progress->show();
    // remove bad labels from label volume if freesurfer
    // in order to eliminate the unwanted values, the label must first
    // be converted into a 1D vector
    if (isFreesurfer) {
        label(find(label<8)).fill(0);
        s16_vec badLabels;
        badLabels<<14<<15<<24<<30<<31<<41<<43<<44<<46<<1000<<1004<<2000<<2004;
        for (int i = 0; i< badLabels.n_elem; ++i)
            label(find(label == badLabels.at(i))).fill(0);
        // remove regions > 60 and < 1000
        uvec loc = find(label > 60);
        label(loc(find(label(loc)<1000))).fill(0);
    }
    s16_vec lbl = s16_vec(label.memptr(),label.n_elem);
    // get labels values and their sizes, it is assumed that hist
    // will give the count of every label since the nbins = n labels
    s16_vec labels = unique(lbl);
    uvec labelsSize = hist(lbl,labels);
    if (labels[0] == 0) {
        labels.shed_row(0);
        labelsSize.shed_row(0);
    }
    int cc = 0;
    s16_vec idx = zeros<s16_vec>(labels.max()+1);
    for (uint i=0; i<labels.n_elem; ++i)
        idx(labels(i)) = cc++;
    progress->setValue(1);
    // compute centroids
    int r = label.n_rows, c = label.n_cols, s = label.n_slices;
    centroids = zeros<fmat>(labels.n_elem,3);
    for (uint i=0;i<labels.size();++i)
        centroids(i,span::all) = mean(conv_to<fmat>::
                                      from(getIndex(find(lbl == labels(i)),r,c,s)),0);

    // fill header
    fibers.getVoxelDimension(header.dx,header.dy,header.dz);
    header.nR = r, header.nC = c, header.nS = s;
    header.nRegions = labels.n_elem;
    // prepare intersection cube
//    frowvec t; t<<header.dx<<header.dy<<header.dz;
//    float cubeSizeLimit = max((cubeSize/2)/t);
//    float endSize = ceil(cubeSizeLimit*2)/2;
//    fvec index = linspace<fvec>(0,cubeSizeLimit,floor(cubeSizeLimit));
//    index.in;
    // form the network
    NW = zeros<mat>(labels.n_elem,labels.n_elem);
    // compute fiber pairs
    int x=0,y=0,z=0, p1, p2;
    for (int i =0; i<fibers.size();++i) {
        // first end
        x = qMax(qMin(qRound(fibers.getFiber(i).first().x()),r),0);
        y = qMax(qMin(qRound(fibers.getFiber(i).first().y()),c),0);
        z = qMax(qMin(qRound(fibers.getFiber(i).first().z()),s),0);
        p1 = label(x,y,z);
        // second end
        x = qMax(qMin(qRound(fibers.getFiber(i).last().x()),r),0);
        y = qMax(qMin(qRound(fibers.getFiber(i).last().y()),c),0);
        z = qMax(qMin(qRound(fibers.getFiber(i).last().z()),s),0);
        p2 = label(x,y,z);
        if (p1 > 0 && p2 > 0) {
            NW(idx(p1),idx(p2))++;
            NW(idx(p2),idx(p1))++;
        }
        progress->setValue(progress->value()+1);
    }
    // remove self connections
    NW.diag().fill(0);
    // normalize the network w.r.t. labels sizes
    for (uint i =0;i<labels.n_elem;++i) {
        for (uint j =i+1;j<labels.n_elem;++j) {
            NW(i,j) = NW(i,j)/(labelsSize(i)+labelsSize(j));
            NW(j,i) = NW(i,j);
        }
    }
    // prepare mask
    label(find(label>0)).fill(1);
    maskImage = conv_to<uchar_cube>::from(label);
    progress->setValue(progress->maximum());
    if (isFreesurfer)
        readNames(QDir::currentPath()+"/FreesurferLabels.txt");
    return true;
}