LCOV - code coverage report
Current view: top level - improc - eigenCube.hpp (source / functions) Coverage Total Hit
Test: mxlib Lines: 100.0 % 47 47
Test Date: 2026-02-19 16:58:26 Functions: 100.0 % 12 12

            Line data    Source code
       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              : 
      20              : namespace mx
      21              : {
      22              : namespace improc
      23              : {
      24              : 
      25              : /// An image cube with an Eigen-like API
      26              : /** \ingroup eigen_image_processing
      27              :  */
      28              : template <typename dataT>
      29              : class eigenCube
      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              : 
     223              : template <typename dataT>
     224           15 : eigenCube<dataT>::eigenCube()
     225              : {
     226           15 :     _rows = 0;
     227           15 :     _cols = 0;
     228           15 :     _planes = 0;
     229           15 :     _owner = false;
     230           15 : }
     231              : 
     232              : template <typename dataT>
     233            2 : eigenCube<dataT>::eigenCube( Index nrows, Index ncols, Index nplanes )
     234              : {
     235            2 :     _rows = nrows;
     236            2 :     _cols = ncols;
     237            2 :     _planes = nplanes;
     238              : 
     239            2 :     m_data = new dataT[_rows * _cols * _planes];
     240            2 :     _owner = true;
     241            2 : }
     242              : 
     243              : template <typename dataT>
     244              : eigenCube<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              : 
     254              : template <typename dataT>
     255           17 : eigenCube<dataT>::~eigenCube()
     256              : {
     257           17 :     if( _owner && m_data )
     258              :     {
     259           17 :         delete[] m_data;
     260              :     }
     261           17 : }
     262              : 
     263              : template <typename dataT>
     264              : void 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              : 
     272              : template <typename dataT>
     273            1 : eigenCube<dataT> &eigenCube<dataT>::operator=( const eigenCube<dataT> &ec )
     274              : {
     275            1 :     resize( ec.rows(), ec.cols(), ec.planes() );
     276              : 
     277            1 :     int N = _rows * _cols * _planes;
     278              : 
     279      4194305 :     for( int i = 0; i < N; ++i )
     280      4194304 :         m_data[i] = ec.m_data[i];
     281              : 
     282            1 :     return *this;
     283              : }
     284              : 
     285              : template <typename dataT>
     286              : void 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              : 
     310              : template <typename dataT>
     311              : void eigenCube<dataT>::clear()
     312              : {
     313              :     if( _owner && m_data )
     314              :     {
     315              :         delete[] m_data;
     316              :     }
     317              : 
     318              :     _rows = 0;
     319              :     _cols = 0;
     320              :     _planes = 0;
     321              : }
     322              : 
     323              : template <typename dataT>
     324           18 : void eigenCube<dataT>::resize( int r, int c, int p )
     325              : {
     326           18 :     if( _owner && m_data )
     327              :     {
     328            3 :         delete[] m_data;
     329              :     }
     330              : 
     331           18 :     _rows = r;
     332           18 :     _cols = c;
     333           18 :     _planes = p;
     334              : 
     335     12714002 :     m_data = new dataT[_rows * _cols * _planes];
     336           18 :     _owner = true;
     337           18 : }
     338              : 
     339              : template <typename dataT>
     340              : void eigenCube<dataT>::resize( int r, int c )
     341              : {
     342              :     resize( r, c, 1 );
     343              : }
     344              : 
     345              : template <typename dataT>
     346          800 : dataT *eigenCube<dataT>::data()
     347              : {
     348          800 :     return m_data;
     349              : }
     350              : 
     351              : template <typename dataT>
     352              : const dataT *eigenCube<dataT>::data() const
     353              : {
     354              :     return m_data;
     355              : }
     356              : 
     357              : template <typename dataT>
     358     18303571 : const typename eigenCube<dataT>::Index eigenCube<dataT>::rows() const
     359              : {
     360     18303571 :     return _rows;
     361              : }
     362              : 
     363              : template <typename dataT>
     364     13976528 : const typename eigenCube<dataT>::Index eigenCube<dataT>::cols() const
     365              : {
     366     13976528 :     return _cols;
     367              : }
     368              : 
     369              : template <typename dataT>
     370       198391 : const typename eigenCube<dataT>::Index eigenCube<dataT>::planes() const
     371              : {
     372       198391 :     return _planes;
     373              : }
     374              : 
     375              : template <typename dataT>
     376              : Eigen::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              : 
     381              : template <typename dataT>
     382     43841925 : Eigen::Map<Eigen::Array<dataT, Eigen::Dynamic, Eigen::Dynamic>> eigenCube<dataT>::image( Index n )
     383              : {
     384     43841925 :     return Eigen::Map<Eigen::Array<dataT, Eigen::Dynamic, Eigen::Dynamic>>( m_data + n * _rows * _cols, _rows, _cols );
     385              : }
     386              : 
     387              : template <typename dataT>
     388      4325376 : const Eigen::Map<Eigen::Array<dataT, Eigen::Dynamic, Eigen::Dynamic>> eigenCube<dataT>::image( Index n ) const
     389              : {
     390      4325376 :     return Eigen::Map<Eigen::Array<dataT, Eigen::Dynamic, Eigen::Dynamic>>( m_data + n * _rows * _cols, _rows, _cols );
     391              : }
     392              : 
     393              : template <typename dataT>
     394              : Eigen::Map<Eigen::Array<dataT, Eigen::Dynamic, Eigen::Dynamic>,
     395              :            Eigen::Unaligned,
     396              :            Eigen::Stride<Eigen::Dynamic, Eigen::Dynamic>>
     397            2 : eigenCube<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            2 :         m_data + j * _rows + i,
     403              :         _planes,
     404              :         1,
     405            4 :         Eigen::Stride<Eigen::Dynamic, Eigen::Dynamic>( 0, _rows * _cols ) );
     406              : }
     407              : 
     408              : template <typename dataT>
     409              : Eigen::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              : 
     414              : template <typename dataT>
     415              : void eigenCube<dataT>::Covar( Eigen::Matrix<dataT, Eigen::Dynamic, Eigen::Dynamic> &cv )
     416              : {
     417              :     cv = asVectors().matrix().transpose() * asVectors().matrix();
     418              : }
     419              : 
     420              : template <typename dataT>
     421              : template <typename eigenT>
     422              : void 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              : 
     436              : template <typename dataT>
     437              : template <typename eigenT>
     438              : void 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              : 
     452              : template <typename dataT>
     453              : template <typename eigenT, typename eigenCubeT>
     454              : void 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              : 
     491              : template <typename dataT>
     492              : template <typename eigenT>
     493              : void 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              : 
     517              : template <typename dataT>
     518              : template <typename eigenT, typename eigenCubeT>
     519              : void 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              : 
     556              : template <typename dataT>
     557              : template <typename eigenT>
     558              : void 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              : 
     574              : template <typename dataT>
     575              : template <typename eigenT>
     576              : void 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              : 
     603              : template <typename dataT>
     604              : template <typename eigenT, typename eigenCubeT>
     605              : void 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              : 
     642              : template <typename dataT>
     643              : template <typename eigenT>
     644              : void 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              : 
     668              : template <typename dataT>
     669              : template <typename eigenT, typename eigenCubeT>
     670              : void eigenCube<dataT>::sigmaMean(
     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
        

Generated by: LCOV version 2.0-1