IMP logo
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
4  * Copyright 2007-2022 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 <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) {
50  starting_radius_ = 5.0;
51  n_angles_ = 0;
52  matrix_rows_ = rows;
53  matrix_cols_ = cols;
54  ending_radius_ =
55  std::min(rows / 2., cols / 2.); // maximum radius, half the size
56  n_rings_ = cv::getOptimalDFTSize((int)ending_radius_);
57  radius_step_ =
58  (ending_radius_ - starting_radius_) / (static_cast<double>(n_rings_));
59  parameters_set_ = true;
60  IMP_LOG_VERBOSE("PolarResamplingParameters setup. Input matrix: "
61  << rows << " x " << cols << " Starting radius= "
62  << starting_radius_ << " Ending radius= " << ending_radius_
63  << " Rings= " << n_rings_ << std::endl);
64  }
65 
66  //! Gets the initial radius of the resampling
67  double get_starting_radius() const {
68  get_is_setup();
69  return starting_radius_;
70  }
71 
72  //! Gets the largest radius
73  double get_ending_radius() const {
74  get_is_setup();
75  return ending_radius_;
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");
84  return starting_radius_ + n_ring * radius_step_;
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
110  double get_radius_step() const {
111  if (get_is_setup() == false) {
112  IMP_THROW("trying to get radius_step before initializing",
114  }
115  return radius_step_;
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) {
132  double r = get_radius(i);
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 {
164  out << "starting_radius = " << starting_radius_ << std::endl;
165  out << "ending_radius = " << ending_radius_ << std::endl;
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)
180  double starting_radius_; // starting radius for the polar resampling
181  double ending_radius_; // ending radius for the polar resampling
182  // Number of sampling points for radius and angles
183  unsigned int n_rings_, n_angles_, matrix_rows_, matrix_cols_;
184  bool parameters_set_;
185  double radius_step_, angle_step_;
186 
187 private:
188  friend class cereal::access;
189 
190  template<class Archive> void serialize(Archive &ar) {
191  ar(polar_map_, map_16SC2_, map_16UC1_, starting_radius_,
192  ending_radius_, n_rings_, n_angles_, matrix_rows_, matrix_cols_,
193  parameters_set_, radius_step_, angle_step_);
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)
Interface with OpenCV Copyright 2007-2022 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:50
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:136