27 #ifndef fitGaussian_hpp
28 #define fitGaussian_hpp
33 #include "../../mxError.hpp"
35 #include "../func/gaussian.hpp"
36 #include "../constants.hpp"
38 #include "../../improc/eigenImage.hpp"
57 template<
typename _realT>
58 struct gaussian1D_fitter;
64 template<
typename _realT>
69 static const int nparams = 4;
71 static void func(realT *p, realT *hx,
int m,
int n,
void *adata)
75 realT G0 = arr->G0(p);
77 realT x0 = arr->x0(p);
78 realT
sigma = arr->sigma(p);
84 for(
int i=0; i<arr->
m_nx; ++i)
86 if(arr->
m_mask[i] == 0)
continue;
92 for(
int i=0; i<arr->
m_nx; ++i)
94 if(arr->
m_mask[i] == 0)
continue;
95 hx[i] = func::gaussian<realT>(i, G0,
G, x0,
sigma) - arr->
m_data[i];
103 for(
int i=0; i<arr->
m_nx; ++i)
110 for(
int i=0; i<arr->
m_nx; ++i)
112 hx[i] = func::gaussian<realT>(i, G0,
G, x0,
sigma) - arr->
m_data[i];
144 template<
typename _realT>
150 typedef _realT realT;
160 this->allocate_params(arr.nparams());
185 this->allocate_params(arr.nparams());
200 arr.sigma(this->p,
sigma);
241 return arr.G0( this->p );
247 return arr.G( this->p );
253 return arr.x0( this->p );
261 return arr.sigma( this->p );
266 extern template class fitGaussian1D<float>;
267 extern template class fitGaussian1D<double>;
288 template<
typename _realT>
289 struct gaussian2D_sym_fitter;
292 template<
typename _realT>
293 struct gaussian2D_gen_fitter;
295 template<
typename _realT>
296 struct gaussian2D_gen_fitter_bgfixed;
321 template<
typename fitterT>
327 typedef typename fitterT::realT realT;
333 if(fitterT::maxNparams == 5)
341 this->allocate_params(arr.nparams());
366 arr.
setFixed(G0,
G, x0, y0, sigma_x, sigma_y, theta);
367 this->allocate_params(arr.nparams());
381 this->allocate_params(arr.nparams());
398 arr.sigma(this->p,
sigma);
418 arr.sigma_x(this->p,sigma_x);
419 arr.sigma_y(this->p,sigma_y);
420 arr.theta(this->p,theta);
451 for(
int j=0;j<nx; ++j)
453 for(
int i=0;i<ny; ++i)
457 this->n += arr.
mask[idx_mat];
467 fitter.paramNormalizer(&arr, this->p, 1);
471 fitter.paramNormalizer(&arr, this->p, -1);
472 fitter.paramNormalizer(&arr, this->init_p, -1);
483 return arr.G0(this->p);
489 return arr.G(this->p);
495 return arr.x0(this->p);
501 return arr.y0(this->p);
511 return arr.sigma(this->p);
525 return arr.sigma_x(this->p);
531 return arr.sigma_y(this->p);
537 return arr.theta(this->p);
549 template<
typename _realT>
552 typedef _realT realT;
554 static const int maxNparams = 5;
556 static void func(realT *p, realT *hx,
int m,
int n,
void *adata)
560 size_t idx_mat, idx_dat;
564 for(
int j=0;j<arr->
ny; j++)
566 for(
int i=0;i<arr->
nx;i++)
568 idx_mat = i+j*arr->
nx;
570 hx[idx_dat] = func::gaussian2D<realT>(i,j,p[0],p[1], p[2], p[3], p[4]) - arr->data[idx_mat];
592 template<
typename _realT>
595 typedef _realT realT;
597 static const int maxNparams = 7;
599 static void func(realT *p, realT *hx,
int m,
int n,
void *adata)
603 size_t idx_mat, idx_dat;
605 realT G0 = arr->G0(p);
607 realT x0 = arr->x0(p);
608 realT y0 = arr->y0(p);
614 if( a*
c - b*b <= 0 || a <= 0 ||
c <= 0 || a+
c <= 2*fabs(b))
618 if(arr->
mask ==
nullptr)
620 for(
int j=0;j<arr->
ny; ++j)
622 for(
int i=0;i<arr->
ny; ++i)
624 idx_mat = i+j*arr->
nx;
625 hx[idx_dat] = arr->
data[idx_mat];
632 for(
int j=0;j<arr->
ny; ++j)
634 for(
int i=0;i<arr->
ny; ++i)
636 idx_mat = i+j*arr->
nx;
637 if(arr->
mask[idx_mat]==0)
continue;
638 hx[idx_dat] = arr->
data[idx_mat];
650 if(arr->
mask ==
nullptr)
652 for(
int j=0;j<arr->
ny; ++j)
654 for(
int i=0;i<arr->
nx; ++i)
656 idx_mat = i+j*arr->
nx;
658 hx[idx_dat] = func::gaussian2D<realT>(i,j, G0,
G, x0, y0, a, b,
c) - arr->
data[idx_mat];
666 for(
int j=0;j<arr->
ny; ++j)
668 for(
int i=0;i<arr->
nx; ++i)
670 idx_mat = i+j*arr->
nx;
672 if(arr->
mask[idx_mat] == 0)
678 hx[idx_dat] = func::gaussian2D<realT>(i,j, G0,
G, x0, y0, a, b,
c) - arr->
data[idx_mat];
698 realT sx = arr->sigma_x(p);
699 realT sy = arr->sigma_y(p);
700 realT th = arr->theta(p);
713 realT na = arr->a(p);
714 realT nb = arr->b(p);
715 realT nc = arr->c(p);
734 template<
typename realT>
740 template<
typename realT>
749 template<
typename realT>
766 Ag = im( (
int) xg, (
int) yg);
767 for(
int i =0; i< 2*maxWidth+1; ++i)
769 for(
int j=0; j< 2*maxWidth+1; ++j)
771 if( im( (
int)(xg0 - maxWidth + i), (
int) (yg0 - maxWidth + j)) > Ag )
773 Ag = im( (
int) (xg0 - maxWidth + i), (
int) (yg0 - maxWidth + j));
774 xg = xg0 - maxWidth + i;
775 yg = yg0 - maxWidth + j;
780 realT dAng = math::two_pi<realT>()/nAngs;
787 realT minD = widthWidth;
790 for(
int i=0; i < nAngs; ++i)
795 for(
int j=0; j < widthWidth; ++j)
797 if( im( (
int)(xg + j*
c), (
int)(yg + j*s)) <= 0.5*Ag )
818 realT minang = fmod(minDidx * dAng - 0.5*math::pi<realT>(), math::pi<realT>());
819 if(minang < 0) minang = fmod(minang + math::two_pi<realT>(), math::pi<realT>());
821 realT maxang = fmod(maxDidx * dAng, math::pi<realT>());
824 angG = 0.5*(minang + maxang);
833 int guessGauss2D_ang<float>(
float & Ag,
848 int guessGauss2D_ang<double>(
double & Ag,
Wrapper for a native array to pass to levmarInterface, with 1D Gaussian details.
Wrapper for a native array to pass to levmarInterface, with 2D Gaussian details.
Class to manage fitting a 1D Gaussian to data via the levmarInterface.
realT G()
Get the peak scaling.
realT sigma()
Return sigma.
void setArray(realT *data, realT *coords, int nx)
Set the data aray.
realT G0()
Get the current value of G0, the constant.
void setGuess(realT G0, realT G, realT x0, realT sigma)
Set the initial guess for a symmetric Gaussian.
void setFixed(bool G0, bool G, bool x0, bool sigma)
Set whether each parameter is fixed.
realT x0()
Get the center x-coordinate.
void setArray(realT *data, int nx)
Set the data aray.
Class to manage fitting a 2D Gaussian to data via the levmarInterface.
realT x0()
Get the center x-coordinate.
void setGuess(realT G0, realT G, realT x0, realT y0, realT sigma)
Set the initial guess for a symmetric Gaussian.
void setFixed(bool G0, bool G, bool x0, bool y0, bool sigma_x, bool sigma_y, bool theta)
Set whether each parameter is fixed.
realT theta()
Return the orientation of the long axis.
realT y0()
Get the center y-coordinate.
array2FitGaussian2D< realT > arr
Data array to pass to the levmar library. Contains the actual data plus the parameters if fixed.
realT sigma()
Return the width parameter.
void setArray(realT *data, int nx, int ny)
Set the data aray.
realT G0()
Get the current value of G0, the constant.
void setGuess(realT G0, realT G, realT x0, realT y0, realT sigma_x, realT sigma_y, realT theta)
Set the initial guess for the general Gaussian.
realT fwhm()
Return the full-width at half maximum.
realT sigma_y()
Return the width parameter on the short axis.
void setFixed(bool G0, bool G, bool x0, bool y0, bool sigma)
Set whether each parameter is fixed.
realT G()
Get the peak scaling.
realT sigma_x()
Return the width parameter on the long axis.
void setArray(realT *data, int nx, int ny, realT *mask)
Set the data aray, with a mask.
A templatized interface to the levmar package.
int fit()
Perform the fit.
constexpr units::realT G()
Newton's Gravitational Constant.
constexpr units::realT c()
The speed of light.
constexpr units::realT sigma()
Stefan-Boltzmann Constant.
Eigen::Array< scalarT, -1, -1 > eigenImage
Definition of the eigenImage type, which is an alias for Eigen::Array.
int guessGauss2D_ang(realT &Ag, realT &xg, realT &yg, realT &xFWHM, realT &yFWHM, realT &angG, mx::improc::eigenImage< realT > &im, realT maxWidth, realT widthWidth, realT nAngs, realT xg0, realT yg0)
Form an estimate of the parameters of an elliptical Gaussian from a 2D image.
floatT sigma2fwhm(floatT sig)
Convert from Gaussian width parameter to FWHM.
void gaussian2D_gen2rot(realT &sigma_x, realT &sigma_y, realT &theta, const realT a, const realT b, const realT c)
Convert from (a,b,c) to ( , , ) for the elliptical Gaussian.
void gaussian2D_rot2gen(realT &a, realT &b, realT &c, const realT sigma_x, const realT sigma_y, const realT theta)
Convert from ( , , ) to (a,b,c) for the elliptical Gaussian.
A c++ interface to the templatized levmar minimization routines..
Wrapper for a native array to pass to levmarInterface, with !D Gaussian details.
size_t m_nx
X dimension of the array.
realT * m_mask
Pointer to the (optional) mask array. Any 0 pixels are excluded from the fit.
realT * m_coords
Pointer to the array of x values (optional)
realT * m_data
///< Pointer to the array of y values
void setFixed(bool G0, bool G, bool x0, bool sigma)
Set whether each parameter is fixed.
Wrapper for a native array to pass to levmarInterface, with 2D Gaussian details.
size_t ny
Y dimension of the array.
void setFixed(bool G0, bool G, bool x0, bool y0, bool sigma_x, bool sigma_y, bool theta)
Set whether each parameter is fixed.
size_t nx
X dimension of the array.
realT * data
Pointer to the array.
realT * mask
Pointer to the (optional) mask array. Any 0 pixels are excluded from the fit.
Wrapper for a native array to pass to levmarInterface.
size_t ny
X dimension of the array.
size_t nx
Pointer to the array.
levmarInterface fitter structure for the symmetric Gaussian.
levmarInterface fitter structure for the general elliptical Gaussian.
Alias for the fitGaussian1D type fitting the gaussian.
void paramNormalizer(array2FitGaussian2D< realT > *arr, realT *p, int dir)
Does nothing in this case.