13#pragma GCC system_header
16#include "../math/vectorUtils.hpp"
28template <
typename dataT>
32 typedef bool is_eigenCube;
35 typedef typename Eigen::Array<dataT, Eigen::Dynamic, Eigen::Dynamic>::Index Index;
37 typedef Eigen::Map<Eigen::Array<dataT, Eigen::Dynamic, Eigen::Dynamic>> imageRef;
39 typedef Eigen::Array<dataT, Eigen::Dynamic, Eigen::Dynamic> imageT;
46 dataT *m_data{
nullptr };
82 void resize(
int r,
int c,
int p );
84 void resize(
int r,
int c );
88 const dataT *data()
const;
90 const Index rows()
const;
92 const Index cols()
const;
94 const Index planes()
const;
97 Eigen::Map<Eigen::Array<dataT, Eigen::Dynamic, Eigen::Dynamic>>
cube();
100 Eigen::Map<Eigen::Array<dataT, Eigen::Dynamic, Eigen::Dynamic>>
image( Index n );
103 const Eigen::Map<Eigen::Array<dataT, Eigen::Dynamic, Eigen::Dynamic>>
107 Eigen::Map<Eigen::Array<dataT, Eigen::Dynamic, Eigen::Dynamic>,
109 Eigen::Stride<Eigen::Dynamic, Eigen::Dynamic>>
113 Eigen::Map<Eigen::Array<dataT, Eigen::Dynamic, Eigen::Dynamic>>
asVectors();
116 void Covar( Eigen::Matrix<dataT, Eigen::Dynamic, Eigen::Dynamic> &cv );
122 template <
typename eigenT>
129 template <
typename eigenT>
137 template <
typename eigenT,
typename eigenCubeT>
141 double minGoodFract = 0.0
149 template <
typename eigenT>
151 std::vector<dataT> &weights
159 template <
typename eigenT,
typename eigenCubeT>
161 std::vector<dataT> &weights,
163 double minGoodFract =
171 template <
typename eigenT>
178 template <
typename eigenT>
188 template <
typename eigenT,
typename eigenCubeT>
193 double minGoodFract =
201 template <
typename eigenT>
203 std::vector<dataT> &weights,
212 template <
typename eigenT,
typename eigenCubeT>
215 std::vector<dataT> &weights,
218 double minGoodFract =
223template <
typename dataT>
232template <
typename dataT>
239 m_data =
new dataT[_rows * _cols * _planes];
243template <
typename dataT>
254template <
typename dataT>
257 if( _owner && m_data )
263template <
typename dataT>
264void eigenCube<dataT>::setZero()
266 int N = _rows * _cols * _planes;
268 for(
int i = 0; i < N; ++i )
269 m_data[i] = ( (dataT)0 );
272template <
typename dataT>
273eigenCube<dataT> &eigenCube<dataT>::operator=(
const eigenCube<dataT> &ec )
275 resize( ec.rows(), ec.cols(), ec.planes() );
277 int N = _rows * _cols * _planes;
279 for(
int i = 0; i < N; ++i )
280 m_data[i] = ec.m_data[i];
285template <
typename dataT>
286void eigenCube<dataT>::shallowCopy( eigenCube<dataT> &src,
bool takeOwner )
288 if( _owner && m_data )
296 _planes = src._planes;
299 if( takeOwner ==
true )
310template <
typename dataT>
313 if( _owner && m_data )
323template <
typename dataT>
326 if( _owner && m_data )
335 m_data =
new dataT[_rows * _cols * _planes];
339template <
typename dataT>
340void eigenCube<dataT>::resize(
int r,
int c )
345template <
typename dataT>
346dataT *eigenCube<dataT>::data()
351template <
typename dataT>
352const dataT *eigenCube<dataT>::data()
const
357template <
typename dataT>
358const typename eigenCube<dataT>::Index eigenCube<dataT>::rows()
const
363template <
typename dataT>
364const typename eigenCube<dataT>::Index eigenCube<dataT>::cols()
const
369template <
typename dataT>
370const typename eigenCube<dataT>::Index eigenCube<dataT>::planes()
const
375template <
typename dataT>
378 return Eigen::Map<Eigen::Array<dataT, Eigen::Dynamic, Eigen::Dynamic>>( m_data, _rows * _cols, _planes );
381template <
typename dataT>
384 return Eigen::Map<Eigen::Array<dataT, Eigen::Dynamic, Eigen::Dynamic>>( m_data + n * _rows * _cols, _rows, _cols );
387template <
typename dataT>
390 return Eigen::Map<Eigen::Array<dataT, Eigen::Dynamic, Eigen::Dynamic>>( m_data + n * _rows * _cols, _rows, _cols );
393template <
typename dataT>
394Eigen::Map<Eigen::Array<dataT, Eigen::Dynamic, Eigen::Dynamic>,
396 Eigen::Stride<Eigen::Dynamic, Eigen::Dynamic>>
399 return Eigen::Map<Eigen::Array<dataT, Eigen::Dynamic, Eigen::Dynamic>,
401 Eigen::Stride<Eigen::Dynamic, Eigen::Dynamic>>(
402 m_data + j * _rows + i, _planes, 1, Eigen::Stride<Eigen::Dynamic, Eigen::Dynamic>( 0, _rows * _cols ) );
405template <
typename dataT>
408 return Eigen::Map<Eigen::Array<dataT, Eigen::Dynamic, Eigen::Dynamic>>( m_data, _rows * _cols, _planes );
411template <
typename dataT>
414 cv = asVectors().matrix().transpose() * asVectors().matrix();
417template <
typename dataT>
418template <
typename eigenT>
421 mim.resize( _rows, _cols );
423#pragma omp parallel for schedule( static, 1 ) num_threads( Eigen::nbThreads() )
424 for( Index i = 0; i < _rows; ++i )
426 for( Index j = 0; j < _cols; ++j )
428 mim( i, j ) = pixel( i, j ).sum();
433template <
typename dataT>
434template <
typename eigenT>
437 mim.resize( _rows, _cols );
439#pragma omp parallel for schedule( static, 1 ) num_threads( Eigen::nbThreads() )
440 for( Index i = 0; i < _rows; ++i )
442 for( Index j = 0; j < _cols; ++j )
444 mim( i, j ) = pixel( i, j ).mean();
449template <
typename dataT>
450template <
typename eigenT,
typename eigenCubeT>
453 mim.resize( _rows, _cols );
457 std::vector<dataT> work;
460 for( Index i = 0; i < _rows; ++i )
462 for( Index j = 0; j < _cols; ++j )
467 for( Index k = 0; k < _planes; ++k )
469 if( ( mask.pixel( i, j ) )( k, 0 ) == 1 )
471 work.push_back( ( pixel( i, j ) )( k, 0 ) );
475 if( work.size() > minGoodFract * _planes )
481 mim( i, j ) = invalidNumber<float>();
488template <
typename dataT>
489template <
typename eigenT>
492 mim.resize( _rows, _cols );
494#pragma omp parallel num_threads( Eigen::nbThreads() )
496 std::vector<Scalar> work;
498#pragma omp for schedule( static, 10 )
499 for( Index i = 0; i < _rows; ++i )
501 for( Index j = 0; j < _cols; ++j )
503 work.resize( _planes );
505 for(
int k = 0; k < _planes; ++k )
506 work[k] = ( pixel( i, j ) )( k, 0 );
514template <
typename dataT>
515template <
typename eigenT,
typename eigenCubeT>
518 mim.resize( _rows, _cols );
520#pragma omp parallel num_threads( Eigen::nbThreads() )
522 std::vector<Scalar> work, wwork;
524#pragma omp for schedule( static, 10 )
525 for( Index i = 0; i < _rows; ++i )
527 for( Index j = 0; j < _cols; ++j )
534 for( Index k = 0; k < _planes; ++k )
536 if( ( mask.pixel( i, j ) )( k, 0 ) == 1 )
538 work.push_back( ( pixel( i, j ) )( k, 0 ) );
539 wwork.push_back( weights[k] );
542 if( work.size() > minGoodFract * _planes )
547 mim( i, j ) = invalidNumber<float>();
553template <
typename dataT>
554template <
typename eigenT>
557 mim.resize( _rows, _cols );
559#pragma omp parallel for schedule( static, 10 ) num_threads( Eigen::nbThreads() )
560 for( Index i = 0; i < _rows; ++i )
563 std::vector<Scalar> work;
564 for( Index j = 0; j < _cols; ++j )
571template <
typename dataT>
572template <
typename eigenT>
575 mim.resize( _rows, _cols );
577 #pragma omp parallel num_threads( Eigen::nbThreads() )
579 std::vector<Scalar> work;
581 #pragma omp for schedule( static, 10 )
582 for( Index i = 0; i < _rows; ++i )
584 for( Index j = 0; j < _cols; ++j )
586 work.resize( _planes );
587 for(
int k = 0; k < _planes; ++k )
588 work[k] = ( pixel( i, j ) )( k, 0 );
596template <
typename dataT>
597template <
typename eigenT,
typename eigenCubeT>
600 mim.resize( _rows, _cols );
604 std::vector<Scalar> work;
607 for( Index i = 0; i < _rows; ++i )
609 for( Index j = 0; j < _cols; ++j )
614 for( Index k = 0; k < _planes; ++k )
616 if( ( mask.pixel( i, j ) )( k, 0 ) == 1 )
618 work.push_back( ( pixel( i, j ) )( k, 0 ) );
622 if( work.size() > minGoodFract * _planes )
628 mim( i, j ) = invalidNumber<float>();
635template <
typename dataT>
636template <
typename eigenT>
639 mim.resize( _rows, _cols );
641#pragma omp parallel num_threads( Eigen::nbThreads() )
643 std::vector<Scalar> work;
645#pragma omp for schedule( static, 10 )
646 for( Index i = 0; i < _rows; ++i )
648 for( Index j = 0; j < _cols; ++j )
650 work.resize( _planes );
652 for(
int k = 0; k < _planes; ++k )
653 work[k] = ( pixel( i, j ) )( k, 0 );
661template <
typename dataT>
662template <
typename eigenT,
typename eigenCubeT>
664 eigenT &mim, std::vector<dataT> &weights, eigenCubeT &mask, dataT sigma,
double minGoodFract )
666 mim.resize( _rows, _cols );
668#pragma omp parallel num_threads( Eigen::nbThreads() )
670 std::vector<Scalar> work, wwork;
672#pragma omp for schedule( static, 10 )
673 for( Index i = 0; i < _rows; ++i )
675 for( Index j = 0; j < _cols; ++j )
682 for( Index k = 0; k < _planes; ++k )
684 if( ( mask.pixel( i, j ) )( k, 0 ) == 1 )
686 work.push_back( ( pixel( i, j ) )( k, 0 ) );
687 wwork.push_back( weights[k] );
690 if( work.size() > minGoodFract * _planes )
695 mim( i, j ) = invalidNumber<float>();
An image cube with an Eigen-like API.
void sigmaMean(eigenT &mim, std::vector< dataT > &weights, eigenCubeT &mask, Scalar sigma, double minGoodFract=0.0)
Calculate the sigma clipped weighted mean image of the cube, with a mask cube.
void Covar(Eigen::Matrix< dataT, Eigen::Dynamic, Eigen::Dynamic > &cv)
Calculate the covariance matrix of the images in the cube.
void sigmaMean(eigenT &mim, Scalar sigma)
Calculate the sigma clipped mean image of the cube.
void mean(eigenT &mim, std::vector< dataT > &weights, eigenCubeT &mask, double minGoodFract=0.0)
Calculate the weighted mean image of the cube, with a mask cube.
void clear()
De-allocate and set all sizes to 0.
const Eigen::Map< Eigen::Array< dataT, Eigen::Dynamic, Eigen::Dynamic > > image(Index n) const
Returns a 2D Eigen::Eigen::Map pointed at the specified image.
void sum(eigenT &mim)
Calculate the sum image of the cube.
void sigmaMean(eigenT &mim, std::vector< dataT > &weights, Scalar sigma)
Calculate the sigma clipped weighted mean image of the cube.
Eigen::Map< Eigen::Array< dataT, Eigen::Dynamic, Eigen::Dynamic >, Eigen::Unaligned, Eigen::Stride< Eigen::Dynamic, Eigen::Dynamic > > pixel(Index i, Index j)
Returns an Eigen::Eigen::Map-ed vector of the pixels at the given coordinate.
void median(eigenT &mim)
Calculate the median image of the cube.
void mean(eigenT &mim, std::vector< dataT > &weights)
Calculate the weighted mean image of the cube.
Eigen::Map< Eigen::Array< dataT, Eigen::Dynamic, Eigen::Dynamic > > cube()
Returns a 2D Eigen::Eigen::Map pointed at the entire cube.
void mean(eigenT &mim, eigenCubeT &mask, double minGoodFract=0.0)
Calculate the mean image of the cube with a mask.
void mean(eigenT &mim)
Calculate the mean image of the cube.
eigenCube(dataT *ndata, size_t nrows, size_t ncols, size_t nplanes)
C'tor taking an existing array as an argument.
void sigmaMean(eigenT &mim, eigenCubeT &mask, Scalar sigma, double minGoodFract=0.0)
Calculate the sigma clipped mean image of the cube, with a mask cube.
eigenCube(Index nrows, Index ncols, Index nplanes)
C'tor which will allocate space..
Eigen::Map< Eigen::Array< dataT, Eigen::Dynamic, Eigen::Dynamic > > asVectors()
Return an Eigen::Eigen::Map of the cube where each image is a vector.
Eigen::Map< Eigen::Array< dataT, Eigen::Dynamic, Eigen::Dynamic > > image(Index n)
Returns a 2D Eigen::Eigen::Map pointed at the specified image.
Tools for using the eigen library for image processing.
imageT::Scalar imageMedian(const imageT &mat, const maskT *mask, std::vector< typename imageT::Scalar > *work=0)
Calculate the median of an Eigen-like array.
vectorT::value_type vectorSigmaMean(const vectorT &vec, const vectorT *weights, const sigmaT &sigma, int &maxPasses)
Calculate the sigma-clipped mean of a vector.
valueT vectorMean(const valueT *vec, size_t sz)
Calculate the mean of a vector.
Header for the image processing utilities.