API
pupilFitter.hpp
Go to the documentation of this file.
1 /** \file pupilFitter.hpp
2  * \brief The MagAO-X Pyramid Pupil Fitter class header
3  *
4  * \ingroup pupilFit_files
5  */
6 
7 #ifndef pupilFitter_hpp
8 #define pupilFitter_hpp
9 
10 #include <mx/improc/eigenImage.hpp>
11 #include <mx/improc/imageUtils.hpp>
12 #include <mx/improc/circleOuterpix.hpp>
13 #include <mx/improc/imageTransforms.hpp>
14 
15 namespace MagAOX
16 {
17 namespace app
18 {
19 
20 /// Struct to perform centration and measure diameter of Pyramid pupils
21 template<typename realT>
22 struct pupilFitter
23 {
24  mx::improc::eigenImage<realT> m_quad;
25  mx::improc::eigenImage<realT> m_quadMag;
26  mx::improc::eigenImage<realT> m_circ;
27  mx::improc::eigenImage<realT> m_circMag;
28 
29  unsigned m_rows {0}; ///< [in] the size of a quad, in rows
30  unsigned m_cols {0}; ///< [in] the size of a quad, in cols
31 
32  int m_numPupils {4}; ///< the number of pupils. Default is 4, 3 is also supported.
33  float m_pupMedIndex {0.6866}; ///< the index of the illuminated pupil median in a sorted array.
34 
35  float m_med[4] = {0,0,0,0};
36  float m_avgx[4] = {0,0,0,0};
37  float m_avgy[4] = {0,0,0,0};
38  float m_avgr[4] = {0,0,0,0};
39 
40  float m_thresh {0.5};
41 
42  std::vector<realT> m_pixs;
43 
45 
46  int setSize( unsigned rows, ///< [in] the new size of a quad, in rows
47  unsigned cols ///< [in] the new size of a quad, in cols
48  );
49 
50  /// Returns the quadrant starting coordinates
51  int quadCoords( size_t & i0, ///< [out] the i coordinate of the lower-left corner of quad
52  size_t & j0, ///< [out] the j coordinate of the lower-left corner of auad
53  int quadNo ///< [in] the quadrant number
54  );
55 
56  int threshold( mx::improc::eigenImage<realT> & im );
57 
58  int getQuad( mx::improc::eigenImage<realT> & quad,
59  mx::improc::eigenImage<realT> & im,
60  int quadNo
61  );
62 
63  int putQuad( mx::improc::eigenImage<realT> & im,
64  mx::improc::eigenImage<realT> & quad,
65  int quadNo
66  );
67 
68  int outerpix( float & avgx,
69  float & avgy,
70  float & avgr,
71  int quadNo
72  );
73 
74  int fit( mx::improc::eigenImage<realT> & im,
75  mx::improc::eigenImage<realT> & edged
76  );
77 
78  //int emitRegion( const std::string fname );
79 
80 };
81 
82 template<typename realT>
83 int pupilFitter<realT>::setSize( unsigned rows,
84  unsigned cols
85  )
86 {
87  m_rows = rows;
88  m_cols = cols;
89 
90  m_quad.resize(m_rows,m_cols);
91  m_circ.resize(m_rows,m_cols);
92 
93  //Set up for the magnified version
94  m_quadMag.resize(m_quad.rows()*10, m_quad.cols()*10);
95  m_circMag.resize(m_circ.rows()*10, m_circ.cols()*10);
96 
97  m_pixs.resize(m_quadMag.rows()*m_quadMag.cols());
98 
99  return 0;
100 }
101 
102 template<typename realT>
104  size_t & j0,
105  int quadNo
106  )
107 {
108  if(m_numPupils == 3)
109  {
110  i0 = 0;
111  j0 = 0;
112 
113  if(quadNo == 1)
114  {
115  i0 = m_rows;
116  }
117  if(quadNo == 2)
118  {
119  i0 = 0.5*m_rows;
120  j0 = m_cols;
121  }
122  }
123  else
124  {
125  i0=0;
126  j0=0;
127 
128  if(quadNo == 1) i0 = m_rows;
129  if(quadNo == 2) j0 = m_cols;
130  if(quadNo == 3)
131  {
132  i0 = m_rows;
133  j0 = m_cols;
134  }
135 
136  }
137 
138  return 0;
139 }
140 
141 template<typename realT>
142 int pupilFitter<realT>::threshold( mx::improc::eigenImage<realT> & im )
143 {
144  for(int i =0; i< im.rows(); ++i)
145  {
146  for(int j=0; j< im.cols(); ++j)
147  {
148  if(im(i,j) >= m_thresh) im(i,j) = 1;
149  else im(i,j) = 0;
150  }
151  }
152 
153  return 0;
154 }
155 
156 template<typename realT>
157 int pupilFitter<realT>::getQuad( mx::improc::eigenImage<realT> & quad,
158  mx::improc::eigenImage<realT> & im,
159  int quadNo
160  )
161 {
162 
163  if(im.rows() != 2*m_rows || im.cols() != 2*m_cols)
164  {
165  return -1;
166  }
167 
168  size_t i0=0, j0=0;
169  quadCoords(i0, j0, quadNo);
170 
171  for(size_t i =i0; i< i0+m_rows; ++i)
172  {
173  for(size_t j=j0; j<j0+m_cols;++j)
174  {
175  quad(i-i0, j-j0) = im(i,j);
176  }
177  }
178 
179  return 0;
180 }
181 
182 template<typename realT>
183 int pupilFitter<realT>::putQuad( mx::improc::eigenImage<realT> & im,
184  mx::improc::eigenImage<realT> & quad,
185  int quadNo
186  )
187 {
188  if(im.rows() != 2*m_rows || im.cols() != 2*m_cols)
189  {
190  return -1;
191  }
192 
193  size_t i0=0, j0=0;
194  quadCoords(i0, j0, quadNo);
195 
196  for(size_t i =i0; i< i0+m_rows; ++i)
197  {
198  for(size_t j=j0; j<j0+m_cols;++j)
199  {
200  im(i,j) = quad(i-i0, j-j0);;
201  }
202  }
203 
204  return 0;
205 }
206 
207 template<typename realT>
209  float & avgy,
210  float & avgr,
211  int quadNo
212  )
213 {
214 
215  realT x0, y0, avgr0;
216 
217  mx::improc::circleOuterpix(x0, y0, avgr0, avgx, avgy, avgr, m_circMag, m_quadMag);
218 
219  avgx/=10.0;
220  avgy/=10.0;
221  avgr/=10.0;
222 
223  size_t i0=0, j0=0;
224  quadCoords(i0, j0, quadNo);
225 
226  avgx += i0;
227  avgy += j0;
228 
229  return 0;
230 
231 }
232 
233 
234 
235 template<typename realT>
236 int pupilFitter<realT>::fit( mx::improc::eigenImage<realT> & im,
237  mx::improc::eigenImage<realT> & edged
238  )
239 {
240  mx::improc::eigenImage<realT> imin = im;
241  im.setZero();
242  for(int i=0; i< m_numPupils; ++i)
243  {
244  // 0) magnify the image
245  getQuad(m_quad, imin, i);
246 
247  mx::improc::imageMagnify(m_quadMag, m_quad, mx::improc::bilinearTransform<realT>());
248 
249  // 1) normalize by median of pupil
250 
251  for(size_t j=0; j < m_pixs.size(); ++j) m_pixs[j] = m_quadMag.data()[j];
252 
253  std::sort(m_pixs.begin(), m_pixs.end());
254 
255  m_med[i] = m_pixs[m_pupMedIndex*m_pixs.size()]; //This should be the median of the pupils if the right size and contained in the quad
256 
257  m_quadMag/=m_med[i];
258 
259  // 2) Threshold the normalized quad
260  threshold(m_quadMag);
261 
262  // 3) Find outer pixels and the radius
263  outerpix(m_avgx[i], m_avgy[i], m_avgr[i], i);
264 
265  // 4) De-magnify and prepare for putting on the streams
266  mx::improc::imageRebinSum( m_quad, m_quadMag, true);
267  mx::improc::imageRebinSum( m_circ, m_circMag);
268  putQuad(im, m_quad, i);
269  putQuad(edged, m_circ, i);
270  }
271 
272  return 0;
273 }
274 } //namespace app
275 } //namespace MagAOX
276 
277 #endif //pupilFitter_hpp
Definition: dm.hpp:24
Struct to perform centration and measure diameter of Pyramid pupils.
Definition: pupilFitter.hpp:23
int m_numPupils
the number of pupils. Default is 4, 3 is also supported.
Definition: pupilFitter.hpp:32
unsigned m_rows
[in] the size of a quad, in rows
Definition: pupilFitter.hpp:29
std::vector< realT > m_pixs
Definition: pupilFitter.hpp:42
int putQuad(mx::improc::eigenImage< realT > &im, mx::improc::eigenImage< realT > &quad, int quadNo)
int outerpix(float &avgx, float &avgy, float &avgr, int quadNo)
unsigned m_cols
[in] the size of a quad, in cols
Definition: pupilFitter.hpp:30
int getQuad(mx::improc::eigenImage< realT > &quad, mx::improc::eigenImage< realT > &im, int quadNo)
mx::improc::eigenImage< realT > m_circMag
Definition: pupilFitter.hpp:27
int setSize(unsigned rows, unsigned cols)
Definition: pupilFitter.hpp:83
mx::improc::eigenImage< realT > m_quadMag
Definition: pupilFitter.hpp:25
int quadCoords(size_t &i0, size_t &j0, int quadNo)
Returns the quadrant starting coordinates.
int threshold(mx::improc::eigenImage< realT > &im)
mx::improc::eigenImage< realT > m_circ
Definition: pupilFitter.hpp:26
mx::improc::eigenImage< realT > m_quad
Definition: pupilFitter.hpp:24
float m_pupMedIndex
the index of the illuminated pupil median in a sorted array.
Definition: pupilFitter.hpp:33
int fit(mx::improc::eigenImage< realT > &im, mx::improc::eigenImage< realT > &edged)