27 #ifndef imagingUtils_hpp
28 #define imagingUtils_hpp
32 #include "../math/constants.hpp"
33 #include "../mxError.hpp"
53 template<
typename realT>
59 return (lambda/metersPerPixel) * (1./pixels);
71 template<
class arrayT>
73 typename arrayT::Scalar eps=0,
74 typename arrayT::Scalar rad=0,
75 typename arrayT::Scalar overscan = 0
81 mxError(
"circularPupil", MXE_INVALIDARG,
"Central obscuration can not be < 0." );
87 mxError(
"circularPupil", MXE_INVALIDARG,
"Central obscuration can not be > 1." );
94 typename arrayT::Scalar r;
95 typename arrayT::Scalar xc = 0.5*(l0-1);
96 typename arrayT::Scalar yc = 0.5*(l1-1);
98 if(rad <= 0) rad = 0.5*std::min(l0-1, l1-1);
100 for(
size_t i=0; i < l0; i++)
102 for(
size_t j=0; j < l1; j++)
104 r = std::sqrt( std::pow(i-xc, 2) + std::pow(j-yc, 2) );
106 if(r <= rad+( overscan ) && r >= eps*rad) m(i,j) = 1;
119 template<
class arrayT>
120 void drawLine( arrayT & im,
121 typename arrayT::Scalar x0,
122 typename arrayT::Scalar y0,
123 typename arrayT::Scalar x1,
124 typename arrayT::Scalar y1,
125 typename arrayT::Scalar halfWidth
132 typename arrayT::Scalar xc, yc;
134 xc = 0.5*(im.rows()-1);
135 yc = 0.5*(im.cols()-1);
138 typename arrayT::Scalar m = (y1-y0)/(x1-x0);
143 for(
int x = x0; x<=x1; ++x)
147 for(
int i=0; i<= halfWidth; ++i)
149 if( x+xc >= 0 && x+xc < d1 && y+yc+i >= 0 && y+yc+i < d2) im(x+xc,y+yc+i) = 0;
150 if( x+xc >= 0 && x+xc < d1 && y+yc-i >= 0 && y+yc-i < d2) im(x+xc,y+yc-i) = 0;
156 for(
int x = x1; x<=x0; ++x)
160 for(
int i=0; i<= halfWidth; ++i)
162 if( x+xc >= 0 && x+xc < d1 && y+yc+i >= 0 && y+yc+i < d2) im(x+xc,y+yc+i) = 0;
163 if( x+xc >= 0 && x+xc < d1 && y+yc-i >= 0 && y+yc-i < d2) im(x+xc,y+yc-i) = 0;
182 template<
typename arrayOutT,
typename arrayInT>
184 const arrayInT & realPupil,
185 int wavefrontSizePixels)
188 complexPupil.resize(wavefrontSizePixels, wavefrontSizePixels);
189 complexPupil.set(
typename arrayOutT::Scalar(0,0));
192 int bl = 0.5*(complexPupil.rows()-1) - 0.5*(realPupil.rows()-1.);
194 for(
int i=0; i< realPupil.cols(); ++i)
196 for(
int j=0; j < realPupil.rows(); ++j)
198 complexPupil(bl+i, bl+j) =
typename arrayOutT::Scalar(realPupil(i,j),0);
216 template<
typename arrayOutT,
typename arrayInT>
218 const arrayInT & realAmplitude,
219 const arrayInT & realPhase,
220 int wavefrontSizePixels)
223 complexWavefront.resize(wavefrontSizePixels, wavefrontSizePixels);
224 complexWavefront.set(
typename arrayOutT::Scalar(0,0));
227 int bl = 0.5*(complexWavefront.rows()-1) - 0.5*(realAmplitude.rows()-1.);
229 for(
int i=0; i< realAmplitude.cols(); ++i)
231 for(
int j=0; j < realAmplitude.rows(); ++j)
233 complexWavefront(bl+j, bl+i) = realAmplitude(j,i)*exp( (
typename arrayOutT::Scalar(0,1)) * realPhase(j,i));
247 template<
typename wavefrontT>
249 typename wavefrontT::Scalar::value_type xTilt,
250 typename wavefrontT::Scalar::value_type yTilt)
252 typedef typename wavefrontT::Scalar complexT;
253 typedef typename wavefrontT::Scalar::value_type realT;
255 realT
pi = math::pi<realT>();
257 int wfsSizeX = complexWavefront.cols();
258 int wfsSizeY = complexWavefront.rows();
260 realT xCen = 0.5*(wfsSizeX-1);
261 realT yCen = 0.5*(wfsSizeY-1);
263 realT argX = 2.0*
pi/(wfsSizeX-1.0);
264 realT argY = 2.0*
pi/(wfsSizeY-1.0);
266 for(
int ii=0; ii < wfsSizeX; ++ii)
268 for(
int jj=0; jj < wfsSizeY; ++jj)
270 complexWavefront(ii,jj) = complexWavefront(ii,jj)*exp( complexT( (realT)0., argX*xTilt*(ii-xCen)+argY*yTilt*(jj-yCen)));
275 template<
typename imageT1,
typename imageT2>
276 void extractBlock(imageT1 & im,
285 int im_rows = im.cols();
287 int wf_rows = wf.cols();
289 typedef typename imageT1::Scalar dataT;
296 for(
int j =0; j< imYsz; ++j)
298 im_data = &im.data()[imX0 + (imY0+j)*im_rows];
299 wf_data = &wf.data()[wfX0 + (wfY0+j)*wf_rows];
301 memcpy( im_data, wf_data,
sizeof(dataT)*imXsz);
305 template<
typename realImageT,
306 typename complexImageT>
307 void extractIntensityImage(realImageT & im,
316 int im_rows = im.cols();
318 int wf_rows = wf.cols();
320 typename realImageT::Scalar * im_data;
321 typename complexImageT::Scalar * wf_data;
323 for(
int j =0; j< imXsz; ++j)
325 im_data = &im.data()[imX0 + (imY0+j)*im_rows];
326 wf_data = &wf.data()[wfX0 + (wfY0+j)*wf_rows];
327 for(
int i=0; i<imYsz; ++i)
329 im_data[i] = norm(wf_data[i]);
334 template<
typename realImageT,
335 typename complexImageT>
336 void extractIntensityImageAccum(realImageT & im,
345 int im_rows = im.cols();
347 int wf_rows = wf.cols();
349 typename realImageT::Scalar * im_data;
350 typename complexImageT::Scalar * wf_data;
352 for(
int j =0; j< imXsz; ++j)
354 im_data = &im.data()[imX0 + (imY0+j)*im_rows];
355 wf_data = &wf.data()[wfX0 + (wfY0+j)*wf_rows];
356 for(
int i=0; i<imYsz; ++i)
358 im_data[i] += norm(wf_data[i]);
constexpr T pi()
Get the value of pi.
void makeComplexPupil(arrayOutT &complexWavefront, const arrayInT &realAmplitude, const arrayInT &realPhase, int wavefrontSizePixels)
Create a complex wavefront from a real amplitude and a real phase.
void tiltWavefront(wavefrontT &complexWavefront, typename wavefrontT::Scalar::value_type xTilt, typename wavefrontT::Scalar::value_type yTilt)
Apply a tilt to a wavefront.
realT fftPlateScale(size_t pixels, realT metersPerPixel, realT lambda)
Calculate the angular plate scale (radians per pixel) of an image after propagation by FFT.
int circularPupil(arrayT &m, typename arrayT::Scalar eps=0, typename arrayT::Scalar rad=0, typename arrayT::Scalar overscan=0)
Fill in an Eigen-like array with a circular pupil mask.
Declares and defines a class for managing images.