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