27#ifndef improc_imageUtils_hpp
28#define improc_imageUtils_hpp
44template <
typename realT =
double>
47 return 0.5 * ( 1.0 * rows_cols - 1 );
54template <
typename realT =
double,
typename imT>
57 return imCen<realT>( im.rows() );
64template <
typename realT =
double,
typename imT>
67 return imCen<realT>( im.cols() );
75constexpr T invalidNumber()
83 return ( ( ( ( *(uint32_t *)&value ) & 0x7fffffff ) > 0x7f800000 ) || ( value == invalidNumber<float>() ) ||
84 !std::isfinite( value ) );
90template <
typename realT>
99 x1 = xc - ( x0 - xc );
100 y1 = yc - ( y0 - yc );
109template <
class imageT,
typename valueT>
114 for(
int c = 0; c < im.cols(); ++c )
116 for(
int r = 0; r < im.rows(); ++r )
118 if(
IsNan( im( r, c ) ) )
127template <
class imageT>
130 typename imageT::Scalar zero = 0;
131 zeroNaNs<imageT, typename imageT::Scalar>( im, zero );
138template <
class cubeT,
class maskCubeT>
145 mask->resize( imc.rows(), imc.cols(), imc.planes() );
149 for(
int p = 0; p < imc.planes(); ++p )
151 for(
int c = 0; c < imc.cols(); ++c )
153 for(
int r = 0; r < imc.rows(); ++r )
155 if(
IsNan( imc.image( p )( r, c ) ) )
157 imc.image( p )( r, c ) = 0;
160 ( *mask ).image( p )( r, c ) = 1;
169template <
class cubeT>
172 return zeroNaNCube<cubeT, cubeT>( imc,
nullptr );
180template <
class calcT,
class imageT>
183 return static_cast<calcT
>( im.sum() ) / ( im.rows() * im.cols() );
191template <
class calcT,
class imageT,
class maskT>
195 return static_cast<calcT
>( ( im * mask ).sum() ) / ( mask.sum() );
203template <
typename calcT,
class imageT>
208 return ( im.template cast<calcT>() - mn ).square().sum() / ( im.rows() * im.cols() );
216template <
typename calcT,
class imageT,
class maskT>
222 return ( im.template cast<calcT>() * mask - mn ).square().sum() / ( mask.sum() );
229template <
typename imageT>
231 typename imageT::Scalar &y,
238 typename imageT::Scalar sum = im.sum();
242 x = 0.5 * ( im.rows() - 1.0 );
243 y = 0.5 * ( im.cols() - 1.0 );
247 for(
int j = 0; j < im.cols(); ++j )
249 for(
int i = 0; i < im.rows(); ++i )
251 x += ( i + 1 ) * im( i, j );
252 y += ( j + 1 ) * im( i, j );
268template <
typename floatT,
typename imageT,
typename magImageT,
typename transformT>
280 floatT magSize_x = ceil( ( im.rows() - 1.0 ) / scale_x ) + 1;
281 floatT magSize_y = ceil( ( im.cols() - 1.0 ) / scale_y ) + 1;
283 floatT mag_x = ( (floatT)magSize_x - 1.0 ) / ( (floatT)im.rows() - 1.0 );
284 floatT mag_y = ( (floatT)magSize_y - 1.0 ) / ( (floatT)im.cols() - 1.0 );
286 scale_x = 1.0 / mag_x;
287 scale_y = 1.0 / mag_y;
289 magIm.resize( magSize_x, magSize_y );
294 magIm.maxCoeff( &ix, &iy );
307template <
typename floatT,
typename imageT,
typename magImageT>
334template <
typename imageT,
typename imageT1,
typename imageT2,
typename imageT3,
typename imageT4>
337 const imageT2 &mask1,
342 combo.resize( im1.rows(), im2.cols() );
344 for(
int c = 0; c < combo.cols(); ++c )
346 for(
int r = 0; r < combo.rows(); ++r )
348 if( mask1( r, c ) == 1 && mask2( r, c ) == 0 )
349 combo( r, c ) = im1( r, c );
350 else if( mask2( r, c ) == 1 & mask1( r, c ) == 0 )
351 combo( r, c ) = im2( r, c );
352 else if( mask1( r, c ) == 1 && mask2( r, c ) == 1 )
353 combo( r, c ) = 0.5 * ( im1( r, c ) + im2( r, c ) );
360template <
typename eigenT,
typename eigenTin>
361void removeRowsAndCols( eigenT &out,
const eigenTin &in,
int st,
int w )
364 out.resize( in.rows() - w, in.cols() - w );
366 out.topLeftCorner( st, st ) = in.topLeftCorner( st, st );
368 out.bottomLeftCorner( in.rows() - ( st + w ), st ) = in.bottomLeftCorner( in.rows() - ( st + w ), st );
370 out.topRightCorner( st, in.cols() - ( st + w ) ) = in.topRightCorner( st, in.cols() - ( st + w ) );
372 out.bottomRightCorner( in.rows() - ( st + w ), in.cols() - ( st + w ) ) =
373 in.bottomRightCorner( in.rows() - ( st + w ), in.cols() - ( st + w ) );
376template <
typename eigenT,
typename eigenTin>
377void removeRows( eigenT &out,
const eigenTin &in,
int st,
int w )
380 out.resize( in.rows() - w, in.cols() );
382 out.topLeftCorner( st, in.cols() ) = in.topLeftCorner( st, in.cols() );
384 out.bottomLeftCorner( in.rows() - ( st + w ), in.cols() ) =
385 in.bottomLeftCorner( in.rows() - ( st + w ), in.cols() );
388template <
typename eigenT,
typename eigenTin>
389void removeCols( eigenT &out,
const eigenTin &in,
int st,
int w )
392 out.resize( in.rows(), in.cols() - w );
394 out.topLeftCorner( in.rows(), st ) = in.topLeftCorner( in.rows(), st );
396 out.topRightCorner( in.rows(), in.cols() - ( st + w ) ) = in.topRightCorner( in.rows(), in.cols() - ( st + w ) );
404void *
imcpy(
void *dest,
void * imcpy(void *dest, void *src, size_t width, size_t height, size_t szof)
Copy one image to another, with no transformation.
int imageMaxInterp(floatT &x, floatT &y, floatT &scale_x, floatT &scale_y, magImageT &magIm, const imageT &im, transformT trans)
Find the maximum in an image at sub-pixel resolution by interpolation.
calcT imageVariance(imageT &im, calcT mn)
Calculate the variance of an image given its mean.
int imageCenterOfLight(typename imageT::Scalar &x, typename imageT::Scalar &y, const imageT &im)
Calculate the center of light of an image.
void combine2ImagesMasked(imageT &combo, const imageT1 &im1, const imageT2 &mask1, const imageT3 &im2, const imageT4 &mask2)
Combine two images, each with their own mask defining good pixels.
bool IsNan(float value)
Check if the number is nan, using several different methods.
calcT imageMean(imageT &im)
Calculate the mean value of an image.
void zeroNaNs(imageT &im, valueT val)
Zero any NaNs in an image.
void * imcpy_flipLR(void *dest, void *src, size_t width, size_t height, size_t szof)
Copy one image to another, flipping left-right.
void zeroNaNCube(cubeT &imc, maskCubeT *mask)
Zero any NaNs in an image cube.
void * imcpy_flipUDLR(void *dest, void *src, size_t width, size_t height, size_t szof)
Copy one image to another, flipping up-down and left-right.
void * imcpy_flipUD(void *dest, void *src, size_t width, size_t height, size_t szof)
Copy one image to another, flipping up-down.
int reflectImageCoords(int &x1, int &y1, int x0, int y0, realT xc, realT yc)
Reflect pixel coordinates across the given center pixel.
realT imCen(int rows_cols)
Get the mxlib standard center coordinate of an image.
realT imCenX(const imT &im)
Get the mxlib standard center x-coordinate of an image.
realT imCenY(const imT &im)
Get the mxlib standard center y-coordinate of an image.