IMP logo
IMP Reference Guide  2.14.0
The Integrative Modeling Platform
PolarResamplingParameters.h
Go to the documentation of this file.
1 /**
2  * \file IMP/em2d/PolarResamplingParameters.h
3  * \brief Functions related with rotations in em2d
4  * Copyright 2007-2020 IMP Inventors. All rights reserved.
5 */
6 
7 #ifndef IMPEM2D_POLAR_RESAMPLING_PARAMETERS_H
8 #define IMPEM2D_POLAR_RESAMPLING_PARAMETERS_H
9 
10 #include "IMP/em2d/em2d_config.h"
12 #include "IMP/algebra/constants.h"
13 #include "IMP/exception.h"
14 #include "IMP/log.h"
15 #include "IMP/log_macros.h"
16 #include <IMP/constants.h>
17 
18 IMPEM2D_BEGIN_NAMESPACE
19 
20 //! Class to manage the parameters required for the polar resampling in the
21 //! rotational_alignment function
22 class IMPEM2DEXPORT PolarResamplingParameters {
23 
24  public:
26  parameters_set_ = false;
27  };
28 
29  //! Compute the parameters for a polar resampling from the dimensions of
30  //! a matrix
31  PolarResamplingParameters(unsigned int rows, unsigned int cols) {
32  setup(rows, cols);
33  }
34 
35  //! Compute the parameters for a polar resampling getting the dimensions from
36  //! the matrix
37  /*!
38  \param[in] m Matrix that is going to be resampled
39  */
40  PolarResamplingParameters(const cv::Mat &m) { setup(m.rows, m.cols); }
41 
43 
44  //! Initialize the internal parameters to generate all the values
45  //! The class uses a number of radius values for resampling that is
46  //! optimal to perform FFT during the rotational alignment. The first guess
47  //! is half the rows and columns
48  void setup(unsigned int rows, unsigned int cols) {
49  starting_radius_ = 5.0;
50  n_angles_ = 0;
51  matrix_rows_ = rows;
52  matrix_cols_ = cols;
53  ending_radius_ =
54  std::min(rows / 2., cols / 2.); // maximum radius, half the size
55  n_rings_ = cv::getOptimalDFTSize((int)ending_radius_);
56  radius_step_ =
57  (ending_radius_ - starting_radius_) / (static_cast<double>(n_rings_));
58  parameters_set_ = true;
59  IMP_LOG_VERBOSE("PolarResamplingParameters setup. Input matrix: "
60  << rows << " x " << cols << " Starting radius= "
61  << starting_radius_ << " Ending radius= " << ending_radius_
62  << " Rings= " << n_rings_ << std::endl);
63  }
64 
65  //! Gets the initial radius of the resampling
66  double get_starting_radius() const {
67  get_is_setup();
68  return starting_radius_;
69  }
70 
71  //! Gets the largest radius
72  double get_ending_radius() const {
73  get_is_setup();
74  return ending_radius_;
75  }
76 
77  //! Gets the current radius employed for the ring in consideration)
78  double get_radius(unsigned int n_ring) const {
79  get_is_setup();
80  IMP_USAGE_CHECK(n_ring <= n_rings_,
81  "PolarResamplingParameters: Requested ring is above the "
82  "maximum number");
83  return starting_radius_ + n_ring * radius_step_;
84  }
85 
86  //! Get the number of rings (that is, the number of radius values considered)
87  unsigned int get_number_of_rings() const {
88  get_is_setup();
89  return n_rings_;
90  }
91 
92  //! You give an approximated number of values that you want to
93  //! use for the resampling, and the function computes the optimal number
94  //! for an FFT based on this approximated number
95  void set_estimated_number_of_angles(unsigned int aprox_value) {
96  n_angles_ = cv::getOptimalDFTSize(aprox_value);
97  angle_step_ = (2 * PI) / static_cast<double>(n_angles_);
98  }
99 
100  //! Gets the number of points that are sampled for the angles
101  //! remember that this number is usually different to the approximated value
102  //! that you provide to the function set_estimated_number_of_angles()
103  unsigned int get_number_of_angles() const { return n_angles_; }
104 
105  //! get the angular step used
106  double get_angle_step() const { return angle_step_; }
107 
108  //! Get the step for the radius coordinate
109  double get_radius_step() const {
110  if (get_is_setup() == false) {
111  IMP_THROW("trying to get radius_step before initializing",
113  }
114  return radius_step_;
115  }
116 
117  //! After the number of radius and angles values are set, this function
118  //! Builds a map of resampling coordinates. This map is very useful for
120  if (n_angles_ == 0) {
121  IMP_THROW("Number of sampling points for the angle is zero",
123  }
124  // create the appropriate map
125  polar_map_.create(n_rings_, n_angles_, CV_32FC2); // 2 channels, floats
126  // Build a map to use with the OpenCV the cv::remap
127  // function for polar resampling
128  cv::Vec2d v;
129  for (unsigned int i = 0; i < n_rings_; ++i) {
130  for (unsigned int j = 0; j < n_angles_; ++j) {
131  double r = get_radius(i);
132  double theta = j * angle_step_;
133  // row and col of input to use
134  double row = static_cast<double>(matrix_rows_) / 2.0 + r * sin(theta);
135  double col = static_cast<double>(matrix_cols_) / 2.0 + r * cos(theta);
136  polar_map_.at<cv::Vec2f>(i, j)[0] = static_cast<float>(row);
137  polar_map_.at<cv::Vec2f>(i, j)[1] = static_cast<float>(col);
138  }
139  }
140  // Convert to fast maps
141  cv::Mat empty;
142  cv::convertMaps(polar_map_, empty, map_16SC2_, map_16UC1_, CV_16SC2);
143  }
144 
145  //! Get the samplings maps of type CV_16SC2 and CV_16UC1
146  //! (this map combination is faster for remapping. See OpenCV help for remap()
147  void get_resampling_maps(cv::Mat &m1, cv::Mat &m2) const {
148  m1 = map_16SC2_;
149  m2 = map_16UC1_;
150  }
151 
152  //! Obtain the resampling map of type CV_32FC2 (floats, slower that those
153  //! obtained with get_resampling_maps()
154  void get_resampling_map(cv::Mat &m1) const {
155  IMP_LOG_VERBOSE("returning resampling map "
156  << polar_map_.rows << "x" << polar_map_.cols << " depth "
157  << polar_map_.depth() << " type " << polar_map_.type()
158  << std::endl);
159  m1 = polar_map_;
160  }
161 
162  void show(std::ostream &out) const {
163  out << "starting_radius = " << starting_radius_ << std::endl;
164  out << "ending_radius = " << ending_radius_ << std::endl;
165  out << "n_rings = " << n_rings_ << std::endl;
166  }
167 
168  bool get_is_setup() const {
169  if (parameters_set_) return true;
170  return false;
171  }
172 
173  protected:
174  cv::Mat polar_map_; // CV_23CF, map in floats.
175  cv::Mat map_16SC2_; // Map for speed up resampling (see OpenCV help for
176  // remap)
177  cv::Mat map_16UC1_; // Map for speed up resampling (see OpenCV help for
178  // remap)
179  double starting_radius_; // starting radius for the polar resampling
180  double ending_radius_; // ending radius for the polar resampling
181  // Number of sampling points for radius and angles
182  unsigned int n_rings_, n_angles_, matrix_rows_, matrix_cols_;
183  bool parameters_set_;
184  double radius_step_, angle_step_;
185 };
186 
188 
189 IMPEM2D_END_NAMESPACE
190 
191 #endif /* IMPEM2D_POLAR_RESAMPLING_PARAMETERS_H */
static const double PI
the constant pi
Various useful constants.
void set_estimated_number_of_angles(unsigned int aprox_value)
Interface with OpenCV Copyright 2007-2020 IMP Inventors. All rights reserved.
#define IMP_LOG_VERBOSE(expr)
Definition: log_macros.h:83
Exception definitions and assertions.
A more IMP-like version of the std::vector.
Definition: Vector.h:39
double get_ending_radius() const
Gets the largest radius.
#define IMP_VALUES(Name, PluralName)
Define the type for storing sets of values.
Definition: value_macros.h:23
void get_resampling_maps(cv::Mat &m1, cv::Mat &m2) const
double get_angle_step() const
get the angular step used
Logging and error reporting support.
double get_radius_step() const
Get the step for the radius coordinate.
double get_starting_radius() const
Gets the initial radius of the resampling.
unsigned int get_number_of_rings() const
Get the number of rings (that is, the number of radius values considered)
Various useful constants.
std::ostream & show(Hierarchy h, std::ostream &out=std::cout)
Print the hierarchy using a given decorator to display each node.
#define IMP_THROW(message, exception_name)
Throw an exception with a message.
Definition: check_macros.h:50
void setup(unsigned int rows, unsigned int cols)
double get_radius(unsigned int n_ring) const
Gets the current radius employed for the ring in consideration)
PolarResamplingParameters(unsigned int rows, unsigned int cols)
#define IMP_USAGE_CHECK(expr, message)
A runtime test for incorrect usage of a class or method.
Definition: check_macros.h:168
Logging and error reporting support.
An exception for an invalid value being passed to IMP.
Definition: exception.h:137