MeVisLabToolboxReference
|
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