MeVisLab Toolbox Reference
mlKernelTools.h
Go to the documentation of this file.
1 /*************************************************************************************
2 **
3 ** Copyright 2007, MeVis Medical Solutions AG
4 **
5 ** The user may use this file in accordance with the license agreement provided with
6 ** the Software or, alternatively, in accordance with the terms contained in a
7 ** written agreement between the user and MeVis Medical Solutions AG.
8 **
9 ** For further information use the contact form at https://www.mevislab.de/contact
10 **
11 **************************************************************************************/
12 
13 
16 
17 #if !defined(__mlKernelTools_H)
18 #define __mlKernelTools_H
19 
20 // ML-includes
21 #include "mlInitSystemKernel.h"
22 #include "mlLineApplicator.h"
23 #include "mlKernel.h"
24 
25 ML_START_NAMESPACE
26 
27  //---------------------------------------------------------------------------------------------
30  //---------------------------------------------------------------------------------------------
31 
32  //-------------------------------------------------------------------------------------------
52  //-------------------------------------------------------------------------------------------
53  template<typename DATATYPE> struct fctLineFilter{
54  public:
59  virtual void operator() (TSubImageWithCursor<DATATYPE> *, TSubImageWithCursor<DATATYPE> *, size_t) const {}
60 
62  virtual ~fctLineFilter() {}
63  };
64 
65  //-------------------------------------------------------------------------------------------
71  //-------------------------------------------------------------------------------------------
72  template<class T, typename DATATYPE>
73  struct useObjectLineFilter : public fctLineFilter<DATATYPE>{
74 
78  T* pOb;
79 
84 
85  public:
91  pOb(po), pLF(pf) {}
92 
94  ~useObjectLineFilter() override {}
95 
101  void operator () (TSubImageWithCursor<DATATYPE> *inSubImg, TSubImageWithCursor<DATATYPE> *outSubImg, size_t numVox) const override
102  { (pOb->*pLF)(inSubImg, outSubImg, numVox);}
103  };
105 
106 
107 
108  //-------------------------------------------------------------------------------------------
109  //
111  //
112  //-------------------------------------------------------------------------------------------
113 
114  //-------------------------------------------------------------------------------------------
118  //-------------------------------------------------------------------------------------------
119 
120  // internal function, for scalar types
121  template <typename DATATYPE>
122  static inline bool _isScalarValueInRange(const DATATYPE& v, bool normal, double minVal, double maxVal,
124  {
125  if (normal) {
126  return (v >= minVal) && (v <= maxVal);
127  } else {
128  return (v < maxVal) || (v > minVal);
129  }
130  }
131 
132  // internal function, for non-scalar types
133  template <typename DATATYPE>
134  static inline bool _isScalarValueInRange(const DATATYPE&, bool, double, double,
136  {
137  return true;
138  }
139  template <typename DATATYPE>
140  static inline bool isScalarValueInRange(const DATATYPE& v, bool normal, double minVal, double maxVal)
141  {
142  return _isScalarValueInRange(v, normal, minVal, maxVal, OverloadSelector::isScalarType<DATATYPE>());
143  }
144 
145  //-------------------------------------------------------------------------------------------
149  //-------------------------------------------------------------------------------------------
150  template <typename IN_DATATYPE, typename OUT_DATATYPE>
151  static void MLKernelToolsCopyLine(const IN_DATATYPE *inCursor,
152  OUT_DATATYPE *outCursor,
153  size_t numVox,
154  MLsoffset srcVoxelOffset)
155  {
156  if (inCursor == nullptr || outCursor == nullptr) {
157  return;
158  }
159 
160  // Add srcVoxelOffset to inCursor. So we don't need to do it again and again in the loop.
161  inCursor += srcVoxelOffset;
162  for (size_t i=0; i<numVox; ++i){
163  // Copy input voxel to output.
164  *outCursor = static_cast<OUT_DATATYPE>(*inCursor);
165 
166  // Move read and write cursor forward.
167  ++outCursor;
168  ++inCursor;
169  }
170  }
171 
172  //-------------------------------------------------------------------------------------------
183  //-------------------------------------------------------------------------------------------
184  template <typename IN_DATATYPE, typename OUT_DATATYPE, typename K_DATATYPE>
185  static void MLKernelToolsCorrelateLine(const IN_DATATYPE *inCursor,
186  OUT_DATATYPE *outCursor,
187  size_t numVox,
188  const K_DATATYPE *valTab,
189  const MLsoffset *indexTab,
190  size_t indexTabSize)
191  {
192  // Sum up the products of the kernel element values and the input image voxels which are
193  // found in the input page covered by kernel elements. Input image voxels are found
194  // by offsetting the pointer to the input image voxel with the indexes from indexTab.
195 
196  typedef typename TypeTraits<OUT_DATATYPE>::IntermediateType IntermediateType;
197 
198  // Apply kernel tab to all voxels in line.
199  for (size_t i=0; i < numVox; i++){
200 
201  // IntermediateType is double for scalar types and OUT_DATATYPE itself for all other types
202  IntermediateType retVal = ml_cast_from_scalar<IntermediateType>(0);
203  for (size_t c=0; c < indexTabSize; c++){
204  retVal += static_cast<IntermediateType>(inCursor[indexTab[c]]) *
205  ml_scalar_factor_cast<IntermediateType>(valTab[c]);
206  }
207 
208  // Write result into output image.
209  *outCursor = ml_cast_from_intermediate_type_without_clamping<OUT_DATATYPE>(retVal);
210 
211  // Move read and write cursor forward.
212  ++outCursor;
213  ++inCursor;
214  } // for
215  }
216 
217  //-------------------------------------------------------------------------------------------
232  //-------------------------------------------------------------------------------------------
233  template <typename IN_DATATYPE, typename OUT_DATATYPE, typename K_DATATYPE>
234  static void MLKernelToolsCorrelateLineWithImageInterval(const IN_DATATYPE *inCursor,
235  OUT_DATATYPE *outCursor,
236  size_t numVox,
237  const K_DATATYPE *valTab,
238  const MLsoffset *indexTab,
239  size_t indexTabSize,
240  MLsoffset srcVoxelOffset,
241  MLdouble minVal,
242  MLdouble maxVal)
243  {
244  // Test whether we have a normal interval or an exclusive one (i.e. min > max).
245  const bool normal = minVal <= maxVal;
246 
247  typedef typename TypeTraits<OUT_DATATYPE>::IntermediateType IntermediateType;
248 
249  // Apply kernel tab to all voxels in line.
250  for (size_t i=0; i < numVox; i++){
251  IN_DATATYPE srcVox = *(inCursor+srcVoxelOffset);
252 
253  // Test input image voxel. Is it in image interval?
254  if (! isScalarValueInRange(srcVox, normal, minVal, maxVal)){
255  // No, copy value from input.
256  *outCursor = static_cast<OUT_DATATYPE>(srcVox);
257  }
258  else{
259  // Sum up the products of the kernel element values and the input image voxels which are
260  // found in the input page covered by kernel elements. Input image voxels are found
261  // by offsetting the pointer to the input image voxel with the indexes from indexTab.
262 
263  // IntermediateType is double for scalar types and OUT_DATATYPE itself for all other types
264  IntermediateType retVal = ml_cast_from_scalar<IntermediateType>(0);
265  for (size_t c=0; c < indexTabSize; c++){
266  retVal += static_cast<IntermediateType>(inCursor[indexTab[c]]) *
267  ml_scalar_factor_cast<IntermediateType>(valTab[c]);
268  }
269 
270  // Write result into output image.
271  *outCursor = ml_cast_from_intermediate_type_without_clamping<OUT_DATATYPE>(retVal);
272 
273  } // else
274 
275  // Move read and write cursor forward.
276  ++outCursor;
277  ++inCursor;
278  } // for
279  }
280 
281 
282 
283 
284  //-------------------------------------------------------------------------------------------
302  //-------------------------------------------------------------------------------------------
303  template <typename IN_DATATYPE, typename OUT_DATATYPE, typename K_DATATYPE>
304  static void MLKernelToolsCorrelateLineWithKernelInterval(const IN_DATATYPE *inCursor,
305  OUT_DATATYPE *outCursor,
306  size_t numVox,
307  const K_DATATYPE *valTab,
308  const MLsoffset *indexTab,
309  size_t indexTabSize,
310  MLsoffset srcVoxelOffset,
311  MLdouble minVal,
312  MLdouble maxVal)
313  {
314  // Test whether we have a normal interval or an exclusive one (i.e. min > max).
315  const bool normal = minVal <= maxVal;
316 
317  typedef typename TypeTraits<OUT_DATATYPE>::IntermediateType IntermediateType;
318 
319  // Apply kernel tab to all voxels in line.
320  for (size_t i=0; i < numVox; i++){
321 
322  // Sums of weights for the kernel elements
323  MLdouble posValSum = 0; // that match the threshold criterion
324  MLdouble negValSum = 0; // that doesn't match the threshold criterion
325 
326  // IntermediateType is double for scalar types and OUT_DATATYPE itself for all other types
327  IntermediateType retVal = ml_cast_from_scalar<IntermediateType>(0);
328  for (size_t c=0; c < indexTabSize; c++){
329  IN_DATATYPE val = inCursor[indexTab[c]];
330 
331  // Get element from kernel table and multiply it with its corresponding input
332  // page voxel and add it to result value. Do this only if the voxel belongs
333  // to the kernel interval. Sum up the weights of valid and invalid voxels.
334  if (isScalarValueInRange(val, normal, minVal, maxVal)){
335  retVal += static_cast<IntermediateType>(val) *
336  ml_scalar_factor_cast<IntermediateType>(valTab[c]);
337  posValSum += valTab[c];
338  }
339  else {
340  negValSum += valTab[c];
341  }
342  }
343 
344  // If any value has been added to retVal then pretend as if all kernel voxels which did
345  // not match the kernel threshold interval hold the weighted average of those who did.
346  // Otherwise return value from input image which is under the replaced output image voxel.
347  if (MLValueIs0WOM(posValSum)) {
348  *outCursor = static_cast<OUT_DATATYPE>(inCursor[srcVoxelOffset]);
349  } else {
350  *outCursor = ml_cast_from_intermediate_type_without_clamping<OUT_DATATYPE>(retVal *
351  ml_scalar_factor_cast<IntermediateType>((posValSum + negValSum) / posValSum));
352  }
353 
354  // Move read and write cursor forward.
355  ++outCursor;
356  ++inCursor;
357  }
358  }
359 
360 
361 
362 
363  //-------------------------------------------------------------------------------------------
384  //-------------------------------------------------------------------------------------------
385  template <typename IN_DATATYPE, typename OUT_DATATYPE, typename K_DATATYPE>
386  static void MLKernelToolsCorrelateLineWithImageAndKernelInterval(const IN_DATATYPE *inCursor,
387  OUT_DATATYPE *outCursor,
388  size_t numVox,
389  const K_DATATYPE *valTab,
390  const MLsoffset *indexTab,
391  size_t indexTabSize,
392  MLsoffset srcVoxelOffset,
393  MLdouble imgIntMinVal,
394  MLdouble imgIntMaxVal,
395  MLdouble kernIntMinVal,
396  MLdouble kernIntMaxVal)
397  {
398  // Test whether we have a normal interval or an exclusive one (i.e. min > max).
399  const bool normalImgInt = imgIntMinVal <= imgIntMaxVal;
400  const bool normalKernInt = kernIntMinVal <= kernIntMaxVal;
401 
402  typedef typename TypeTraits<OUT_DATATYPE>::IntermediateType IntermediateType;
403 
404  // Scan all voxels in line.
405  for (size_t i=0; i < numVox; i++){
406 
407  // Get pointer to kernel origin in input data and the voxel corresponding to the changed voxel.
408  const IN_DATATYPE *voxPtr = inCursor;
409  IN_DATATYPE srcVox = *(voxPtr+srcVoxelOffset);
410 
411  // Test input image voxel. Is it in image interval?
412  if (! isScalarValueInRange(srcVox, normalImgInt, imgIntMinVal, imgIntMaxVal)){
413  // No, copy value from input.
414  *outCursor = static_cast<OUT_DATATYPE>(srcVox);
415  }
416  else{
417  // Yes, voxel needs to be filtered.
418 
419  // Sums of weights for the kernel elements
420  MLdouble posValSum = 0; // that match the threshold criterion
421  MLdouble negValSum = 0; // that do not match the threshold criterion
422 
423  // IntermediateType is double for scalar types and OUT_DATATYPE itself for all other types
424  IntermediateType retVal = ml_cast_from_scalar<IntermediateType>(0);
425  for (size_t c=0; c < indexTabSize; c++){
426  IN_DATATYPE val = inCursor[indexTab[c]];
427 
428  // Get element from kernel table and multiply it with its corresponding input
429  // page voxel and add it to result value. Do this only if the voxel belongs
430  // to the kernel interval. Sum up the weights of valid and invalid voxels.
431  if (isScalarValueInRange(val, normalKernInt, kernIntMinVal, kernIntMaxVal)){
432  retVal += static_cast<IntermediateType>(val) *
433  ml_scalar_factor_cast<IntermediateType>(valTab[c]);
434  posValSum += valTab[c];
435  }
436  else {
437  negValSum += valTab[c];
438  }
439  }
440 
441  // If any value has been added to retVal then pretend as if all kernel voxels which did
442  // not match the kernel threshold interval hold the weighted average of those who did.
443  // Otherwise return value from input image which is under the replaced output image voxel.
444  if (MLValueIs0WOM(posValSum)) {
445  *outCursor = static_cast<OUT_DATATYPE>(inCursor[srcVoxelOffset]);
446  } else {
447  *outCursor = ml_cast_from_intermediate_type_without_clamping<OUT_DATATYPE>(retVal *
448  ml_scalar_factor_cast<IntermediateType>((posValSum + negValSum) / posValSum));
449  }
450 
451  } // else
452 
453  // Move read and write cursor forward.
454  ++outCursor;
455  ++inCursor;
456  }
457  }
458 
459  //-------------------------------------------------------------------------------------------
470  //-------------------------------------------------------------------------------------------
471  template <typename IN_DATATYPE, typename OUT_DATATYPE, typename K_DATATYPE>
472  static void MLKernelToolsCorrelateLineEvtWithIntervals(const IN_DATATYPE *inCursor,
473  OUT_DATATYPE *outCursor,
474  size_t numVox,
475  const K_DATATYPE *valTab,
476  const MLsoffset *indexTab,
477  size_t indexTabSize,
478  MLsoffset srcVoxelOffset,
479  MLdouble imgIntMinVal,
480  MLdouble imgIntMaxVal,
481  MLdouble kernIntMinVal,
482  MLdouble kernIntMaxVal,
483  bool useImgInt,
484  bool useKernInt)
485  {
486  if (useImgInt && !useKernInt) {
487  // Image interval on but kernel interval off:
489  outCursor,
490  numVox,
491  valTab,
492  indexTab,
493  indexTabSize,
494  srcVoxelOffset,
495  imgIntMinVal,
496  imgIntMaxVal);
497  } else if (!useImgInt && useKernInt) {
498  // Image interval off but kernel interval on:
500  outCursor,
501  numVox,
502  valTab,
503  indexTab,
504  indexTabSize,
505  srcVoxelOffset,
506  kernIntMinVal,
507  kernIntMaxVal);
508  } else if (useImgInt && useKernInt) {
509  // Image interval and kernel interval on:
511  outCursor,
512  numVox,
513  valTab,
514  indexTab,
515  indexTabSize,
516  srcVoxelOffset,
517  imgIntMinVal,
518  imgIntMaxVal,
519  kernIntMinVal,
520  kernIntMaxVal);
521  } else {
522  // Convolute the line normally without using intervals.
524  outCursor,
525  numVox,
526  valTab,
527  indexTab,
528  indexTabSize);
529  }
530  } // correlateLineEvtWithIntervals
531 
533 
534 
535 
536  //---------------------------------------------------------------------------------------------
644  //---------------------------------------------------------------------------------------------
646  {
647  public:
648 
649 
650  //---------------------------------------------------------------------------------------------
653  //---------------------------------------------------------------------------------------------
654 
655  //-------------------------------------------------------------------------------------------
700  //-------------------------------------------------------------------------------------------
701  enum BorderHandling {NO_PAD = 0,
708 
709  NUM_BORDER_HANDLINGS};
710 
711  //-------------------------------------------------------------------------------------------
713  //-------------------------------------------------------------------------------------------
714  static const char* const BorderHandlingNames[];
716 
717 
718 
719 
720 
721  //-------------------------------------------------------------------------------------------
724  //-------------------------------------------------------------------------------------------
725 
733  static MLsoffset *createIndexTab(const ImageVector &inSubImgStrides, const Kernel &kernel);
734 
737  static void deleteIndexTab(MLsoffset *idxTab);
738 
744  static MLsoffset calcSrcVoxelOffset(const ImageVector &strides,
745  const ImageVector &kernelNegExt);
746 
751  const ImageVector &kernelExt,
752  BorderHandling borderHandling,
753  MLint numIterations=1);
754 
758  static void adaptWorldCoordinates(PagedImage &outImg,
759  BorderHandling borderHandling,
760  const ImageVector &negExt);
761 
771  const ImageVector &negKernelExt,
772  const ImageVector &posKernelExt,
773  bool isSeparable,
774  MLint numIterations);
775 
794  BorderHandling borderHandling,
795  const ImageVector &negExt,
796  const ImageVector &posExt,
797  bool isSeparable=false,
798  MLint numIterations=1);
799 
810  const ImageVector &negKernelExt);
811 
821  const ImageVector &negFilterExt,
822  const ImageVector &posFilterExt,
823  BorderHandling borderHandling,
824  bool isSeparable=false,
825  MLint numIterations=1);
826 
827 
837  static void fillBorders(const ImageVector &inImgExt,
838  const ImageVector &negKernelExt,
839  const ImageVector &posKernelExt,
840  KernelTools::BorderHandling borderHandling,
841  MLdouble fillValue,
842  SubImage &outSubImg,
843  SubImage &inSubImg);
844 
846 
847 
848 
849 
850  //-------------------------------------------------------------------------------------------
852  //-------------------------------------------------------------------------------------------
854  template <typename IN_DATATYPE, typename OUT_DATATYPE>
855  static void copyLine(const IN_DATATYPE *inCursor,
856  OUT_DATATYPE *outCursor,
857  size_t numVox,
858  MLsoffset srcVoxelOffset)
859  {
860  MLKernelToolsCopyLine(inCursor, outCursor, numVox, srcVoxelOffset);
861  }
862 
864  template <typename IN_DATATYPE, typename OUT_DATATYPE, typename K_DATATYPE>
865  static void correlateLine(const IN_DATATYPE *inCursor,
866  OUT_DATATYPE *outCursor,
867  size_t numVox,
868  const K_DATATYPE *valTab,
869  const MLsoffset *indexTab,
870  size_t indexTabSize)
871  {
872  MLKernelToolsCorrelateLine(inCursor, outCursor, numVox, valTab, indexTab, indexTabSize);
873  }
874 
876  template <typename IN_DATATYPE, typename OUT_DATATYPE, typename K_DATATYPE>
877  static void correlateLineWithImageInterval(const IN_DATATYPE *inCursor,
878  OUT_DATATYPE *outCursor,
879  size_t numVox,
880  const K_DATATYPE *valTab,
881  const MLsoffset *indexTab,
882  size_t indexTabSize,
883  MLsoffset srcVoxelOffset,
884  MLdouble minVal,
885  MLdouble maxVal)
886  {
887  MLKernelToolsCorrelateLineWithImageInterval(inCursor, outCursor, numVox, valTab, indexTab, indexTabSize, srcVoxelOffset, minVal, maxVal);
888  }
889 
891  template <typename IN_DATATYPE, typename OUT_DATATYPE, typename K_DATATYPE>
892  static void correlateLineWithKernelInterval(const IN_DATATYPE *inCursor,
893  OUT_DATATYPE *outCursor,
894  size_t numVox,
895  const K_DATATYPE *valTab,
896  const MLsoffset *indexTab,
897  size_t indexTabSize,
898  MLsoffset srcVoxelOffset,
899  MLdouble minVal,
900  MLdouble maxVal)
901  {
902  MLKernelToolsCorrelateLineWithKernelInterval(inCursor, outCursor, numVox, valTab, indexTab, indexTabSize, srcVoxelOffset, minVal, maxVal);
903  }
904 
906  template <typename IN_DATATYPE, typename OUT_DATATYPE, typename K_DATATYPE>
907  static void correlateLineWithImageAndKernelInterval(const IN_DATATYPE *inCursor,
908  OUT_DATATYPE *outCursor,
909  size_t numVox,
910  const K_DATATYPE *valTab,
911  const MLsoffset *indexTab,
912  size_t indexTabSize,
913  MLsoffset srcVoxelOffset,
914  MLdouble imgIntMinVal,
915  MLdouble imgIntMaxVal,
916  MLdouble kernIntMinVal,
917  MLdouble kernIntMaxVal)
918  {
919  MLKernelToolsCorrelateLineWithImageAndKernelInterval(inCursor, outCursor, numVox, valTab, indexTab, indexTabSize, srcVoxelOffset,
920  imgIntMinVal, imgIntMaxVal, kernIntMinVal, kernIntMaxVal);
921  }
922 
924  template <typename IN_DATATYPE, typename OUT_DATATYPE, typename K_DATATYPE>
925  static void correlateLineEvtWithIntervals(const IN_DATATYPE *inCursor,
926  OUT_DATATYPE *outCursor,
927  size_t numVox,
928  const K_DATATYPE *valTab,
929  const MLsoffset *indexTab,
930  size_t indexTabSize,
931  MLsoffset srcVoxelOffset,
932  MLdouble imgIntMinVal,
933  MLdouble imgIntMaxVal,
934  MLdouble kernIntMinVal,
935  MLdouble kernIntMaxVal,
936  bool useImgInt,
937  bool useKernInt)
938  {
939  MLKernelToolsCorrelateLineEvtWithIntervals(inCursor, outCursor, numVox, valTab, indexTab, indexTabSize, srcVoxelOffset,
940  imgIntMinVal, imgIntMaxVal, kernIntMinVal, kernIntMaxVal, useImgInt, useKernInt);
941  }
942 
944  template <typename DATATYPE>
945  static void applyFiltering(const ImageVector &inImgExt,
946  LineApplicator<DATATYPE> &lineApp,
947  BorderHandling borderHandling,
948  MLdouble fillValue,
951  {
952  MLKernelToolsApplyFiltering(inImgExt,lineApp, borderHandling, fillValue, outSubImg, inSubImg);
953  }
954 
956  template <typename DATATYPE>
957  static void applyFiltering(const ImageVector &inImgExt,
958  const fctLineFilter<DATATYPE> &lineFilter,
959  const ImageVector &negKernelExt,
960  const ImageVector &posKernelExt,
961  BorderHandling borderHandling,
962  MLdouble fillValue,
965  {
966  MLKernelToolsApplyFiltering(inImgExt, lineFilter, negKernelExt, posKernelExt, borderHandling, fillValue, outSubImg, inSubImg);
967  }
969 
970  }; // end of class KernelTools
971 
972 
973 
974  //-------------------------------------------------------------------------------------------
976  //-------------------------------------------------------------------------------------------
977 
978  //-------------------------------------------------------------------------------------------
993  //-------------------------------------------------------------------------------------------
994  template <typename DATATYPE>
995  static void MLKernelToolsApplyFiltering(const ImageVector &inImgExt,
996  LineApplicator<DATATYPE> &lineApp,
997  KernelTools::BorderHandling borderHandling,
998  MLdouble fillValue,
1001  {
1002  // Extract parameters for the internal \c _applyFiltering function from \c KernelLineApplicator object
1003  MLKernelToolsApplyFiltering(inImgExt,
1006  lineApp.getNegativeExtent(),
1007  lineApp.getPositiveExtent(),
1008  borderHandling,
1009  fillValue,
1010  outSubImg,
1011  inSubImg);
1012  }
1013 
1014  //-------------------------------------------------------------------------------------------
1024  //-------------------------------------------------------------------------------------------
1025  template <typename DATATYPE>
1026  static void MLKernelToolsApplyFiltering(const ImageVector &inImgExt,
1027  const fctLineFilter<DATATYPE> &lineFilter,
1028  const ImageVector &negKernelExt,
1029  const ImageVector &posKernelExt,
1030  KernelTools::BorderHandling borderHandling,
1031  MLdouble fillValue,
1032  TSubImageWithCursor<DATATYPE> &outSubImg,
1034  {
1035  // Fill border of subimages before calculating the correct area in output subimage.
1036  KernelTools::fillBorders(inImgExt, negKernelExt, posKernelExt, borderHandling, fillValue, outSubImg, inSubImg);
1037 
1038  // Calculate output image area to be calculated.
1039  SubImageBox area(KernelTools::calcAreaToBeCalculated(inImgExt, negKernelExt, posKernelExt, borderHandling));
1040 
1041  // Clamp region to be filled in output page, because e.g. in PAD_DST_FILL not the
1042  // entire output buffer needs to be calculated; the rest is filled.
1043  SubImageBox calcArea = outSubImg.getBox();
1044  calcArea = calcArea.intersect(area);
1045 
1046  // Print size and position of output page.
1047  ImageVector ov1 = calcArea.v1;
1048  ImageVector ov2 = calcArea.v2;
1049  ImageVector pOf = KernelTools::calcOutInCoordShift(borderHandling, negKernelExt);
1050 
1051 
1052  // Scan all voxels of the output page in u,t,c,z, y and x direction with a 'voxel cursor'.
1053  ImageVector p;
1054  ImageVector rowStart;
1055  MLint rowLength = ov2.x - ov1.x + 1;
1056  for (p.u=ov1.u; p.u<=ov2.u; p.u++){
1057  for (p.t=ov1.t; p.t<=ov2.t; p.t++){
1058  for (p.c=ov1.c; p.c<=ov2.c; p.c++){
1059  for (p.z=ov1.z; p.z<=ov2.z; p.z++){
1060  rowStart .set(0, 0, p.z, p.c, p.t, p.u);
1061  for (p.y=ov1.y; p.y<=ov2.y; p.y++){
1062  // Move cursors in input and output subimage to start of rows.
1063  // The input image cursor defines the current kernel placement.
1064  // The output image cursor defines the result voxel filtered from kernel and input image values.
1065  // Note that both cursors are placed in global image coordinates, and NOT in local page coordinates!
1066  rowStart .x = ov1.x;
1067  rowStart .y = p.y;
1068  outSubImg.setCursorImagePosition(rowStart);
1069  inSubImg .setCursorImagePosition(rowStart-pOf);
1070 
1071  // Apply the kernel to a line in the input image and write result into the
1072  // output image. Note that \c lineFilter is a function-like object whose
1073  // operator() (TSubImageWithCursor<DATATYPE> *, TSubImageWithCursor<DATATYPE> *, long) is called
1074  // when the object is used as function.
1075  lineFilter(&inSubImg, &outSubImg, static_cast<size_t>(rowLength));
1076  }
1077  }
1078  }
1079  }
1080  }
1081  }
1083 
1084 ML_END_NAMESPACE
1085 
1086 #endif // __mlKernelTools_H
1087 
1088 
1089 
@ T
Definition: SoKeyGrabber.h:71
Class collecting a set of templated an normal functions for filtering operations using kernels.
static void deleteIndexTab(MLsoffset *idxTab)
Function to delete an index table created with createIndexTab.
static void applyFiltering(const ImageVector &inImgExt, const fctLineFilter< DATATYPE > &lineFilter, const ImageVector &negKernelExt, const ImageVector &posKernelExt, BorderHandling borderHandling, MLdouble fillValue, TSubImageWithCursor< DATATYPE > &outSubImg, TSubImageWithCursor< DATATYPE > &inSubImg)
See MLKernelToolsApplyFiltering.
static void correlateLine(const IN_DATATYPE *inCursor, OUT_DATATYPE *outCursor, size_t numVox, const K_DATATYPE *valTab, const MLsoffset *indexTab, size_t indexTabSize)
See MLKernelToolsCorrelateLine.
static SubImageBox calcInSubImageBoxForOutSubImg(const SubImageBox &outSubImgBox, BorderHandling borderHandling, const ImageVector &negExt, const ImageVector &posExt, bool isSeparable=false, MLint numIterations=1)
Computes the size of the input page needed to calculate the page whose extents are given by outSubImg...
static void fillBorders(const ImageVector &inImgExt, const ImageVector &negKernelExt, const ImageVector &posKernelExt, KernelTools::BorderHandling borderHandling, MLdouble fillValue, SubImage &outSubImg, SubImage &inSubImg)
Fill the borders of the input or the output subimage (inSubImg or outSubImg) with the correct values ...
static SubImageBox calcAreaToBeCalculated(const ImageVector &inImgExt, const ImageVector &negFilterExt, const ImageVector &posFilterExt, BorderHandling borderHandling, bool isSeparable=false, MLint numIterations=1)
Calculate the area of the output to be calculated when the kernel the negative negKernelExt and the p...
static MLsoffset calcSrcVoxelOffset(const ImageVector &strides, const ImageVector &kernelNegExt)
Computes the offset index from voxel in output image to voxel in input image which can be returned as...
static MLsoffset * createIndexTab(const ImageVector &inSubImgStrides, const Kernel &kernel)
Create the table of offsets from the voxel (0,0,0,0,0,0) to the coordinates given by kernel....
static void expandForSeparableOrIterativeFiltering(SubImageBox &box, const ImageVector &negKernelExt, const ImageVector &posKernelExt, bool isSeparable, MLint numIterations)
Adds additional "borders around a box for separable or iterative filtering, for example around reques...
static void adaptWorldCoordinates(PagedImage &outImg, BorderHandling borderHandling, const ImageVector &negExt)
Convenience function to correct the world matrix of the image outImg when a kernel is applied to outI...
static void correlateLineEvtWithIntervals(const IN_DATATYPE *inCursor, OUT_DATATYPE *outCursor, size_t numVox, const K_DATATYPE *valTab, const MLsoffset *indexTab, size_t indexTabSize, MLsoffset srcVoxelOffset, MLdouble imgIntMinVal, MLdouble imgIntMaxVal, MLdouble kernIntMinVal, MLdouble kernIntMaxVal, bool useImgInt, bool useKernInt)
See MLKernelToolsCorrelateLineEvtWithIntervals.
static void correlateLineWithKernelInterval(const IN_DATATYPE *inCursor, OUT_DATATYPE *outCursor, size_t numVox, const K_DATATYPE *valTab, const MLsoffset *indexTab, size_t indexTabSize, MLsoffset srcVoxelOffset, MLdouble minVal, MLdouble maxVal)
See MLKernelToolsCorrelateLineWithKernelInterval.
static ImageVector calcOutImageExt(const ImageVector &imgExt, const ImageVector &kernelExt, BorderHandling borderHandling, MLint numIterations=1)
Calculate extents of output image for input image extents imgExt and kernel extents kernelExt if bord...
static void applyFiltering(const ImageVector &inImgExt, LineApplicator< DATATYPE > &lineApp, BorderHandling borderHandling, MLdouble fillValue, TSubImageWithCursor< DATATYPE > &outSubImg, TSubImageWithCursor< DATATYPE > &inSubImg)
See MLKernelToolsApplyFiltering.
BorderHandling
The border handling defines how an image is filtered at its borders if the kernel reaches undefined r...
static void correlateLineWithImageInterval(const IN_DATATYPE *inCursor, OUT_DATATYPE *outCursor, size_t numVox, const K_DATATYPE *valTab, const MLsoffset *indexTab, size_t indexTabSize, MLsoffset srcVoxelOffset, MLdouble minVal, MLdouble maxVal)
See MLKernelToolsCorrelateLineWithImageInterval.
static ImageVector calcOutInCoordShift(BorderHandling borderHandling, const ImageVector &negKernelExt)
For every voxel coordinate written into the output image there is a voxel coordinate in the input ima...
static void correlateLineWithImageAndKernelInterval(const IN_DATATYPE *inCursor, OUT_DATATYPE *outCursor, size_t numVox, const K_DATATYPE *valTab, const MLsoffset *indexTab, size_t indexTabSize, MLsoffset srcVoxelOffset, MLdouble imgIntMinVal, MLdouble imgIntMaxVal, MLdouble kernIntMinVal, MLdouble kernIntMaxVal)
See MLKernelToolsCorrelateLineWithImageAndKernelInterval.
static void copyLine(const IN_DATATYPE *inCursor, OUT_DATATYPE *outCursor, size_t numVox, MLsoffset srcVoxelOffset)
Wrapping of functions globally available in ML_NAMESPACE for backward compatibility.
The LineApplicator class provides pure virtual functions used by the old applyFiltering functions fro...
virtual ImageVector getNegativeExtent() const
Returns the negative extent of a kernel used for filtering.
virtual ImageVector getPositiveExtent() const
Returns the positive extent of a kernel used for filtering.
The class PagedImage, representing a fragmented image that manages properties and data of an image lo...
Definition: mlPagedImage.h:66
This class manages/represents a rectangular 6D image region that is organized linearly in memory.
Definition: mlSubImage.h:75
const SubImageBox & getBox() const
Returns the box describing the origin/extent of the subimage.
Definition: mlSubImage.h:230
void set(const ComponentType v=0)
Sets all components to v or - if v is not specified - to 0.
VectorType v1
Corner v1 of the subimage region (included in region).
Definition: mlSubImageBox.h:63
static TSubImageBox< intT > intersect(const TSubImageBox< intT > &box1, const TSubImageBox< intT > &box2)
Returns the overlapping region of subimage regions box1 and box2.
VectorType v2
Corner v2 of the subimage region (also included in region!).
Definition: mlSubImageBox.h:69
A class that offers a TSubImage with a TSubImageCursor.
Definition: mlTSubImage.h:990
void setCursorImagePosition(const ImageVector &position)
Sets the cursor to the given 6D position relative to the origin of the complete image region.
Definition: mlTSubImage.h:1034
ComponentType c
Color component of the vector.
Definition: mlImageVector.h:65
ComponentType t
Time component of the vector.
Definition: mlImageVector.h:67
ComponentType u
Unit/Modality/User component of the vector.
Definition: mlImageVector.h:69
ComponentType z
Z component of the vector.
Definition: mlImageVector.h:63
ComponentType x
X component of the vector.
Definition: mlImageVector.h:59
ComponentType y
Y component of the vector.
Definition: mlImageVector.h:61
bool MLValueIs0WOM(MLint8 a)
Returns true if value is 0; otherwise, it returns false.
#define MLKERNELEXPORT
Includes files used in many parts of the dll, defined dll-specific macros and controls any system dep...
MLint MLsoffset
Signed ML offset type that is a 32-bit signed integer on 32-bit platforms and a 64-bit integer on 64-...
Definition: mlTypeDefs.h:562
double MLdouble
Definition: mlTypeDefs.h:217
MLint64 MLint
A signed ML integer type with at least 64 bits used for index calculations on very large images even ...
Definition: mlTypeDefs.h:490
static void MLKernelToolsCorrelateLineWithImageAndKernelInterval(const IN_DATATYPE *inCursor, OUT_DATATYPE *outCursor, size_t numVox, const K_DATATYPE *valTab, const MLsoffset *indexTab, size_t indexTabSize, MLsoffset srcVoxelOffset, MLdouble imgIntMinVal, MLdouble imgIntMaxVal, MLdouble kernIntMinVal, MLdouble kernIntMaxVal)
Correlate all voxels of the a row pointed to by inCursor with the current kernel and write the result...
static bool isScalarValueInRange(const DATATYPE &v, bool normal, double minVal, double maxVal)
static void MLKernelToolsCorrelateLineEvtWithIntervals(const IN_DATATYPE *inCursor, OUT_DATATYPE *outCursor, size_t numVox, const K_DATATYPE *valTab, const MLsoffset *indexTab, size_t indexTabSize, MLsoffset srcVoxelOffset, MLdouble imgIntMinVal, MLdouble imgIntMaxVal, MLdouble kernIntMinVal, MLdouble kernIntMaxVal, bool useImgInt, bool useKernInt)
Correlate all voxels of the a row pointed to by inCursor with the current kernel and write the result...
static void MLKernelToolsCopyLine(const IN_DATATYPE *inCursor, OUT_DATATYPE *outCursor, size_t numVox, MLsoffset srcVoxelOffset)
Copy the line from input subimage which corresponds to the line to be modified in the output image.
static void MLKernelToolsApplyFiltering(const ImageVector &inImgExt, const fctLineFilter< DATATYPE > &lineFilter, const ImageVector &negKernelExt, const ImageVector &posKernelExt, KernelTools::BorderHandling borderHandling, MLdouble fillValue, TSubImageWithCursor< DATATYPE > &outSubImg, TSubImageWithCursor< DATATYPE > &inSubImg)
Compute the page outSubImg by filtering inSubImg with the passed function taking care of correct inte...
static void MLKernelToolsCorrelateLineWithKernelInterval(const IN_DATATYPE *inCursor, OUT_DATATYPE *outCursor, size_t numVox, const K_DATATYPE *valTab, const MLsoffset *indexTab, size_t indexTabSize, MLsoffset srcVoxelOffset, MLdouble minVal, MLdouble maxVal)
Correlate all voxels of the a row pointed to by inCursor with the current kernel and write the result...
static void MLKernelToolsCorrelateLineWithImageInterval(const IN_DATATYPE *inCursor, OUT_DATATYPE *outCursor, size_t numVox, const K_DATATYPE *valTab, const MLsoffset *indexTab, size_t indexTabSize, MLsoffset srcVoxelOffset, MLdouble minVal, MLdouble maxVal)
Correlate all voxels of the a row pointed to by inCursor with the current kernel and write the result...
static bool _isScalarValueInRange(const DATATYPE &, bool, double, double, OverloadSelector::OnFalse)
static void MLKernelToolsCorrelateLine(const IN_DATATYPE *inCursor, OUT_DATATYPE *outCursor, size_t numVox, const K_DATATYPE *valTab, const MLsoffset *indexTab, size_t indexTabSize)
Correlate all voxels of the a row pointed to by inCursor with the current kernel and write the result...
Helper types to switch between implementations of functions by overloading.
Definition: mlTypeTraits.h:332
void IntermediateType
Definition: mlTypeTraits.h:54
The basic implementation of a filter to filter an image row with kernel operations.
Definition: mlKernelTools.h:53
virtual ~fctLineFilter()
Virtual destructor to avoid warnings. Currently it does nothing.
Definition: mlKernelTools.h:62
Wrapper for the use of object bound row filters.
Definition: mlKernelTools.h:73
T * pOb
Pointer to store the pointer to the class type object passed to the explicit useObjectLineFilter as p...
Definition: mlKernelTools.h:78
~useObjectLineFilter() override
Virtual destructor to avoid warnings. Currently it does nothing.
Definition: mlKernelTools.h:94
useObjectLineFilter(T *po, void(T::*pf)(TSubImageWithCursor< DATATYPE > *, TSubImageWithCursor< DATATYPE > *, size_t))
Constructor.
Definition: mlKernelTools.h:90