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