13 #pragma GCC system_header
14 #include <Eigen/Dense>
17 #include "../math/vectorUtils.hpp"
29 template<
typename dataT>
33 typedef bool is_eigenCube;
36 typedef typename Eigen::Array<dataT,Eigen::Dynamic,Eigen::Dynamic>::Index Index;
38 typedef Eigen::Map<Eigen::Array<dataT, Eigen::Dynamic, Eigen::Dynamic> > imageRef;
40 typedef Eigen::Array<dataT,Eigen::Dynamic,Eigen::Dynamic> imageT;
48 dataT * m_data {
nullptr};
85 void resize(
int r,
int c,
int p);
87 void resize(
int r,
int c);
91 const dataT * data()
const;
93 const Index rows()
const;
95 const Index cols()
const;
97 const Index planes()
const;
100 Eigen::Map<Eigen::Array<dataT, Eigen::Dynamic, Eigen::Dynamic> >
cube();
103 Eigen::Map<Eigen::Array<dataT, Eigen::Dynamic, Eigen::Dynamic> >
image(Index n );
106 const Eigen::Map<Eigen::Array<dataT, Eigen::Dynamic, Eigen::Dynamic> >
image(Index n )
const;
109 Eigen::Map<Eigen::Array<dataT, Eigen::Dynamic, Eigen::Dynamic>, Eigen::Unaligned, Eigen::Stride<Eigen::Dynamic, Eigen::Dynamic> >
pixel(Index i, Index j);
112 Eigen::Map<Eigen::Array<dataT, Eigen::Dynamic, Eigen::Dynamic> >
asVectors();
115 void Covar(Eigen::Matrix<dataT, Eigen::Dynamic, Eigen::Dynamic> & cv);
121 template<
typename eigenT>
128 template<
typename eigenT>
136 template<
typename eigenT,
typename eigenCubeT>
139 double minGoodFract = 0.0
146 template<
typename eigenT>
148 std::vector<dataT> & weights
156 template<
typename eigenT,
typename eigenCubeT>
158 std::vector<dataT> & weights,
160 double minGoodFract = 0.0
167 template<
typename eigenT>
174 template<
typename eigenT>
184 template<
typename eigenT,
typename eigenCubeT>
188 double minGoodFract = 0.0
195 template<
typename eigenT>
197 std::vector<dataT> & weights,
206 template<
typename eigenT,
typename eigenCubeT>
208 std::vector<dataT> & weights,
211 double minGoodFract = 0.0
218 template<
typename dataT>
227 template<
typename dataT>
234 m_data =
new dataT[_rows*_cols*_planes];
238 template<
typename dataT>
249 template<
typename dataT>
258 template<
typename dataT>
259 void eigenCube<dataT>::setZero()
261 int N = _rows*_cols*_planes;
263 for(
int i=0;i<N;++i) m_data[i] = ((dataT) 0);
266 template<
typename dataT>
267 eigenCube<dataT> & eigenCube<dataT>::operator=(
const eigenCube<dataT> & ec)
269 resize(ec.rows(), ec.cols(), ec.planes());
271 int N = _rows*_cols*_planes;
273 for(
int i=0;i<N;++i) m_data[i] = ec.m_data[i];
278 template<
typename dataT>
279 void eigenCube<dataT>::shallowCopy(eigenCube<dataT> & src,
bool takeOwner)
289 _planes = src._planes;
292 if(takeOwner ==
true)
303 template<
typename dataT>
316 template<
typename dataT>
328 m_data =
new dataT[_rows*_cols*_planes];
333 template<
typename dataT>
334 void eigenCube<dataT>::resize(
int r,
int c)
339 template<
typename dataT>
340 dataT * eigenCube<dataT>::data()
345 template<
typename dataT>
346 const dataT * eigenCube<dataT>::data()
const
351 template<
typename dataT>
352 const typename eigenCube<dataT>::Index eigenCube<dataT>::rows()
const
357 template<
typename dataT>
358 const typename eigenCube<dataT>::Index eigenCube<dataT>::cols()
const
363 template<
typename dataT>
364 const typename eigenCube<dataT>::Index eigenCube<dataT>::planes()
const
369 template<
typename dataT>
372 return Eigen::Map<Eigen::Array<dataT, Eigen::Dynamic, Eigen::Dynamic> >(m_data, _rows*_cols, _planes);
375 template<
typename dataT>
378 return Eigen::Map<Eigen::Array<dataT, Eigen::Dynamic, Eigen::Dynamic> >(m_data + n*_rows*_cols, _rows, _cols);
381 template<
typename dataT>
384 return Eigen::Map<Eigen::Array<dataT, Eigen::Dynamic, Eigen::Dynamic> >(m_data + n*_rows*_cols, _rows, _cols);
387 template<
typename dataT>
388 Eigen::Map<Eigen::Array<dataT, Eigen::Dynamic, Eigen::Dynamic>, Eigen::Unaligned, Eigen::Stride<Eigen::Dynamic, Eigen::Dynamic> >
eigenCube<dataT>::pixel(Index i, Index j)
390 return Eigen::Map<Eigen::Array<dataT, Eigen::Dynamic, Eigen::Dynamic>, Eigen::Unaligned, Eigen::Stride<Eigen::Dynamic, Eigen::Dynamic> >(m_data + j*_rows + i, _planes, 1, Eigen::Stride<Eigen::Dynamic, Eigen::Dynamic>(0,_rows*_cols));
393 template<
typename dataT>
396 return Eigen::Map<Eigen::Array<dataT, Eigen::Dynamic, Eigen::Dynamic> >(m_data, _rows*_cols, _planes);
399 template<
typename dataT>
402 cv = asVectors().matrix().transpose()*asVectors().matrix();
405 template<
typename dataT>
406 template<
typename eigenT>
409 mim.resize(_rows, _cols);
411 #pragma omp parallel for schedule(static, 1) num_threads(Eigen::nbThreads())
412 for(Index i=0; i < _rows; ++i)
414 for(Index j=0;j< _cols; ++j)
416 mim(i,j) = pixel(i,j).sum();
421 template<
typename dataT>
422 template<
typename eigenT>
425 mim.resize(_rows, _cols);
427 #pragma omp parallel for schedule(static, 1) num_threads(Eigen::nbThreads())
428 for(Index i=0; i < _rows; ++i)
430 for(Index j=0;j< _cols; ++j)
432 mim(i,j) = pixel(i,j).mean();
437 template<
typename dataT>
438 template<
typename eigenT,
typename eigenCubeT>
444 mim.resize(_rows, _cols);
446 #pragma omp parallel num_threads(Eigen::nbThreads())
448 std::vector<dataT> work;
450 #pragma omp for schedule(static, 1)
451 for(Index i=0; i < _rows; ++i)
453 for(Index j=0;j< _cols; ++j)
458 for(Index
k=0;
k<_planes; ++
k)
461 if( (mask.pixel(i,j))(
k,0) == 1)
463 work.push_back( (pixel(i,j))(
k,0) );
466 if(work.size() > minGoodFract*_planes)
470 else mim(i,j) = std::numeric_limits<dataT>::quiet_NaN();
477 template<
typename dataT>
478 template<
typename eigenT>
480 std::vector<dataT> & weights
483 mim.resize(_rows, _cols);
485 #pragma omp parallel num_threads(Eigen::nbThreads())
487 std::vector<Scalar> work;
489 #pragma omp for schedule(static, 10)
490 for(Index i=0; i < _rows; ++i)
492 for(Index j=0;j< _cols; ++j)
494 work.resize(_planes);
496 for(
int k =0;
k< _planes; ++
k) work[
k] = (pixel(i,j))(
k,0);
504 template<
typename dataT>
505 template<
typename eigenT,
typename eigenCubeT>
507 std::vector<dataT> & weights,
512 mim.resize(_rows, _cols);
514 #pragma omp parallel num_threads(Eigen::nbThreads())
516 std::vector<Scalar> work, wwork;
518 #pragma omp for schedule(static, 10)
519 for(Index i=0; i < _rows; ++i)
521 for(Index j=0;j< _cols; ++j)
528 for(Index
k =0;
k< _planes; ++
k)
530 if( (mask.pixel(i,j))(
k,0) == 1)
532 work.push_back( (pixel(i,j))(
k,0) );
533 wwork.push_back( weights[
k] );
536 if(work.size() > minGoodFract*_planes)
540 else mim(i,j) = std::numeric_limits<dataT>::quiet_NaN();
546 template<
typename dataT>
547 template<
typename eigenT>
550 mim.resize(_rows, _cols);
552 #pragma omp parallel for schedule(static, 10) num_threads(Eigen::nbThreads())
553 for(Index i=0; i < _rows; ++i)
556 std::vector<Scalar> work;
557 for(Index j=0;j< _cols; ++j)
564 template<
typename dataT>
565 template<
typename eigenT>
568 mim.resize(_rows, _cols);
570 #pragma omp parallel num_threads(Eigen::nbThreads())
572 std::vector<Scalar> work;
574 #pragma omp for schedule(static, 10)
575 for(Index i=0; i < _rows; ++i)
577 for(Index j=0;j< _cols; ++j)
579 work.resize(_planes);
580 for(
int k =0;
k< _planes; ++
k) work[
k] = (pixel(i,j))(
k,0);
590 template<
typename dataT>
591 template<
typename eigenT,
typename eigenCubeT>
598 mim.resize(_rows, _cols);
600 #pragma omp parallel num_threads(Eigen::nbThreads())
602 std::vector<Scalar> work;
604 #pragma omp for schedule(static, 10)
605 for(Index i=0; i < _rows; ++i)
607 for(Index j=0;j< _cols; ++j)
612 for(Index
k =0;
k< _planes; ++
k)
614 if( (mask.pixel(i,j))(
k,0) == 1)
616 work.push_back( (pixel(i,j))(
k,0) );
619 if(work.size() > minGoodFract*_planes)
623 else mim(i,j) = std::numeric_limits<dataT>::quiet_NaN();
632 template<
typename dataT>
633 template<
typename eigenT>
636 mim.resize(_rows, _cols);
638 #pragma omp parallel num_threads(Eigen::nbThreads())
640 std::vector<Scalar> work;
642 #pragma omp for schedule(static, 10)
643 for(Index i=0; i < _rows; ++i)
645 for(Index j=0;j< _cols; ++j)
647 work.resize(_planes);
649 for(
int k =0;
k< _planes; ++
k) work[
k] = (pixel(i,j))(
k,0);
659 template<
typename dataT>
660 template<
typename eigenT,
typename eigenCubeT>
662 std::vector<dataT> & weights,
668 mim.resize(_rows, _cols);
670 #pragma omp parallel num_threads(Eigen::nbThreads())
672 std::vector<Scalar> work, wwork;
674 #pragma omp for schedule(static, 10)
675 for(Index i=0; i < _rows; ++i)
677 for(Index j=0;j< _cols; ++j)
684 for(Index
k =0;
k< _planes; ++
k)
686 if( (mask.pixel(i,j))(
k,0) == 1)
688 work.push_back( (pixel(i,j))(
k,0) );
689 wwork.push_back( weights[
k] );
692 if(work.size() > minGoodFract*_planes)
696 else mim(i,j) = std::numeric_limits<dataT>::quiet_NaN();
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.
constexpr units::realT c()
The speed of light.
constexpr units::realT sigma()
Stefan-Boltzmann Constant.
constexpr units::realT k()
Boltzmann Constant.
@ imageMedian
The median of each image (within the search region) is subtracted from itself.
vectorT::value_type vectorSigmaMean(const vectorT &vec, const vectorT *weights, typename vectorT::value_type 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.