IMP Reference Guide  develop.8b7eb21230,2024/06/24 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
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 <cereal/access.hpp>
17 #include <IMP/constants.h>
18
19 IMPEM2D_BEGIN_NAMESPACE
20
21 //! Class to manage the parameters required for the polar resampling in the
22 //! rotational_alignment function
23 class IMPEM2DEXPORT PolarResamplingParameters {
24
25  public:
27  parameters_set_ = false;
28  };
29
30  //! Compute the parameters for a polar resampling from the dimensions of
31  //! a matrix
32  PolarResamplingParameters(unsigned int rows, unsigned int cols) {
33  setup(rows, cols);
34  }
35
36  //! Compute the parameters for a polar resampling getting the dimensions from
37  //! the matrix
38  /*!
39  \param[in] m Matrix that is going to be resampled
40  */
41  PolarResamplingParameters(const cv::Mat &m) { setup(m.rows, m.cols); }
42
44
45  //! Initialize the internal parameters to generate all the values
46  //! The class uses a number of radius values for resampling that is
47  //! optimal to perform FFT during the rotational alignment. The first guess
48  //! is half the rows and columns
49  void setup(unsigned int rows, unsigned int cols) {
51  n_angles_ = 0;
52  matrix_rows_ = rows;
53  matrix_cols_ = cols;
55  std::min(rows / 2., cols / 2.); // maximum radius, half the size
59  parameters_set_ = true;
60  IMP_LOG_VERBOSE("PolarResamplingParameters setup. Input matrix: "
61  << rows << " x " << cols << " Starting radius= "
63  << " Rings= " << n_rings_ << std::endl);
64  }
65
66  //! Gets the initial radius of the resampling
68  get_is_setup();
70  }
71
72  //! Gets the largest radius
74  get_is_setup();
76  }
77
78  //! Gets the current radius employed for the ring in consideration)
79  double get_radius(unsigned int n_ring) const {
80  get_is_setup();
81  IMP_USAGE_CHECK(n_ring <= n_rings_,
82  "PolarResamplingParameters: Requested ring is above the "
83  "maximum number");
85  }
86
87  //! Get the number of rings (that is, the number of radius values considered)
88  unsigned int get_number_of_rings() const {
89  get_is_setup();
90  return n_rings_;
91  }
92
93  //! You give an approximated number of values that you want to
94  //! use for the resampling, and the function computes the optimal number
95  //! for an FFT based on this approximated number
96  void set_estimated_number_of_angles(unsigned int aprox_value) {
97  n_angles_ = cv::getOptimalDFTSize(aprox_value);
98  angle_step_ = (2 * PI) / static_cast<double>(n_angles_);
99  }
100
101  //! Gets the number of points that are sampled for the angles
102  //! remember that this number is usually different to the approximated value
103  //! that you provide to the function set_estimated_number_of_angles()
104  unsigned int get_number_of_angles() const { return n_angles_; }
105
106  //! get the angular step used
107  double get_angle_step() const { return angle_step_; }
108
109  //! Get the step for the radius coordinate
111  if (get_is_setup() == false) {
112  IMP_THROW("trying to get radius_step before initializing",
114  }
116  }
117
118  //! After the number of radius and angles values are set, this function
119  //! Builds a map of resampling coordinates. This map is very useful for
121  if (n_angles_ == 0) {
122  IMP_THROW("Number of sampling points for the angle is zero",
124  }
125  // create the appropriate map
126  polar_map_.create(n_rings_, n_angles_, CV_32FC2); // 2 channels, floats
127  // Build a map to use with the OpenCV the cv::remap
128  // function for polar resampling
129  cv::Vec2d v;
130  for (unsigned int i = 0; i < n_rings_; ++i) {
131  for (unsigned int j = 0; j < n_angles_; ++j) {
133  double theta = j * angle_step_;
134  // row and col of input to use
135  double row = static_cast<double>(matrix_rows_) / 2.0 + r * sin(theta);
136  double col = static_cast<double>(matrix_cols_) / 2.0 + r * cos(theta);
137  polar_map_.at<cv::Vec2f>(i, j)[0] = static_cast<float>(row);
138  polar_map_.at<cv::Vec2f>(i, j)[1] = static_cast<float>(col);
139  }
140  }
141  // Convert to fast maps
142  cv::Mat empty;
143  cv::convertMaps(polar_map_, empty, map_16SC2_, map_16UC1_, CV_16SC2);
144  }
145
146  //! Get the samplings maps of type CV_16SC2 and CV_16UC1
147  //! (this map combination is faster for remapping. See OpenCV help for remap()
148  void get_resampling_maps(cv::Mat &m1, cv::Mat &m2) const {
149  m1 = map_16SC2_;
150  m2 = map_16UC1_;
151  }
152
153  //! Obtain the resampling map of type CV_32FC2 (floats, slower that those
154  //! obtained with get_resampling_maps()
155  void get_resampling_map(cv::Mat &m1) const {
156  IMP_LOG_VERBOSE("returning resampling map "
157  << polar_map_.rows << "x" << polar_map_.cols << " depth "
158  << polar_map_.depth() << " type " << polar_map_.type()
159  << std::endl);
160  m1 = polar_map_;
161  }
162
163  void show(std::ostream &out) const {
166  out << "n_rings = " << n_rings_ << std::endl;
167  }
168
169  bool get_is_setup() const {
170  if (parameters_set_) return true;
171  return false;
172  }
173
174  protected:
175  cv::Mat polar_map_; // CV_23CF, map in floats.
176  cv::Mat map_16SC2_; // Map for speed up resampling (see OpenCV help for
177  // remap)
178  cv::Mat map_16UC1_; // Map for speed up resampling (see OpenCV help for
179  // remap)
182  // Number of sampling points for radius and angles
183  unsigned int n_rings_, n_angles_, matrix_rows_, matrix_cols_;
184  bool parameters_set_;
186
187 private:
188  friend class cereal::access;
189
190  template<class Archive> void serialize(Archive &ar) {
192  ending_radius_, n_rings_, n_angles_, matrix_rows_, matrix_cols_,
194  }
195 };
196
198
199 IMPEM2D_END_NAMESPACE
200
201 #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)
#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:50
#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.
Get the step for the radius coordinate.
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)