// // 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;
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); }
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; }
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); }
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); }
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() */
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; }