IMP  2.0.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/exception.h"
15 #include "IMP/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",
120  IMP::ValueException);
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",
130  IMP::ValueException);
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 */