MeVisLabToolboxReference
MeVisLab/Standard/Sources/ML/MLKernel/mlKernelTools.h
Go to the documentation of this file.
00001 // **InsertLicense** code
00002 //-------------------------------------------------------------------------
00005 
00010 //-------------------------------------------------------------------------
00011 // Prevent multiple including of this file.
00012 #if !defined(__mlKernelTools_H)
00013 #define __mlKernelTools_H
00014 
00015 // ML-includes
00016 #ifndef __mlInitSystemKernel_H
00017 #include "mlInitSystemKernel.h"
00018 #endif
00019 // Exclude some files for an older release for a SYNGO application. 
00020 // The "if !defined" is going to be removed in future.
00021 #if !defined(USE_SYNGO)
00022 #include "mlLineApplicator.h"
00023 #endif
00024 #ifndef __mlKernel_H
00025 #include "mlKernel.h"
00026 #endif
00027 
00028 ML_START_NAMESPACE
00029 
00030   //---------------------------------------------------------------------------------------------
00032 
00033   //---------------------------------------------------------------------------------------------
00034 
00035   //-------------------------------------------------------------------------------------------
00055   //-------------------------------------------------------------------------------------------
00056   template<typename DATATYPE> struct fctLineFilter{
00057     public:
00062       virtual void operator() (TSubImageWithCursor<DATATYPE> *, TSubImageWithCursor<DATATYPE> *, size_t) const {}
00063 
00065       virtual ~fctLineFilter() {}
00066   };
00067 
00068   //-------------------------------------------------------------------------------------------
00074   //-------------------------------------------------------------------------------------------
00075   template<class T, typename DATATYPE>
00076   struct useObjectLineFilter : public fctLineFilter<DATATYPE>{
00077 
00081     T* pOb;
00082 
00086     void (T::*pLF)(TSubImageWithCursor<DATATYPE>*, TSubImageWithCursor<DATATYPE>*, size_t);
00087 
00088     public:
00093       explicit useObjectLineFilter(T* po, void (T::*pf)(TSubImageWithCursor<DATATYPE>*, TSubImageWithCursor<DATATYPE>*, size_t)) :
00094         pOb(po), pLF(pf) {}
00095 
00097       virtual ~useObjectLineFilter() {}
00098 
00104       void operator () (TSubImageWithCursor<DATATYPE> *inSubImg, TSubImageWithCursor<DATATYPE> *outSubImg, size_t numVox) const
00105          { (pOb->*pLF)(inSubImg, outSubImg, numVox);}
00106   };
00108 
00109 
00110 
00111   //-------------------------------------------------------------------------------------------
00112   //
00114   //
00115   //-------------------------------------------------------------------------------------------
00116 
00117   //-------------------------------------------------------------------------------------------
00121   //-------------------------------------------------------------------------------------------
00122 
00123   // internal function, for scalar types
00124   template <typename DATATYPE>
00125     static inline bool _isScalarValueInRange(const DATATYPE& v, bool normal, double minVal, double maxVal,
00126                                             OverloadSelector::OnTrue)
00127     {
00128       if (normal) {
00129         return (v >= minVal) && (v <= maxVal);
00130       } else {
00131         return (v <  maxVal) || (v >  minVal);
00132       }
00133     }
00134 
00135   // internal function, for non-scalar types
00136   template <typename DATATYPE>
00137     static inline bool _isScalarValueInRange(const DATATYPE&, bool, double, double,
00138                                              OverloadSelector::OnFalse)
00139     {
00140       return true;
00141     }
00142   template <typename DATATYPE>
00143     static inline bool isScalarValueInRange(const DATATYPE& v, bool normal, double minVal, double maxVal)
00144     {
00145       return _isScalarValueInRange(v, normal, minVal, maxVal, OverloadSelector::isScalarType<DATATYPE>());
00146     }
00147 
00148   //-------------------------------------------------------------------------------------------
00152   //-------------------------------------------------------------------------------------------
00153   template <typename IN_DATATYPE, typename OUT_DATATYPE>
00154     static void MLKernelToolsCopyLine(const IN_DATATYPE *inCursor,
00155                                       OUT_DATATYPE      *outCursor,
00156                                       size_t            numVox,
00157                                       MLsoffset         srcVoxelOffset)
00158   {
00159     ML_TRACE_IN( "MLKernelToolsCopyLine()" );
00160     ML_TRY
00161     {
00162       // Add srcVoxelOffset to inCursor. So we don't need to do it again and again in the loop.
00163       inCursor += srcVoxelOffset;
00164       for (size_t i=0; i<numVox; ++i){
00165         // Copy input voxel to output.
00166         *outCursor = static_cast<OUT_DATATYPE>(*inCursor);
00167 
00168         // Move read and write cursor forward.
00169         ++outCursor;
00170         ++inCursor;
00171       }
00172     }
00173     ML_CATCH_RETHROW;
00174   }
00175 
00176   //-------------------------------------------------------------------------------------------
00187   //-------------------------------------------------------------------------------------------
00188   template <typename IN_DATATYPE, typename OUT_DATATYPE, typename K_DATATYPE>
00189     static void MLKernelToolsCorrelateLine(const IN_DATATYPE *inCursor,
00190                                            OUT_DATATYPE      *outCursor,
00191                                            size_t             numVox,
00192                                            const K_DATATYPE  *valTab,
00193                                            const MLsoffset   *indexTab,
00194                                            size_t             indexTabSize)
00195   {
00196     ML_TRACE_IN( "MLKernelToolsCorrelateLine( )" );
00197     ML_TRY
00198     {
00199       // Sum up the products of the kernel element values and the input image voxels which are
00200       // found in the input page covered by kernel elements. Input image voxels are found
00201       // by offsetting the pointer to the input image voxel with the indexes from indexTab.
00202 
00203       typedef typename TypeTraits<OUT_DATATYPE>::IntermediateType IntermediateType;
00204 
00205       // Apply kernel tab to all voxels in line.
00206       for (size_t i=0; i < numVox; i++){
00207 
00208         // IntermediateType is double for scalar types and OUT_DATATYPE itself for all other types
00209         IntermediateType retVal = ml_cast_from_scalar<IntermediateType>(0);
00210         for (size_t c=0; c < indexTabSize; c++){
00211           retVal += static_cast<IntermediateType>(inCursor[indexTab[c]]) * 
00212                     ml_scalar_factor_cast<IntermediateType>(valTab[c]);
00213         }
00214 
00215         // Write result into output image.
00216         *outCursor = ml_cast_from_intermediate_type_without_clamping<OUT_DATATYPE>(retVal);
00217 
00218         // Move read and write cursor forward.
00219         ++outCursor;
00220         ++inCursor;
00221       } // for 
00222     }
00223     ML_CATCH_RETHROW;
00224   }
00225 
00226   //-------------------------------------------------------------------------------------------
00241   //-------------------------------------------------------------------------------------------
00242   template <typename IN_DATATYPE, typename OUT_DATATYPE, typename K_DATATYPE>
00243     static void MLKernelToolsCorrelateLineWithImageInterval(const IN_DATATYPE *inCursor,
00244                                                             OUT_DATATYPE      *outCursor,
00245                                                             size_t            numVox,
00246                                                             const K_DATATYPE  *valTab,
00247                                                             const MLsoffset   *indexTab,
00248                                                             size_t            indexTabSize,
00249                                                             MLsoffset         srcVoxelOffset,
00250                                                             MLdouble          minVal,
00251                                                             MLdouble          maxVal)
00252   {
00253     ML_TRACE_IN( "MLKernelToolsCorrelateLineWithImageInterval( )" );
00254     ML_TRY
00255     {
00256       // Test whether we have a normal interval or an exclusive one (i.e. min > max).
00257       const bool normal = minVal <= maxVal;
00258 
00259       typedef typename TypeTraits<OUT_DATATYPE>::IntermediateType IntermediateType;
00260 
00261       // Apply kernel tab to all voxels in line.
00262       for (size_t i=0; i < numVox; i++){
00263         IN_DATATYPE srcVox = *(inCursor+srcVoxelOffset);
00264 
00265         // Test input image voxel. Is it in image interval?
00266         if (! isScalarValueInRange(srcVox, normal, minVal, maxVal)){
00267           // No, copy value from input.
00268           *outCursor = static_cast<OUT_DATATYPE>(srcVox);
00269         }
00270         else{
00271           // Sum up the products of the kernel element values and the input image voxels which are
00272           // found in the input page covered by kernel elements. Input image voxels are found
00273           // by offsetting the pointer to the input image voxel with the indexes from indexTab.
00274 
00275           // IntermediateType is double for scalar types and OUT_DATATYPE itself for all other types
00276           IntermediateType retVal = ml_cast_from_scalar<IntermediateType>(0);
00277           for (size_t c=0; c < indexTabSize; c++){
00278             retVal += static_cast<IntermediateType>(inCursor[indexTab[c]]) * 
00279                       ml_scalar_factor_cast<IntermediateType>(valTab[c]);
00280           }
00281 
00282           // Write result into output image.
00283           *outCursor = ml_cast_from_intermediate_type_without_clamping<OUT_DATATYPE>(retVal);
00284 
00285         } // else
00286 
00287         // Move read and write cursor forward.
00288         ++outCursor;
00289         ++inCursor;
00290       } // for 
00291     }
00292     ML_CATCH_RETHROW;
00293   }
00294 
00295 
00296 
00297 
00298   //-------------------------------------------------------------------------------------------
00316   //-------------------------------------------------------------------------------------------
00317   template <typename IN_DATATYPE, typename OUT_DATATYPE, typename K_DATATYPE>
00318     static void MLKernelToolsCorrelateLineWithKernelInterval(const IN_DATATYPE *inCursor,
00319                                                              OUT_DATATYPE      *outCursor,
00320                                                              size_t            numVox,
00321                                                              const K_DATATYPE  *valTab,
00322                                                              const MLsoffset   *indexTab,
00323                                                              size_t            indexTabSize,
00324                                                              MLsoffset         srcVoxelOffset,
00325                                                              MLdouble          minVal,
00326                                                              MLdouble          maxVal)
00327   {
00328     ML_TRACE_IN( "MLKernelToolsCorrelateLineWithKernelInterval ( )" );
00329     ML_TRY
00330     {
00331       // Test whether we have a normal interval or an exclusive one (i.e. min > max).
00332       const bool normal = minVal <= maxVal;
00333 
00334       typedef typename TypeTraits<OUT_DATATYPE>::IntermediateType IntermediateType;
00335 
00336       // Apply kernel tab to all voxels in line.
00337       for (size_t i=0; i < numVox; i++){
00338 
00339         // Sums of weights for the kernel elements
00340         MLdouble posValSum = 0; // that match the threshold criterion
00341         MLdouble negValSum = 0; // that doesn't match the threshold criterion
00342 
00343         // IntermediateType is double for scalar types and OUT_DATATYPE itself for all other types
00344         IntermediateType retVal = ml_cast_from_scalar<IntermediateType>(0);
00345         for (size_t c=0; c < indexTabSize; c++){
00346           IN_DATATYPE val = inCursor[indexTab[c]];
00347 
00348           // Get element from kernel table and multiply it with its corresponding input
00349           // page voxel and add it to result value. Do this only if the voxel belongs
00350           // to the kernel interval. Sum up the weights of valid and invalid voxels.
00351           if (isScalarValueInRange(val, normal, minVal, maxVal)){
00352             retVal += static_cast<IntermediateType>(val) * 
00353                       ml_scalar_factor_cast<IntermediateType>(valTab[c]);
00354             posValSum += valTab[c];
00355           }
00356           else {
00357             negValSum += valTab[c];
00358           }
00359         }
00360 
00361         // If any value has been added to retVal then pretend as if all kernel voxels which did
00362         // not match the kernel threshold interval hold the weighted average of those who did.
00363         // Otherwise return value from input image which is under the replaced output image voxel.
00364         if (MLValueIs0WOM(posValSum)) {
00365           *outCursor = static_cast<OUT_DATATYPE>(inCursor[srcVoxelOffset]);
00366         } else {
00367           *outCursor = ml_cast_from_intermediate_type_without_clamping<OUT_DATATYPE>(retVal *
00368             ml_scalar_factor_cast<IntermediateType>((posValSum + negValSum) / posValSum));
00369         }
00370 
00371         // Move read and write cursor forward.
00372         ++outCursor;
00373         ++inCursor;
00374       }
00375     }
00376     ML_CATCH_RETHROW;
00377   }
00378 
00379 
00380 
00381 
00382   //-------------------------------------------------------------------------------------------
00403   //-------------------------------------------------------------------------------------------
00404   template <typename IN_DATATYPE, typename OUT_DATATYPE, typename K_DATATYPE>
00405     static void MLKernelToolsCorrelateLineWithImageAndKernelInterval(const IN_DATATYPE *inCursor,
00406                                                                      OUT_DATATYPE      *outCursor,
00407                                                                      size_t            numVox,
00408                                                                      const K_DATATYPE  *valTab,
00409                                                                      const MLsoffset   *indexTab,
00410                                                                      size_t            indexTabSize,
00411                                                                      MLsoffset         srcVoxelOffset,
00412                                                                      MLdouble          imgIntMinVal,
00413                                                                      MLdouble          imgIntMaxVal,
00414                                                                      MLdouble          kernIntMinVal,
00415                                                                      MLdouble          kernIntMaxVal)
00416   {
00417     ML_TRACE_IN( "MLKernelToolsCorrelateLineWithImageAndKernelInterval( )" );
00418     ML_TRY
00419     {
00420       // Test whether we have a normal interval or an exclusive one (i.e. min > max).
00421       const bool normalImgInt  = imgIntMinVal  <= imgIntMaxVal;
00422       const bool normalKernInt = kernIntMinVal <= kernIntMaxVal;
00423 
00424       typedef typename TypeTraits<OUT_DATATYPE>::IntermediateType IntermediateType;
00425 
00426       // Scan all voxels in line.
00427       for (size_t i=0; i < numVox; i++){
00428 
00429         // Get pointer to kernel origin in input data and the voxel corresponding to the changed voxel.
00430         const IN_DATATYPE *voxPtr = inCursor;
00431         IN_DATATYPE       srcVox  = *(voxPtr+srcVoxelOffset);
00432 
00433         // Test input image voxel. Is it in image interval?
00434         if (! isScalarValueInRange(srcVox, normalImgInt, imgIntMinVal, imgIntMaxVal)){
00435           // No, copy value from input.
00436           *outCursor = static_cast<OUT_DATATYPE>(srcVox);
00437         }
00438         else{
00439           // Yes, voxel needs to be filtered.
00440 
00441           // Sums of weights for the kernel elements
00442           MLdouble posValSum = 0; // that match the threshold criterion
00443           MLdouble negValSum = 0; // that do not match the threshold criterion
00444 
00445           // IntermediateType is double for scalar types and OUT_DATATYPE itself for all other types
00446           IntermediateType retVal = ml_cast_from_scalar<IntermediateType>(0);
00447           for (size_t c=0; c < indexTabSize; c++){
00448             IN_DATATYPE val = inCursor[indexTab[c]];
00449 
00450             // Get element from kernel table and multiply it with its corresponding input
00451             // page voxel and add it to result value. Do this only if the voxel belongs
00452             // to the kernel interval. Sum up the weights of valid and invalid voxels.
00453             if (isScalarValueInRange(val, normalKernInt, kernIntMinVal, kernIntMaxVal)){
00454               retVal += static_cast<IntermediateType>(val) * 
00455                         ml_scalar_factor_cast<IntermediateType>(valTab[c]);
00456               posValSum += valTab[c];
00457             }
00458             else {
00459               negValSum += valTab[c];
00460             }
00461           }
00462 
00463           // If any value has been added to retVal then pretend as if all kernel voxels which did
00464           // not match the kernel threshold interval hold the weighted average of those who did.
00465           // Otherwise return value from input image which is under the replaced output image voxel.
00466           if (MLValueIs0WOM(posValSum)) {
00467             *outCursor = static_cast<OUT_DATATYPE>(inCursor[srcVoxelOffset]);
00468           } else {
00469             *outCursor = ml_cast_from_intermediate_type_without_clamping<OUT_DATATYPE>(retVal *
00470               ml_scalar_factor_cast<IntermediateType>((posValSum + negValSum) / posValSum));
00471           }
00472 
00473         }  // else
00474 
00475         // Move read and write cursor forward.
00476         ++outCursor;
00477         ++inCursor;
00478       }
00479     }
00480     ML_CATCH_RETHROW;
00481   }
00482 
00483   //-------------------------------------------------------------------------------------------
00494   //-------------------------------------------------------------------------------------------
00495   template <typename IN_DATATYPE, typename OUT_DATATYPE, typename K_DATATYPE>
00496     static void MLKernelToolsCorrelateLineEvtWithIntervals(const IN_DATATYPE *inCursor,
00497                                                            OUT_DATATYPE      *outCursor,
00498                                                            size_t            numVox,
00499                                                            const K_DATATYPE  *valTab,
00500                                                            const MLsoffset   *indexTab,
00501                                                            size_t            indexTabSize,
00502                                                            MLsoffset         srcVoxelOffset,
00503                                                            MLdouble          imgIntMinVal,
00504                                                            MLdouble          imgIntMaxVal,
00505                                                            MLdouble          kernIntMinVal,
00506                                                            MLdouble          kernIntMaxVal,
00507                                                            bool              useImgInt,
00508                                                            bool              useKernInt)
00509   {
00510     ML_TRACE_IN( "MLKernelToolsCorrelateLineEvtWithIntervals( )" );
00511     ML_TRY
00512     {
00513       if (useImgInt && !useKernInt) {
00514         // Image interval on but kernel interval off:
00515         MLKernelToolsCorrelateLineWithImageInterval(inCursor,
00516                                                     outCursor,
00517                                                     numVox,
00518                                                     valTab,
00519                                                     indexTab,
00520                                                     indexTabSize,
00521                                                     srcVoxelOffset,
00522                                                     imgIntMinVal,
00523                                                     imgIntMaxVal);
00524       } else if (!useImgInt && useKernInt) {
00525         // Image interval off but kernel interval on:
00526         MLKernelToolsCorrelateLineWithKernelInterval(inCursor,
00527                                                      outCursor,
00528                                                      numVox,
00529                                                      valTab,
00530                                                      indexTab,
00531                                                      indexTabSize,
00532                                                      srcVoxelOffset,
00533                                                      kernIntMinVal,
00534                                                      kernIntMaxVal);
00535       } else if (useImgInt && useKernInt) {
00536         // Image interval and kernel interval on:
00537         MLKernelToolsCorrelateLineWithImageAndKernelInterval(inCursor,
00538                                                              outCursor,
00539                                                              numVox,
00540                                                              valTab,
00541                                                              indexTab,
00542                                                              indexTabSize,
00543                                                              srcVoxelOffset,
00544                                                              imgIntMinVal,
00545                                                              imgIntMaxVal,
00546                                                              kernIntMinVal,
00547                                                              kernIntMaxVal);
00548       } else {
00549         // Convolute the line normally without using intervals.
00550         MLKernelToolsCorrelateLine(inCursor,
00551                                    outCursor,
00552                                    numVox,
00553                                    valTab,
00554                                    indexTab,
00555                                    indexTabSize);
00556       }
00557     }
00558     ML_CATCH_RETHROW
00559 
00560   } // correlateLineEvtWithIntervals
00561 
00563 
00564 
00565 
00566   //---------------------------------------------------------------------------------------------
00674   //---------------------------------------------------------------------------------------------
00675   class MLKERNELEXPORT KernelTools
00676   {
00677     public:
00678 
00679 
00680     //---------------------------------------------------------------------------------------------
00682 
00683     //---------------------------------------------------------------------------------------------
00684 
00685     //-------------------------------------------------------------------------------------------
00730     //-------------------------------------------------------------------------------------------
00731     enum BorderHandling {NO_PAD              = 0,
00732                          PAD_SRC_FILL        ,
00733                          PAD_DST_FILL        ,
00734                          PAD_DST_ORIGFILL    ,
00735                          PAD_SRC_UNDEFINED   ,
00736                          PAD_DST_UNDEFINED   ,
00737                          PAD_SRC_CLAMP       ,
00738 
00739                          NUM_BORDER_HANDLINGS};
00740 
00741     //-------------------------------------------------------------------------------------------
00743     //-------------------------------------------------------------------------------------------
00744     static const char* const BorderHandlingNames[];
00746 
00747 
00748 
00749 
00750 
00751     //-------------------------------------------------------------------------------------------
00753 
00754     //-------------------------------------------------------------------------------------------
00755 
00763     static MLsoffset *createIndexTab(const ImageVector &inSubImgStrides, const Kernel &kernel);
00764 
00767     static void deleteIndexTab(MLsoffset *idxTab);
00768 
00774     static MLsoffset calcSrcVoxelOffset(const ImageVector &strides, 
00775                                         const ImageVector &kernelNegExt);
00776 
00780     static ImageVector calcOutImageExt(const ImageVector   &imgExt,
00781                                   const ImageVector   &kernelExt,
00782                                   BorderHandling borderHandling, 
00783                                   MLint          numIterations=1);
00784 
00788     static void adaptWorldCoordinates(PagedImage &outImg,
00789                                       BorderHandling borderHandling,
00790                                       const ImageVector &negExt);
00791 
00800     static void expandForSeparableOrIterativeFiltering(SubImageBox  &box, 
00801                                                        const ImageVector &negKernelExt, 
00802                                                        const ImageVector &posKernelExt, 
00803                                                        bool          isSeparable, 
00804                                                        MLint         numIterations);
00805 
00823     static SubImageBox calcInSubImageBoxForOutSubImg(const SubImageBox &outSubImgBox,
00824                                                    BorderHandling   borderHandling,
00825                                                    const ImageVector    &negExt,
00826                                                    const ImageVector    &posExt,
00827                                                    bool             isSeparable=false,
00828                                                    MLint            numIterations=1);
00829 
00839     static ImageVector calcOutInCoordShift(BorderHandling borderHandling, 
00840                                       const ImageVector  &negKernelExt);
00841 
00850     static SubImageBox calcAreaToBeCalculated(const ImageVector  &inImgExt,
00851                                             const ImageVector  &negFilterExt,
00852                                             const ImageVector  &posFilterExt,
00853                                             BorderHandling borderHandling,
00854                                             bool           isSeparable=false,
00855                                             MLint          numIterations=1);
00856 
00857 
00867     static void fillBorders(const ImageVector           &inImgExt,
00868                             const ImageVector           &negKernelExt,
00869                             const ImageVector           &posKernelExt,
00870                             KernelTools::BorderHandling  borderHandling,
00871                             MLdouble                     fillValue,
00872                             SubImage                     &outSubImg,
00873                             SubImage                    &inSubImg);
00874  
00876 
00877 
00878 
00879 
00880     //-------------------------------------------------------------------------------------------
00882     //-------------------------------------------------------------------------------------------
00884     template <typename IN_DATATYPE, typename OUT_DATATYPE>
00885       static void copyLine(const IN_DATATYPE *inCursor,
00886                            OUT_DATATYPE      *outCursor,
00887                            size_t            numVox,
00888                            MLsoffset         srcVoxelOffset)
00889     {
00890       MLKernelToolsCopyLine(inCursor, outCursor, numVox, srcVoxelOffset);
00891     }
00892 
00894     template <typename IN_DATATYPE, typename OUT_DATATYPE, typename K_DATATYPE>
00895       static void correlateLine(const IN_DATATYPE *inCursor,
00896                                 OUT_DATATYPE      *outCursor,
00897                                 size_t             numVox,
00898                                 const K_DATATYPE  *valTab,
00899                                 const MLsoffset   *indexTab,
00900                                 size_t             indexTabSize)
00901     {
00902       MLKernelToolsCorrelateLine(inCursor, outCursor, numVox, valTab, indexTab, indexTabSize);
00903     }
00904 
00906     template <typename IN_DATATYPE, typename OUT_DATATYPE, typename K_DATATYPE>
00907       static void correlateLineWithImageInterval(const IN_DATATYPE *inCursor,
00908                                                  OUT_DATATYPE      *outCursor,
00909                                                  size_t            numVox,
00910                                                  const K_DATATYPE  *valTab,
00911                                                  const MLsoffset   *indexTab,
00912                                                  size_t            indexTabSize,
00913                                                  MLsoffset         srcVoxelOffset,
00914                                                  MLdouble          minVal,
00915                                                  MLdouble          maxVal)
00916     {
00917       MLKernelToolsCorrelateLineWithImageInterval(inCursor, outCursor, numVox, valTab, indexTab, indexTabSize, srcVoxelOffset, minVal, maxVal);
00918     }
00919 
00921     template <typename IN_DATATYPE, typename OUT_DATATYPE, typename K_DATATYPE>
00922       static void correlateLineWithKernelInterval(const IN_DATATYPE *inCursor,
00923                                                   OUT_DATATYPE      *outCursor,
00924                                                   size_t            numVox,
00925                                                   const K_DATATYPE  *valTab,
00926                                                   const MLsoffset   *indexTab,
00927                                                   size_t            indexTabSize,
00928                                                   MLsoffset         srcVoxelOffset,
00929                                                   MLdouble          minVal,
00930                                                   MLdouble          maxVal)
00931     {
00932       MLKernelToolsCorrelateLineWithKernelInterval(inCursor, outCursor, numVox, valTab, indexTab, indexTabSize, srcVoxelOffset, minVal, maxVal);
00933     }
00934 
00936     template <typename IN_DATATYPE, typename OUT_DATATYPE, typename K_DATATYPE>
00937       static void correlateLineWithImageAndKernelInterval(const IN_DATATYPE *inCursor,
00938                                                           OUT_DATATYPE      *outCursor,
00939                                                           size_t            numVox,
00940                                                           const K_DATATYPE  *valTab,
00941                                                           const MLsoffset   *indexTab,
00942                                                           size_t            indexTabSize,
00943                                                           MLsoffset         srcVoxelOffset,
00944                                                           MLdouble          imgIntMinVal,
00945                                                           MLdouble          imgIntMaxVal,
00946                                                           MLdouble          kernIntMinVal,
00947                                                           MLdouble          kernIntMaxVal)
00948     {
00949       MLKernelToolsCorrelateLineWithImageAndKernelInterval(inCursor, outCursor, numVox, valTab, indexTab, indexTabSize, srcVoxelOffset,
00950                                                            imgIntMinVal, imgIntMaxVal, kernIntMinVal, kernIntMaxVal);
00951     }
00952 
00954     template <typename IN_DATATYPE, typename OUT_DATATYPE, typename K_DATATYPE>
00955       static void correlateLineEvtWithIntervals(const IN_DATATYPE *inCursor,
00956                                                 OUT_DATATYPE      *outCursor,
00957                                                 size_t            numVox,
00958                                                 const K_DATATYPE  *valTab,
00959                                                 const MLsoffset   *indexTab,
00960                                                 size_t            indexTabSize,
00961                                                 MLsoffset         srcVoxelOffset,
00962                                                 MLdouble          imgIntMinVal,
00963                                                 MLdouble          imgIntMaxVal,
00964                                                 MLdouble          kernIntMinVal,
00965                                                 MLdouble          kernIntMaxVal,
00966                                                 bool              useImgInt,
00967                                                 bool              useKernInt)
00968     {
00969       MLKernelToolsCorrelateLineEvtWithIntervals(inCursor, outCursor, numVox, valTab, indexTab, indexTabSize, srcVoxelOffset,
00970                                                  imgIntMinVal, imgIntMaxVal, kernIntMinVal, kernIntMaxVal, useImgInt, useKernInt);
00971     }
00972 
00973 // Exclude some files for an older release for a SYNGO application. 
00974 // The "if !defined" is going to be removed in future.
00975 #if !defined(USE_SYNGO)
00976 
00977     template <typename DATATYPE>
00978       static void applyFiltering(const ImageVector        &inImgExt,
00979                                  LineApplicator<DATATYPE> &lineApp,
00980                                  BorderHandling           borderHandling,
00981                                  MLdouble                 fillValue,
00982                                  TSubImageWithCursor<DATATYPE>        &outSubImg,
00983                                  TSubImageWithCursor<DATATYPE>        &inSubImg)
00984     {
00985       MLKernelToolsApplyFiltering(inImgExt,lineApp,  borderHandling, fillValue, outSubImg, inSubImg);
00986     }
00987 #endif
00988 
00990     template <typename DATATYPE>
00991       static void applyFiltering(const ImageVector             &inImgExt,
00992                                  const fctLineFilter<DATATYPE> &lineFilter,
00993                                  const ImageVector             &negKernelExt,
00994                                  const ImageVector             &posKernelExt,
00995                                  BorderHandling                borderHandling,
00996                                  MLdouble                      fillValue,
00997                                  TSubImageWithCursor<DATATYPE>             &outSubImg,
00998                                  TSubImageWithCursor<DATATYPE>             &inSubImg)
00999     {
01000       MLKernelToolsApplyFiltering(inImgExt, lineFilter, negKernelExt, posKernelExt, borderHandling, fillValue, outSubImg, inSubImg);
01001     }
01003 
01004   }; // end of class KernelTools
01005 
01006 
01007 
01008   //-------------------------------------------------------------------------------------------
01010   //-------------------------------------------------------------------------------------------
01011 
01012 // Exclude some files for an older release for a SYNGO application. 
01013 // The "if !defined" is going to be removed in future.
01014 #if !defined(USE_SYNGO)
01015   //-------------------------------------------------------------------------------------------
01030   //-------------------------------------------------------------------------------------------
01031   template <typename DATATYPE>
01032     static void MLKernelToolsApplyFiltering(const ImageVector           &inImgExt,
01033                                             LineApplicator<DATATYPE>    &lineApp,
01034                                             KernelTools::BorderHandling borderHandling,
01035                                             MLdouble                    fillValue,
01036                                             TSubImageWithCursor<DATATYPE>           &outSubImg,
01037                                             TSubImageWithCursor<DATATYPE>           &inSubImg)
01038   {
01039     // Extract parameters for the internal \c _applyFiltering function from \c KernelLineApplicator object
01040     MLKernelToolsApplyFiltering(inImgExt,
01041                                 useObjectLineFilter<LineApplicator<DATATYPE>, DATATYPE>
01042                                         (&lineApp, &LineApplicator<DATATYPE>::applyToLine),
01043                                 lineApp.getNegativeExtent(),
01044                                 lineApp.getPositiveExtent(),
01045                                 borderHandling,
01046                                 fillValue,
01047                                 outSubImg,
01048                                 inSubImg);
01049   }
01050 #endif
01051 
01052   //-------------------------------------------------------------------------------------------
01062   //-------------------------------------------------------------------------------------------
01063   template <typename DATATYPE>
01064     static void MLKernelToolsApplyFiltering(const ImageVector             &inImgExt,
01065                                             const fctLineFilter<DATATYPE> &lineFilter,
01066                                             const ImageVector             &negKernelExt,
01067                                             const ImageVector             &posKernelExt,
01068                                             KernelTools::BorderHandling   borderHandling,
01069                                             MLdouble                      fillValue,
01070                                             TSubImageWithCursor<DATATYPE>             &outSubImg,
01071                                             TSubImageWithCursor<DATATYPE>             &inSubImg)
01072   {
01073     ML_TRACE_IN( "MLKernelToolsApplyFiltering( )" );
01074     ML_TRY
01075     {
01076       // Fill border of subimages before calculating the correct area in output subimage.
01077       KernelTools::fillBorders(inImgExt, negKernelExt, posKernelExt, borderHandling, fillValue, outSubImg, inSubImg);
01078 
01079       // Calculate output image area to be calculated.
01080       SubImageBox area(KernelTools::calcAreaToBeCalculated(inImgExt, negKernelExt, posKernelExt, borderHandling));
01081 
01082       // Clamp region to be filled in output page, because e.g. in PAD_DST_FILL not the
01083       // entire output buffer needs to be calculated; the rest is filled.
01084       SubImageBox calcArea = outSubImg.getBox();
01085       calcArea = calcArea.intersect(area);
01086 
01087       // Print size and position of output page.
01088       ImageVector ov1 = calcArea.v1;
01089       ImageVector ov2 = calcArea.v2;
01090       ImageVector pOf = KernelTools::calcOutInCoordShift(borderHandling, negKernelExt);
01091 
01092 
01093       // Scan all voxels of the output page in u,t,c,z, y and x direction with a 'voxel cursor'.
01094       ImageVector p;
01095       ImageVector rowStart;
01096       MLint  rowLength = ov2.x - ov1.x + 1;
01097       for (p.u=ov1.u;   p.u<=ov2.u;   p.u++){
01098         for (p.t=ov1.t;   p.t<=ov2.t;   p.t++){
01099           for (p.c=ov1.c;   p.c<=ov2.c;   p.c++){
01100             for (p.z=ov1.z;   p.z<=ov2.z;   p.z++){
01101               rowStart .set(0, 0, p.z, p.c, p.t, p.u);
01102               for (p.y=ov1.y;   p.y<=ov2.y;   p.y++){
01103                 // Move cursors in input and output subimage to start of rows.
01104                 // The input image cursor defines the current kernel placement.
01105                 // The output image cursor defines the result voxel filtered from kernel and input image values.
01106                 // Note that both cursors are placed in global image coordinates, and NOT in local page coordinates!
01107                 rowStart .x = ov1.x;
01108                 rowStart .y = p.y;
01109                 outSubImg.setCursorImgPos(rowStart);
01110                 inSubImg .setCursorImgPos(rowStart-pOf);
01111 
01112                 // Apply the kernel to a line in the input image and write result into the
01113                 // output image. Note that \c lineFilter is a function-like object whose
01114                 // operator() (TSubImageWithCursor<DATATYPE> *, TSubImageWithCursor<DATATYPE> *, long) is called
01115                 // when the object is used as function.
01116                 lineFilter(&inSubImg, &outSubImg, static_cast<size_t>(rowLength));
01117               }
01118             }
01119           }
01120         }
01121       }
01122     }
01123     ML_CATCH_RETHROW;
01124   }
01126 
01127 ML_END_NAMESPACE
01128 
01129 #endif // __mlKernelTools_H
01130 
01131 
01132