mxlib
c++ tools for analyzing astronomical data and other tasks by Jared R. Males. [git repo]
Loading...
Searching...
No Matches
eigenCube.hpp
Go to the documentation of this file.
1/** \file eigenCube.hpp
2 * \brief An image cube with an Eigen API
3 *
4 * \author Jared R. Males (jaredmales@gmail.com)
5 *
6 * \ingroup image_processing_files
7 *
8 */
9
10#ifndef eigenCube_hpp
11#define eigenCube_hpp
12
13#pragma GCC system_header
14#include <Eigen/Dense>
15
16#include "../math/vectorUtils.hpp"
17#include "eigenImage.hpp"
18#include "imageUtils.hpp"
19
20namespace mx
21{
22namespace improc
23{
24
25/// An image cube with an Eigen-like API
26/** \ingroup eigen_image_processing
27 */
28template <typename dataT>
30{
31 public:
32 typedef bool is_eigenCube;
33 typedef dataT Scalar;
34
35 typedef typename Eigen::Array<dataT, Eigen::Dynamic, Eigen::Dynamic>::Index Index;
36
37 typedef Eigen::Map<Eigen::Array<dataT, Eigen::Dynamic, Eigen::Dynamic>> imageRef;
38
39 typedef Eigen::Array<dataT, Eigen::Dynamic, Eigen::Dynamic> imageT;
40
41 protected:
42 Index _rows;
43 Index _cols;
44 Index _planes;
45
46 dataT *m_data{ nullptr };
47
48 bool _owner;
49
50 public:
51 eigenCube();
52
53 /// C'tor which will allocate space..
54 /**
55 */
56 eigenCube( Index nrows, ///< [in] Number of rows in the cube
57 Index ncols, ///< [in] Number of columns the cube
58 Index nplanes ///< [in] Number of planes in the cube
59 );
60
61 /// C'tor taking an existing array as an argument.
62 /** The existing array is used as is, as in a map, and ownership is not taken. You are
63 * responsible for memory management, e.g. free-ing this array.
64 */
65 eigenCube( dataT *ndata, ///< [in] Allocated array with a cube of nrows x ncols x nplanes
66 size_t nrows, ///< [in] Number of rows in the cube
67 size_t ncols, ///< [in] Number of columns the cube
68 size_t nplanes ///< [in] Number of planes in the cube
69 );
70
71 ~eigenCube();
72
73 void setZero();
74
75 eigenCube<dataT> &operator=( const eigenCube<dataT> &ec );
76
77 void shallowCopy( eigenCube<dataT> &src, bool takeOwner = false );
78
79 /// De-allocate and set all sizes to 0
80 void clear();
81
82 void resize( int r, int c, int p );
83
84 void resize( int r, int c );
85
86 dataT *data();
87
88 const dataT *data() const;
89
90 const Index rows() const;
91
92 const Index cols() const;
93
94 const Index planes() const;
95
96 /// Returns a 2D Eigen::Eigen::Map pointed at the entire cube.
97 Eigen::Map<Eigen::Array<dataT, Eigen::Dynamic, Eigen::Dynamic>> cube();
98
99 /// Returns a 2D Eigen::Eigen::Map pointed at the specified image.
100 Eigen::Map<Eigen::Array<dataT, Eigen::Dynamic, Eigen::Dynamic>> image( Index n /**< [in] the image number */ );
101
102 /// Returns a 2D Eigen::Eigen::Map pointed at the specified image.
103 const Eigen::Map<Eigen::Array<dataT, Eigen::Dynamic, Eigen::Dynamic>>
104 image( Index n /**< [in] the image number */ ) const;
105
106 /// Returns an Eigen::Eigen::Map-ed vector of the pixels at the given coordinate
107 Eigen::Map<Eigen::Array<dataT, Eigen::Dynamic, Eigen::Dynamic>,
108 Eigen::Unaligned,
109 Eigen::Stride<Eigen::Dynamic, Eigen::Dynamic>>
110 pixel( Index i, Index j );
111
112 /// Return an Eigen::Eigen::Map of the cube where each image is a vector
113 Eigen::Map<Eigen::Array<dataT, Eigen::Dynamic, Eigen::Dynamic>> asVectors();
114
115 /// Calculate the covariance matrix of the images in the cube
116 void Covar( Eigen::Matrix<dataT, Eigen::Dynamic, Eigen::Dynamic> &cv );
117
118 /// Calculate the sum image of the cube
119 /**
120 * \tparam eigenT an Eigen-like type.
121 */
122 template <typename eigenT>
123 void sum( eigenT &mim /**< [out] the resultant sum image. Is resized. */ );
124
125 /// Calculate the mean image of the cube
126 /**
127 * \tparam eigenT an Eigen-like type.
128 */
129 template <typename eigenT>
130 void mean( eigenT &mim /**< [out] the resultant mean image. Is resized. */ );
131
132 /// Calculate the mean image of the cube with a mask.
133 /**
134 * \tparam eigenT an Eigen-like type.
135 * \tparam eigenCubeT an eigenCube type.
136 */
137 template <typename eigenT, typename eigenCubeT>
138 void mean( eigenT &mim, ///< [out] the resultant mean image. Is resized.
139 eigenCubeT &mask, /**< [in] a mask cube. Only pixels with value 1 are included in the
140 mean calculation. */
141 double minGoodFract = 0.0 /**< [in] [optional] the minimum fraction of good pixels, if not met
142 then the pixel is NaN-ed. */
143 );
144
145 /// Calculate the weighted mean image of the cube
146 /**
147 * \tparam eigenT an Eigen-like type.
148 */
149 template <typename eigenT>
150 void mean( eigenT &mim, ///< [out] the resultant mean image. Is resized.
151 std::vector<dataT> &weights ///< [in] a vector of weights to use for calculating the mean
152 );
153
154 /// Calculate the weighted mean image of the cube, with a mask cube.
155 /**
156 * \tparam eigenT an Eigen-like type.
157 * \tparam eigenCubeT an eigenCube type.
158 */
159 template <typename eigenT, typename eigenCubeT>
160 void mean( eigenT &mim, ///< [out] the resultant mean image. Is resized.
161 std::vector<dataT> &weights, ///< [in] a vector of weights to use for calculating the mean
162 eigenCubeT &mask, ///< [in] a mask cube. Only pixels with value 1 are included in the mean calculation.
163 double minGoodFract =
164 0.0 ///< [in] [optional] the minimum fraction of good pixels, if not met then the pixel is NaN-ed.
165 );
166
167 /// Calculate the median image of the cube
168 /**
169 * \tparam eigenT an Eigen-like type.
170 */
171 template <typename eigenT>
172 void median( eigenT &mim /**< [out] the resultant median image. Is resized. */ );
173
174 /// Calculate the sigma clipped mean image of the cube
175 /**
176 * \tparam eigenT an Eigen-like type.
177 */
178 template <typename eigenT>
179 void sigmaMean( eigenT &mim, ///< [out] the resultant mean image
180 Scalar sigma ///< [in] the sigma value at which to clip.
181 );
182
183 /// Calculate the sigma clipped mean image of the cube, with a mask cube
184 /**
185 * \tparam eigenT an Eigen-like type.
186 * \tparam eigenCubeT an eigenCube type.
187 */
188 template <typename eigenT, typename eigenCubeT>
189 void
190 sigmaMean( eigenT &mim, ///< [out] the resultant mean image. Is resized.
191 eigenCubeT &mask, ///< [in] a mask cube. Only pixels with value 1 are included in the mean calculation.
192 Scalar sigma, ///< [in] the sigma value at which to clip.
193 double minGoodFract =
194 0.0 ///< [in] [optional] the minimum fraction of good pixels, if not met then the pixel is NaN-ed.
195 );
196
197 /// Calculate the sigma clipped weighted mean image of the cube
198 /**
199 * \tparam eigenT an Eigen-like type.
200 */
201 template <typename eigenT>
202 void sigmaMean( eigenT &mim, ///< [out] the resultant mean image. Is resized.
203 std::vector<dataT> &weights, ///< [in] a vector of weights to use for calculating the mean
204 Scalar sigma ///< [in] the sigma value at which to clip.
205 );
206
207 /// Calculate the sigma clipped weighted mean image of the cube, with a mask cube.
208 /**
209 * \tparam eigenT an Eigen-like type.
210 * \tparam eigenCubeT an eigenCube type.
211 */
212 template <typename eigenT, typename eigenCubeT>
213 void
214 sigmaMean( eigenT &mim, ///< [out] the resultant mean image. Is resized.
215 std::vector<dataT> &weights, ///< [in] a vector of weights to use for calculating the mean
216 eigenCubeT &mask, ///< [in] a mask cube. Only pixels with value 1 are included in the mean calculation.
217 Scalar sigma, ///< [in] the sigma value at which to clip.
218 double minGoodFract =
219 0.0 ///< [in] [optional] the minimum fraction of good pixels, if not met then the pixel is NaN-ed.
220 );
221};
222
223template <typename dataT>
225{
226 _rows = 0;
227 _cols = 0;
228 _planes = 0;
229 _owner = false;
230}
231
232template <typename dataT>
233eigenCube<dataT>::eigenCube( Index nrows, Index ncols, Index nplanes )
234{
235 _rows = nrows;
236 _cols = ncols;
237 _planes = nplanes;
238
239 m_data = new dataT[_rows * _cols * _planes];
240 _owner = true;
241}
242
243template <typename dataT>
244eigenCube<dataT>::eigenCube( dataT *ndata, size_t nrows, size_t ncols, size_t nplanes )
245{
246 _rows = nrows;
247 _cols = ncols;
248 _planes = nplanes;
249
250 m_data = ndata;
251 _owner = false;
252}
253
254template <typename dataT>
256{
257 if( _owner && m_data )
258 {
259 delete[] m_data;
260 }
261}
262
263template <typename dataT>
264void eigenCube<dataT>::setZero()
265{
266 int N = _rows * _cols * _planes;
267
268 for( int i = 0; i < N; ++i )
269 m_data[i] = ( (dataT)0 );
270}
271
272template <typename dataT>
273eigenCube<dataT> &eigenCube<dataT>::operator=( const eigenCube<dataT> &ec )
274{
275 resize( ec.rows(), ec.cols(), ec.planes() );
276
277 int N = _rows * _cols * _planes;
278
279 for( int i = 0; i < N; ++i )
280 m_data[i] = ec.m_data[i];
281
282 return *this;
283}
284
285template <typename dataT>
286void eigenCube<dataT>::shallowCopy( eigenCube<dataT> &src, bool takeOwner )
287{
288 if( _owner && m_data )
289 {
290 delete m_data;
291 _owner = false;
292 }
293
294 _rows = src._rows;
295 _cols = src._cols;
296 _planes = src._planes;
297 m_data = src.m_data;
298
299 if( takeOwner == true )
300 {
301 _owner = true;
302 src._owner = false;
303 }
304 else
305 {
306 _owner = false;
307 }
308}
309
310template <typename dataT>
312{
313 if( _owner && m_data )
314 {
315 delete[] m_data;
316 }
317
318 _rows = 0;
319 _cols = 0;
320 _planes = 0;
321}
322
323template <typename dataT>
324void eigenCube<dataT>::resize( int r, int c, int p )
325{
326 if( _owner && m_data )
327 {
328 delete[] m_data;
329 }
330
331 _rows = r;
332 _cols = c;
333 _planes = p;
334
335 m_data = new dataT[_rows * _cols * _planes];
336 _owner = true;
337}
338
339template <typename dataT>
340void eigenCube<dataT>::resize( int r, int c )
341{
342 resize( r, c, 1 );
343}
344
345template <typename dataT>
346dataT *eigenCube<dataT>::data()
347{
348 return m_data;
349}
350
351template <typename dataT>
352const dataT *eigenCube<dataT>::data() const
353{
354 return m_data;
355}
356
357template <typename dataT>
358const typename eigenCube<dataT>::Index eigenCube<dataT>::rows() const
359{
360 return _rows;
361}
362
363template <typename dataT>
364const typename eigenCube<dataT>::Index eigenCube<dataT>::cols() const
365{
366 return _cols;
367}
368
369template <typename dataT>
370const typename eigenCube<dataT>::Index eigenCube<dataT>::planes() const
371{
372 return _planes;
373}
374
375template <typename dataT>
376Eigen::Map<Eigen::Array<dataT, Eigen::Dynamic, Eigen::Dynamic>> eigenCube<dataT>::cube()
377{
378 return Eigen::Map<Eigen::Array<dataT, Eigen::Dynamic, Eigen::Dynamic>>( m_data, _rows * _cols, _planes );
379}
380
381template <typename dataT>
382Eigen::Map<Eigen::Array<dataT, Eigen::Dynamic, Eigen::Dynamic>> eigenCube<dataT>::image( Index n )
383{
384 return Eigen::Map<Eigen::Array<dataT, Eigen::Dynamic, Eigen::Dynamic>>( m_data + n * _rows * _cols, _rows, _cols );
385}
386
387template <typename dataT>
388const Eigen::Map<Eigen::Array<dataT, Eigen::Dynamic, Eigen::Dynamic>> eigenCube<dataT>::image( Index n ) const
389{
390 return Eigen::Map<Eigen::Array<dataT, Eigen::Dynamic, Eigen::Dynamic>>( m_data + n * _rows * _cols, _rows, _cols );
391}
392
393template <typename dataT>
394Eigen::Map<Eigen::Array<dataT, Eigen::Dynamic, Eigen::Dynamic>,
395 Eigen::Unaligned,
396 Eigen::Stride<Eigen::Dynamic, Eigen::Dynamic>>
397eigenCube<dataT>::pixel( Index i, Index j )
398{
399 return Eigen::Map<Eigen::Array<dataT, Eigen::Dynamic, Eigen::Dynamic>,
400 Eigen::Unaligned,
401 Eigen::Stride<Eigen::Dynamic, Eigen::Dynamic>>(
402 m_data + j * _rows + i,
403 _planes,
404 1,
405 Eigen::Stride<Eigen::Dynamic, Eigen::Dynamic>( 0, _rows * _cols ) );
406}
407
408template <typename dataT>
409Eigen::Map<Eigen::Array<dataT, Eigen::Dynamic, Eigen::Dynamic>> eigenCube<dataT>::asVectors()
410{
411 return Eigen::Map<Eigen::Array<dataT, Eigen::Dynamic, Eigen::Dynamic>>( m_data, _rows * _cols, _planes );
412}
413
414template <typename dataT>
415void eigenCube<dataT>::Covar( Eigen::Matrix<dataT, Eigen::Dynamic, Eigen::Dynamic> &cv )
416{
417 cv = asVectors().matrix().transpose() * asVectors().matrix();
418}
419
420template <typename dataT>
421template <typename eigenT>
422void eigenCube<dataT>::sum( eigenT &mim )
423{
424 mim.resize( _rows, _cols );
425
426#pragma omp parallel for schedule( static, 1 ) num_threads( Eigen::nbThreads() )
427 for( Index i = 0; i < _rows; ++i )
428 {
429 for( Index j = 0; j < _cols; ++j )
430 {
431 mim( i, j ) = pixel( i, j ).sum();
432 }
433 }
434}
435
436template <typename dataT>
437template <typename eigenT>
438void eigenCube<dataT>::mean( eigenT &mim )
439{
440 mim.resize( _rows, _cols );
441
442#pragma omp parallel for schedule( static, 1 ) num_threads( Eigen::nbThreads() )
443 for( Index i = 0; i < _rows; ++i )
444 {
445 for( Index j = 0; j < _cols; ++j )
446 {
447 mim( i, j ) = pixel( i, j ).mean();
448 }
449 }
450}
451
452template <typename dataT>
453template <typename eigenT, typename eigenCubeT>
454void eigenCube<dataT>::mean( eigenT &mim, eigenCubeT &mask, double minGoodFract )
455{
456 mim.resize( _rows, _cols );
457
458#pragma omp parallel
459 {
460 std::vector<dataT> work;
461
462#pragma omp for
463 for( Index i = 0; i < _rows; ++i )
464 {
465 for( Index j = 0; j < _cols; ++j )
466 {
467
468 work.clear();
469
470 for( Index k = 0; k < _planes; ++k )
471 {
472 if( ( mask.pixel( i, j ) )( k, 0 ) == 1 )
473 {
474 work.push_back( ( pixel( i, j ) )( k, 0 ) );
475 }
476 }
477
478 if( work.size() > minGoodFract * _planes )
479 {
480 mim( i, j ) = math::vectorMean( work );
481 }
482 else
483 {
484 mim( i, j ) = invalidNumber<float>();
485 }
486 }
487 }
488 }
489}
490
491template <typename dataT>
492template <typename eigenT>
493void eigenCube<dataT>::mean( eigenT &mim, std::vector<dataT> &weights )
494{
495 mim.resize( _rows, _cols );
496
497#pragma omp parallel num_threads( Eigen::nbThreads() )
498 {
499 std::vector<Scalar> work;
500
501#pragma omp for schedule( static, 10 )
502 for( Index i = 0; i < _rows; ++i )
503 {
504 for( Index j = 0; j < _cols; ++j )
505 {
506 work.resize( _planes ); // work could be smaller after sigmaMean
507 // int ii=0;
508 for( int k = 0; k < _planes; ++k )
509 work[k] = ( pixel( i, j ) )( k, 0 );
510
511 mim( i, j ) = math::vectorMean( work, weights );
512 }
513 }
514 }
515}
516
517template <typename dataT>
518template <typename eigenT, typename eigenCubeT>
519void eigenCube<dataT>::mean( eigenT &mim, std::vector<dataT> &weights, eigenCubeT &mask, double minGoodFract )
520{
521 mim.resize( _rows, _cols );
522
523#pragma omp parallel num_threads( Eigen::nbThreads() )
524 {
525 std::vector<Scalar> work, wwork;
526
527#pragma omp for schedule( static, 10 )
528 for( Index i = 0; i < _rows; ++i )
529 {
530 for( Index j = 0; j < _cols; ++j )
531 {
532 work.clear();
533 wwork.clear();
534
535 // int ii=0;
536
537 for( Index k = 0; k < _planes; ++k )
538 {
539 if( ( mask.pixel( i, j ) )( k, 0 ) == 1 )
540 {
541 work.push_back( ( pixel( i, j ) )( k, 0 ) );
542 wwork.push_back( weights[k] );
543 }
544 }
545 if( work.size() > minGoodFract * _planes )
546 {
547 mim( i, j ) = math::vectorMean( work, wwork );
548 }
549 else
550 mim( i, j ) = invalidNumber<float>();
551 }
552 }
553 }
554}
555
556template <typename dataT>
557template <typename eigenT>
558void eigenCube<dataT>::median( eigenT &mim )
559{
560 mim.resize( _rows, _cols );
561
562#pragma omp parallel for schedule( static, 10 ) num_threads( Eigen::nbThreads() )
563 for( Index i = 0; i < _rows; ++i )
564 {
565 // Eigen::Eigen::Array<Scalar, Eigen::Eigen::Dynamic, Eigen::Eigen::Dynamic> work;
566 std::vector<Scalar> work;
567 for( Index j = 0; j < _cols; ++j )
568 {
569 mim( i, j ) = imageMedian( pixel( i, j ), &work );
570 }
571 }
572}
573
574template <typename dataT>
575template <typename eigenT>
576void eigenCube<dataT>::sigmaMean( eigenT &mim, dataT sigma )
577{
578 mim.resize( _rows, _cols );
579
580 // clang-format off
581 #pragma omp parallel //clang-format on
582 {
583 std::vector<Scalar> work;
584
585 // clang-format off
586 #pragma omp for // clang-format off
587 for( Index i = 0; i < _rows; ++i )
588 {
589 for( Index j = 0; j < _cols; ++j )
590 {
591 work.resize( _planes );
592 for( int k = 0; k < _planes; ++k )
593 {
594 work[k] = ( pixel( i, j ) )( k, 0 );
595 }
596
597 mim( i, j ) = math::vectorSigmaMean( work, sigma );
598 }
599 }
600 }
601}
602
603template <typename dataT>
604template <typename eigenT, typename eigenCubeT>
605void eigenCube<dataT>::sigmaMean( eigenT &mim, eigenCubeT &mask, dataT sigma, double minGoodFract )
606{
607 mim.resize( _rows, _cols );
608
609#pragma omp parallel
610 {
611 std::vector<Scalar> work;
612
613#pragma omp for
614 for( Index i = 0; i < _rows; ++i )
615 {
616 for( Index j = 0; j < _cols; ++j )
617 {
618 work.clear();
619 int ii = 0;
620
621 for( Index k = 0; k < _planes; ++k )
622 {
623 if( ( mask.pixel( i, j ) )( k, 0 ) == 1 )
624 {
625 work.push_back( ( pixel( i, j ) )( k, 0 ) );
626 }
627 }
628
629 if( work.size() > minGoodFract * _planes )
630 {
631 mim( i, j ) = math::vectorSigmaMean( work, sigma );
632 }
633 else
634 {
635 mim( i, j ) = invalidNumber<float>();
636 }
637 }
638 }
639 }
640}
641
642template <typename dataT>
643template <typename eigenT>
644void eigenCube<dataT>::sigmaMean( eigenT &mim, std::vector<dataT> &weights, dataT sigma )
645{
646 mim.resize( _rows, _cols );
647
648#pragma omp parallel num_threads( Eigen::nbThreads() )
649 {
650 std::vector<Scalar> work;
651
652#pragma omp for schedule( static, 10 )
653 for( Index i = 0; i < _rows; ++i )
654 {
655 for( Index j = 0; j < _cols; ++j )
656 {
657 work.resize( _planes ); // work could be smaller after sigmaMean
658 int ii = 0;
659 for( int k = 0; k < _planes; ++k )
660 work[k] = ( pixel( i, j ) )( k, 0 );
661
662 mim( i, j ) = math::vectorSigmaMean( work, weights, sigma );
663 }
664 }
665 }
666}
667
668template <typename dataT>
669template <typename eigenT, typename eigenCubeT>
671 eigenT &mim, std::vector<dataT> &weights, eigenCubeT &mask, dataT sigma, double minGoodFract )
672{
673 mim.resize( _rows, _cols );
674
675#pragma omp parallel num_threads( Eigen::nbThreads() )
676 {
677 std::vector<Scalar> work, wwork;
678
679#pragma omp for schedule( static, 10 )
680 for( Index i = 0; i < _rows; ++i )
681 {
682 for( Index j = 0; j < _cols; ++j )
683 {
684 work.clear();
685 wwork.clear();
686
687 int ii = 0;
688
689 for( Index k = 0; k < _planes; ++k )
690 {
691 if( ( mask.pixel( i, j ) )( k, 0 ) == 1 )
692 {
693 work.push_back( ( pixel( i, j ) )( k, 0 ) );
694 wwork.push_back( weights[k] );
695 }
696 }
697 if( work.size() > minGoodFract * _planes )
698 {
699 mim( i, j ) = math::vectorSigmaMean( work, wwork, sigma );
700 }
701 else
702 mim( i, j ) = invalidNumber<float>();
703 }
704 }
705 }
706}
707
708} // namespace improc
709
710} // namespace mx
711
712#endif // eigenCube_hpp
An image cube with an Eigen-like API.
Definition eigenCube.hpp:30
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.
The mxlib c++ namespace.
Definition mxlib.hpp:37