MeVisLabToolboxReference
MeVisLab/Standard/Sources/ML/MLKernel/mlKernelLineApplicator.h
Go to the documentation of this file.
00001 // **InsertLicense** code
00002 //-------------------------------------------------------------------------
00005 
00010 //-------------------------------------------------------------------------
00011 // Prevent multiple including of this file.
00012 #if !defined(__mlKernelLineApplicator_H)
00013 #define __mlKernelLineApplicator_H
00014 
00015 // ML-includes
00016 #ifndef __mlInitSystemKernel_H
00017 #include "mlInitSystemKernel.h"
00018 #endif
00019 #ifndef __mlKernel_H
00020 #include "mlKernel.h"
00021 #endif
00022 #ifndef __mlLineApplicator_H
00023 #include "mlLineApplicator.h"
00024 #endif
00025 #ifndef __mlKernelTools_H
00026 #include "mlKernelTools.h"
00027 #endif
00028 #ifndef __mlKernelLineApplicatorBase_H
00029 #include "mlKernelLineApplicatorBase.h"
00030 #endif
00031 
00032 ML_START_NAMESPACE
00033 
00034 
00036 #define ML_DEBUG_ENV_NAME "ML_KERNELLINEAPPLICATOR"
00037 
00038   //---------------------------------------------------------------------------------------------  
00070   //---------------------------------------------------------------------------------------------
00071   template <typename DATATYPE, typename KDATATYPE> 
00072     class MLKERNELEXPORT KernelLineApplicator : public KernelLineApplicatorBase<DATATYPE, KDATATYPE> {
00073 
00074     //-------------------------------------------------------------------------------------------  
00075     //----------------------- CONSTRUCTORS AND DESTRUCTOR ---------------------------------------  
00076     //-------------------------------------------------------------------------------------------  
00077 
00078 public:
00079     //--------------------------------------------------------------------------------------------------------
00105     //--------------------------------------------------------------------------------------------------------
00106     enum ApplyMode {
00107       APPLY_COPY                            = 0,
00108       APPLY_NORMALLY                        ,
00109       APPLY_USER_FILTER                     ,
00110       APPLY_IMAGE_INTERVAL_FILTER           ,
00111       APPLY_KERNEL_INTERVAL_FILTER          ,
00112       APPLY_IMAGE_AND_KERNEL_INTERVAL_FILTER,
00113       
00114       NUM_APPLY_MODES                    
00115     };
00116 
00117     //-------------------------------------------------------------------------------------------
00119     //-------------------------------------------------------------------------------------------
00120     static const char* const ApplyModeNames[];
00121 
00122     //-------------------------------------------------------------------------------------------  
00125     //-------------------------------------------------------------------------------------------  
00126     KernelLineApplicator() : KernelLineApplicatorBase<DATATYPE, KDATATYPE>()
00127     {
00128       _init();
00129     }
00130 
00131     //-------------------------------------------------------------------------------------------  
00133     //-------------------------------------------------------------------------------------------  
00134     KernelLineApplicator(const KernelLineApplicator &kernLineApp): 
00135       KernelLineApplicatorBase<DATATYPE, KDATATYPE>(kernLineApp)
00136     {
00137       _init();
00138       *this=kernLineApp;
00139     }
00140 
00141     //-------------------------------------------------------------------------------------------  
00146     //-------------------------------------------------------------------------------------------  
00147     KernelLineApplicator(const TKernel<KDATATYPE> &kernel,
00148                          ApplyMode applyMode,
00149                          MLdouble iIntMin=-DBL_MIN, MLdouble iIntMax=DBL_MAX, 
00150                          MLdouble kIntMin=-DBL_MIN, MLdouble kIntMax=DBL_MAX) :
00151       KernelLineApplicatorBase<DATATYPE, KDATATYPE>(kernel)
00152     {
00153       // Initialize this instance.
00154       _init();
00155   
00156       // Specify the kernel.
00157       setKernel(kernel);
00158 
00159       // Set the mode how the kernel is applied to the image.
00160       setApplyMode(applyMode);
00161 
00162       // Initialize image and kernel interval.
00163       setImageInterval (iIntMin, iIntMax);
00164       setKernelInterval(kIntMin, kIntMax);
00165     }
00166 
00167     //-------------------------------------------------------------------------------------------  
00169     //-------------------------------------------------------------------------------------------  
00170     virtual ~KernelLineApplicator()
00171     {
00172       KernelLineApplicatorBase<DATATYPE, KDATATYPE>::_clearIndices();
00173     }
00174 
00175     //-------------------------------------------------------------------------------------------  
00177     //-------------------------------------------------------------------------------------------  
00178     const KernelLineApplicator &operator=(const KernelLineApplicator &kernLineApp)
00179     {
00180       // Execute superclass functionality.
00181       KernelLineApplicatorBase<DATATYPE, KDATATYPE>::operator=(kernLineApp);
00182 
00183       // Assign only if objects differ.
00184       if (this != &kernLineApp){
00185         // Copy member settings.
00186         setApplyMode     (kernLineApp._applyMode);
00187         setImageInterval (kernLineApp._origIMin, kernLineApp._origIMax);
00188         setKernelInterval(kernLineApp._kernIMin, kernLineApp._kernIMax);
00189       }
00190 
00191       return *this;
00192     }
00193 
00194 
00195     //-------------------------------------------------------------------------------------------  
00196     //------------------------- PARAMETER CONTROL -----------------------------------------------  
00197     //-------------------------------------------------------------------------------------------  
00198 
00199     //-------------------------------------------------------------------------------------------  
00201 
00202     //-------------------------------------------------------------------------------------------  
00203     inline void setApplyMode(ApplyMode mode)      { _applyMode = mode; }
00204     inline ApplyMode getApplyMode()  const        { return _applyMode; }
00206 
00207 
00208     //-------------------------------------------------------------------------------------------  
00210 
00211     //-------------------------------------------------------------------------------------------  
00212     inline DATATYPE getImageIntervalMin()  const  { return _origIMinDT;  }
00213     inline DATATYPE getImageIntervalMax()  const  { return _origIMaxDT;  }
00214     inline DATATYPE getKernelIntervalMin() const  { return _kernIMinDT;  }
00215     inline DATATYPE getKernelIntervalMax() const  { return _kernIMaxDT;  }
00217 
00218     //-------------------------------------------------------------------------------------------  
00223     //-------------------------------------------------------------------------------------------  
00224     void setImageInterval(MLdouble min=-DBL_MAX, MLdouble   max=DBL_MAX)
00225     {
00226       // Store MLdouble and casted values to DATATYPE. So we don't need to cast so much later.
00227       _origIMin   = min;
00228       _origIMax   = max;
00229       _origIMinDT = static_cast<DATATYPE>(min);
00230       _origIMaxDT = static_cast<DATATYPE>(max);
00231       _normOrigI  = _origIMin <= _origIMax;
00232     }
00233 
00234     //-------------------------------------------------------------------------------------------  
00240     //-------------------------------------------------------------------------------------------  
00241     void setKernelInterval(MLdouble min=-DBL_MAX, MLdouble max=DBL_MAX)
00242     {
00243       // Store MLdouble and casted values to DATATYPE. So we don't need to cast so much later.
00244       _kernIMin   = min;
00245       _kernIMax   = max;
00246       _kernIMinDT = static_cast<DATATYPE>(min);
00247       _kernIMaxDT = static_cast<DATATYPE>(max);
00248       _normKernI  = _kernIMin <= _kernIMax;
00249     }
00250 
00251     //-------------------------------------------------------------------------------------------  
00256     //-------------------------------------------------------------------------------------------  
00257     bool isInImageInterval(DATATYPE v) const
00258     {
00259       // Look whether v is in current interval. Normally v is implicitly converted to
00260       // _origMin/_origMax type for comparison, i.e. 3 <= 3.5 results to false.
00261       // For user defined data types (internally implemented as carrier types), however,
00262       // we want to use the user defined comparison. So we must look for the data type and
00263       // use different casts.
00264       return (MLIsStandardTypePtr((DATATYPE*)NULL) ?
00265 
00266                // Use MLdouble for comparison
00267                (( _normOrigI && ((static_cast<MLdouble>(v) >=_origIMin) && (static_cast<MLdouble>(v) <= _origIMax))) ||
00268                 (!_normOrigI && ((static_cast<MLdouble>(v) < _origIMax) || (static_cast<MLdouble>(v) >  _origIMin)))    ) :
00269 
00270                // Use DATATYPE for comparison.
00271                (( _normOrigI && ((v >=_origIMinDT) && (v <= _origIMaxDT))) ||
00272                 (!_normOrigI && ((v < _origIMaxDT) || (v >  _origIMinDT)))    )
00273              );
00274     }
00275 
00276     //-------------------------------------------------------------------------------------------  
00281     //-------------------------------------------------------------------------------------------  
00282     bool isInKernelInterval(DATATYPE v) const
00283     {
00284       // See \c isInImageInterval for documentation.
00285       return (MLIsStandardTypePtr((DATATYPE*)NULL) ?
00286 
00287                // Use MLdouble for comparison
00288                (( _normKernI && ((static_cast<MLdouble>(v) >=_kernIMin) && (static_cast<MLdouble>(v) <= _kernIMax))) ||
00289                 (!_normKernI && ((static_cast<MLdouble>(v) < _kernIMax) || (static_cast<MLdouble>(v) >  _kernIMin)))    ) :
00290 
00291                // Use DATATYPE for comparison.
00292                (( _normKernI && ((v >=_kernIMinDT) && (v <= _kernIMaxDT))) ||
00293                 (!_normKernI && ((v < _kernIMaxDT) || (v >  _kernIMinDT)))    )
00294              );
00295     }
00296 
00297 
00298     //-------------------------------------------------------------------------------------------  
00303     //-------------------------------------------------------------------------------------------  
00304     void applyToLine(TSubImageWithCursor<DATATYPE> *inSubImg,
00305                      TSubImageWithCursor<DATATYPE> *outSubImg,
00306                      size_t numVox)
00307     {
00308       // Update the index table for this page. It contains an offset to get from the kernel origin
00309       // to any other kernel voxel. It's needed for fast access to values covered by kernel elements.
00310       _defineIndices(*inSubImg);
00311 
00312       // Kernel empty or invalid kernel?
00313       if ((NULL == KernelLineApplicatorBase<DATATYPE, KDATATYPE>::_kernel) || 
00314           (   0 == KernelLineApplicatorBase<DATATYPE, KDATATYPE>::_indexTabSize)){
00315         KernelTools::copyLine(inSubImg->getCursorPos(),
00316                               outSubImg->getCursorPos(), 
00317                               numVox,
00318                               KernelLineApplicatorBase<DATATYPE, KDATATYPE>::_srcVoxOffset);
00319       }
00320       else{
00321         switch (_applyMode){
00322 
00323         default:
00324         case APPLY_COPY:
00325           KernelTools::copyLine(inSubImg->getCursorPos(), 
00326                                 outSubImg->getCursorPos(),
00327                                 numVox, 
00328                                 KernelLineApplicatorBase<DATATYPE, KDATATYPE>::_srcVoxOffset);
00329           break;
00330 
00331         case APPLY_USER_FILTER:
00332           applyUserFilterToLine(inSubImg, outSubImg, numVox);
00333           break;
00334 
00335         case APPLY_NORMALLY:
00336           KernelTools::correlateLine
00337              (inSubImg->getCursorPos(), outSubImg->getCursorPos(), numVox, 
00338               KernelLineApplicatorBase<DATATYPE, KDATATYPE>::_kernel->getValueTab(), 
00339               KernelLineApplicatorBase<DATATYPE, KDATATYPE>::_indexTab, 
00340               KernelLineApplicatorBase<DATATYPE, KDATATYPE>::_indexTabSize);
00341           break;
00342 
00343         case APPLY_IMAGE_INTERVAL_FILTER:
00344           KernelTools::correlateLineWithImageInterval
00345              (inSubImg->getCursorPos(), outSubImg->getCursorPos(), numVox, 
00346               KernelLineApplicatorBase<DATATYPE, KDATATYPE>::_kernel->getValueTab(), 
00347               KernelLineApplicatorBase<DATATYPE, KDATATYPE>::_indexTab, 
00348               KernelLineApplicatorBase<DATATYPE, KDATATYPE>::_indexTabSize, 
00349               KernelLineApplicatorBase<DATATYPE, KDATATYPE>::_srcVoxOffset, 
00350               _origIMin, 
00351               _origIMax);
00352           break;
00353 
00354         case APPLY_KERNEL_INTERVAL_FILTER:
00355           KernelTools::correlateLineWithKernelInterval
00356              (inSubImg->getCursorPos(), outSubImg->getCursorPos(), numVox,
00357               KernelLineApplicatorBase<DATATYPE, KDATATYPE>::_kernel->getValueTab(), 
00358               KernelLineApplicatorBase<DATATYPE, KDATATYPE>::_indexTab, 
00359               KernelLineApplicatorBase<DATATYPE, KDATATYPE>::_indexTabSize, 
00360               KernelLineApplicatorBase<DATATYPE, KDATATYPE>::_srcVoxOffset, 
00361               _kernIMin, 
00362               _kernIMax);
00363           break;
00364 
00365         case APPLY_IMAGE_AND_KERNEL_INTERVAL_FILTER: 
00366           KernelTools::correlateLineWithImageAndKernelInterval
00367              (inSubImg->getCursorPos(), outSubImg->getCursorPos(), numVox, 
00368               KernelLineApplicatorBase<DATATYPE, KDATATYPE>::_kernel->getValueTab(), 
00369               KernelLineApplicatorBase<DATATYPE, KDATATYPE>::_indexTab, 
00370               KernelLineApplicatorBase<DATATYPE, KDATATYPE>::_indexTabSize, 
00371               KernelLineApplicatorBase<DATATYPE, KDATATYPE>::_srcVoxOffset,
00372               _origIMin, 
00373               _origIMax, 
00374               _kernIMin, 
00375               _kernIMax);
00376           break;
00377         }
00378       }
00379     }
00380 
00381     //-------------------------------------------------------------------------------------------  
00386     //-------------------------------------------------------------------------------------------  
00387     virtual void applyUserFilterToLine(TSubImageWithCursor<DATATYPE> *inSubImg,
00388                                        TSubImageWithCursor<DATATYPE> *outSubImg,
00389                                        long numVox) const
00390     {
00391        // Use convenience routine from helper class when not overloaded.
00392        KernelTools::copyLine(inSubImg->getCursorPos(), 
00393                              outSubImg->getCursorPos(), 
00394                              numVox, 
00395                              KernelLineApplicatorBase<DATATYPE, KDATATYPE>::_srcVoxOffset);
00396     }
00397 
00398   protected:
00399 
00400     //-------------------------------------------------------------------------------------------  
00402     //-------------------------------------------------------------------------------------------  
00403     void _init()
00404     {
00405       // Execute superclass functionality.
00406       KernelLineApplicatorBase<DATATYPE, KDATATYPE>::_init();
00407 
00408       // mode how the kernel is applied to the image.
00409       _applyMode = APPLY_NORMALLY;
00410 
00411       // Intervals to exclude input image voxels from filtering or from usage in kernels.
00412       setImageInterval (-DBL_MAX, DBL_MAX);
00413       setKernelInterval(-DBL_MAX, DBL_MAX);
00414     }
00415 
00416 
00417 
00418     //-------------------------------------------------------------------------------------------  
00419     //                     Protected members.
00420     //-------------------------------------------------------------------------------------------  
00421 
00422     //-------------------------------------------------------------------------------------------  
00424     //-------------------------------------------------------------------------------------------  
00425     ApplyMode       _applyMode;
00426 
00427     //-------------------------------------------------------------------------------------------  
00428     // ---------------------- KERNEL INTERVALS AND THEIR PROPERTIES -----------------------------
00429     //-------------------------------------------------------------------------------------------  
00431 
00432     MLdouble        _origIMin;
00433     MLdouble        _origIMax;
00434     DATATYPE        _origIMinDT;
00435     DATATYPE        _origIMaxDT;
00437 
00439     bool            _normOrigI;
00440 
00441 
00442 
00444 
00445     MLdouble        _kernIMin;
00446     MLdouble        _kernIMax;
00447     DATATYPE        _kernIMinDT;
00448     DATATYPE        _kernIMaxDT;
00450 
00452     bool            _normKernI;
00453   };
00454 
00455 //-------------------------------------------------------------------
00457 //-------------------------------------------------------------------
00458 template <typename DATATYPE, typename KDATATYPE> const char * const 
00459  KernelLineApplicator<DATATYPE, KDATATYPE>::ApplyModeNames[] = {
00460     "ApplyCopy",
00461     "ApplyNormally",
00462     "ApplyUserFilter",
00463     "ApplyImageIntervalFilter",
00464     "ApplyKernelIntervalFilter",
00465     "ApplyImageAndKernelInterval"
00466   };
00467 
00468 
00469 
00470 // Forget ML_DEBUG_ENV_NAME, because it probably will be used by other operators, too.
00471 #undef ML_DEBUG_ENV_NAME
00472 
00473 ML_END_NAMESPACE
00474 
00475 #endif // __mlKernelLineApplicator_H
00476