void gmmreg_base::save_transformed(const char* filename, const vnl_vector<double>& params, const char* f_config) { std::ofstream outfile(filename, std::ios_base::out); perform_transform(params); denormalize_all(); transformed_model.print(outfile); char section_correspondence[256] = "CORRESPONDENCE"; int num = GetPrivateProfileInt(section_correspondence, "num_of_thresholds", 0, f_config); if (num > 0) { char s_min[256], s_max[256], s_pairs[256]; GetPrivateProfileString(section_correspondence, "min_threshold", NULL, s_min, 255, f_config); GetPrivateProfileString(section_correspondence, "max_threshold", NULL, s_max, 255, f_config); GetPrivateProfileString(section_correspondence, "matched_pairs", NULL, s_pairs, 255, f_config); std::ofstream f_pair(s_pairs, std::ios_base::out); double min_threshold, max_threshold, interval; min_threshold = atof(s_min); max_threshold = atof(s_max); if (num == 1) { interval = 0.0f; } else { interval = (max_threshold - min_threshold) / (num - 1); } //vnl_matrix<double> working_M, working_S; vnl_matrix<double> dist; vnl_matrix<int> pairs; ComputeSquaredDistanceMatrix(transformed_model, scene, dist); for (int i = 0; i < num; ++i) { double threshold = min_threshold + i*interval; //int n_match = find_working_pair(model, scene, transformed_model, // threshold, working_M, working_S); pick_indices(dist, pairs, threshold*threshold); //printf("%f : %d\n",threshold, n_match); f_pair << "distance threshold : " << threshold << std::endl; f_pair << "# of matched point pairs : " << pairs.cols() << std::endl; int j; for (j = 0; j < pairs.cols(); ++j) { f_pair.width(6); f_pair << std::left << pairs(0, j); } f_pair << std::endl; for (j = 0; j < pairs.cols(); ++j) { f_pair.width(6); f_pair << std::left << pairs(1, j); } f_pair << std::endl; } } std::cout << "Please find the transformed model set in " << filename << std::endl; }
// Get next point where the marker should be placed. Returns true if a place is found, false if none is found. bool get_point(double &x, double &y, double &angle, bool ignore_placement) { if (done_) { return false; } if (locator_.type() == geometry::geometry_types::LineString) { if (!label::middle_point(locator_, x, y)) { done_ = true; return false; } } else { if (!label::centroid(locator_, x, y)) { done_ = true; return false; } } angle = 0; box2d<double> box = perform_transform(angle, x, y); if (params_.avoid_edges && !detector_.extent().contains(box)) { return false; } if (!params_.allow_overlap && !detector_.has_placement(box)) { return false; } if (!ignore_placement) { detector_.insert(box); } done_ = true; return true; }
bool markers_placement<Locator, Detector>::get_point( double & x, double & y, double & angle, bool add_to_detector) { if (done_) return false; unsigned cmd; /* This functions starts at the position of the previous marker, walks along the path, counting how far it has to go in spacing_left. If one marker can't be placed at the position it should go to it is moved a bit. The error is compensated for in the next call to this function. error > 0: Marker too near to the end of the path. error = 0: Perfect position. error < 0: Marker too near to the beginning of the path. */ if (marker_nr_++ == 0) { //First marker spacing_left_ = spacing_ / 2; } else { spacing_left_ = spacing_; } spacing_left_ -= error_; error_ = 0; //Loop exits when a position is found or when no more segments are available while (true) { //Do not place markers too close to the beginning of a segment if (spacing_left_ < marker_width_/2) { set_spacing_left(marker_width_/2); //Only moves forward } //Error for this marker is too large. Skip to the next position. if (abs(error_) > max_error_ * spacing_) { if (error_ > spacing_) { error_ = 0; //Avoid moving backwards MAPNIK_LOG_WARN(markers_placement) << "Extremely large error in markers_placement. Please file a bug report."; } spacing_left_ += spacing_ - error_; error_ = 0; } double dx = next_x - last_x; double dy = next_y - last_y; double segment_length = std::sqrt(dx * dx + dy * dy); if (segment_length <= spacing_left_) { //Segment is to short to place marker. Find next segment spacing_left_ -= segment_length; last_x = next_x; last_y = next_y; while (agg::is_move_to(cmd = locator_.vertex(&next_x, &next_y))) { //Skip over "move" commands last_x = next_x; last_y = next_y; } if (agg::is_stop(cmd)) { done_ = true; return false; } continue; //Try again } /* At this point we know the following things: - segment_length > spacing_left - error is small enough - at least half a marker fits into this segment */ //Check if marker really fits in this segment if (segment_length < marker_width_) { //Segment to short => Skip this segment set_spacing_left(segment_length + marker_width_/2); //Only moves forward continue; } else if (segment_length - spacing_left_ < marker_width_/2) { //Segment is long enough, but we are to close to the end //Note: This function moves backwards. This could lead to an infinite // loop when another function adds a positive offset. Therefore we // only move backwards when there is no offset if (error_ == 0) { set_spacing_left(segment_length - marker_width_/2, true); } else { //Skip this segment set_spacing_left(segment_length + marker_width_/2); //Only moves forward } continue; //Force checking of max_error constraint } angle = atan2(dy, dx); x = last_x + dx * (spacing_left_ / segment_length); y = last_y + dy * (spacing_left_ / segment_length); box2d<double> box = perform_transform(angle, x, y); if (!allow_overlap_ && !detector_.has_placement(box)) { //10.0 is the approxmiate number of positions tried and choosen arbitrarily set_spacing_left(spacing_left_ + spacing_ * max_error_ / 10.0); //Only moves forward continue; } if (add_to_detector) detector_.insert(box); last_x = x; last_y = y; return true; } }
/** Get a point where the marker should be placed. * Each time this function is called a new point is returned. * \param x Return value for x position * \param y Return value for x position * \param angle Return value for rotation angle * \param add_to_detector Add selected position to detector * \return True if a place is found, false if none is found. */ template <typename Locator, typename Detector> bool markers_placement<Locator, Detector>::get_point( double *x, double *y, double *angle, bool add_to_detector) { if (done_) return false; unsigned cmd; double spacing_left; if (marker_nr_++ == 0) { spacing_left = spacing_ / 2; } else { spacing_left = spacing_; } spacing_left -= error_; error_ = 0; while (true) { //Loop exits when a position is found or when no more segments are available if (spacing_left < size_.width()/2) { //Do not place markers to close to the beginning of a segment error_ += size_.width()/2 - spacing_left; spacing_left = size_.width()/2; } if (abs(error_) > max_error_ * spacing_) { spacing_left += spacing_ - error_; error_ = 0; } double dx = next_x - last_x; double dy = next_y - last_y; double d = std::sqrt(dx * dx + dy * dy); if (d <= spacing_left) { //Segment is to short to place marker. Find next segment spacing_left -= d; last_x = next_x; last_y = next_y; while (agg::is_move_to(cmd = locator_.vertex(&next_x, &next_y))) { //Skip over "move" commands last_x = next_x; last_y = next_y; } if (agg::is_stop(cmd)) { done_ = true; return false; } continue; //Try again } //Check if marker really fits in this segment if (d < size_.width()) { //Segment to short => Skip this segment error_ += d + size_.width()/2 - spacing_left; spacing_left = d + size_.width()/2; continue; } else if (d - spacing_left < size_.width()/2) { //Segment is long enough, but we are to close to the end //Note: This function moves backwards. This could lead to an infinite // loop when another function adds a positive offset. Therefore we // only move backwards when there is no offset if (error_ == 0) { error_ += d - size_.width()/2 - spacing_left; spacing_left = d - size_.width()/2; } else { //Skip this segment error_ += d + size_.width()/2 - spacing_left; spacing_left = d + size_.width()/2; } continue; //Force checking of max_error constraint } *angle = atan2(dy, dx); *x = last_x + dx * (spacing_left / d); *y = last_y + dy * (spacing_left / d); box2d<double> box = perform_transform(*angle, *x, *y); if (!allow_overlap_ && !detector_.has_placement(box)) { //10.0 is choosen arbitrarily error_ += spacing_ * max_error_ / 10.0; spacing_left += spacing_ * max_error_ / 10.0; continue; } if (add_to_detector) detector_.insert(box); last_x = *x; last_y = *y; return true; } }