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  // Add srcVoxelOffset to inCursor. So we don't need to do it again and again in the loop.
157  inCursor += srcVoxelOffset;
158  for (size_t i=0; i<numVox; ++i){
159  // Copy input voxel to output.
160  *outCursor = static_cast<OUT_DATATYPE>(*inCursor);
161 
162  // Move read and write cursor forward.
163  ++outCursor;
164  ++inCursor;
165  }
166  }
167 
168  //-------------------------------------------------------------------------------------------
179  //-------------------------------------------------------------------------------------------
180  template <typename IN_DATATYPE, typename OUT_DATATYPE, typename K_DATATYPE>
181  static void MLKernelToolsCorrelateLine(const IN_DATATYPE *inCursor,
182  OUT_DATATYPE *outCursor,
183  size_t numVox,
184  const K_DATATYPE *valTab,
185  const MLsoffset *indexTab,
186  size_t indexTabSize)
187  {
188  // Sum up the products of the kernel element values and the input image voxels which are
189  // found in the input page covered by kernel elements. Input image voxels are found
190  // by offsetting the pointer to the input image voxel with the indexes from indexTab.
191 
192  typedef typename TypeTraits<OUT_DATATYPE>::IntermediateType IntermediateType;
193 
194  // Apply kernel tab to all voxels in line.
195  for (size_t i=0; i < numVox; i++){
196 
197  // IntermediateType is double for scalar types and OUT_DATATYPE itself for all other types
198  IntermediateType retVal = ml_cast_from_scalar<IntermediateType>(0);
199  for (size_t c=0; c < indexTabSize; c++){
200  retVal += static_cast<IntermediateType>(inCursor[indexTab[c]]) *
201  ml_scalar_factor_cast<IntermediateType>(valTab[c]);
202  }
203 
204  // Write result into output image.
205  *outCursor = ml_cast_from_intermediate_type_without_clamping<OUT_DATATYPE>(retVal);
206 
207  // Move read and write cursor forward.
208  ++outCursor;
209  ++inCursor;
210  } // for
211  }
212 
213  //-------------------------------------------------------------------------------------------
228  //-------------------------------------------------------------------------------------------
229  template <typename IN_DATATYPE, typename OUT_DATATYPE, typename K_DATATYPE>
230  static void MLKernelToolsCorrelateLineWithImageInterval(const IN_DATATYPE *inCursor,
231  OUT_DATATYPE *outCursor,
232  size_t numVox,
233  const K_DATATYPE *valTab,
234  const MLsoffset *indexTab,
235  size_t indexTabSize,
236  MLsoffset srcVoxelOffset,
237  MLdouble minVal,
238  MLdouble maxVal)
239  {
240  // Test whether we have a normal interval or an exclusive one (i.e. min > max).
241  const bool normal = minVal <= maxVal;
242 
243  typedef typename TypeTraits<OUT_DATATYPE>::IntermediateType IntermediateType;
244 
245  // Apply kernel tab to all voxels in line.
246  for (size_t i=0; i < numVox; i++){
247  IN_DATATYPE srcVox = *(inCursor+srcVoxelOffset);
248 
249  // Test input image voxel. Is it in image interval?
250  if (! isScalarValueInRange(srcVox, normal, minVal, maxVal)){
251  // No, copy value from input.
252  *outCursor = static_cast<OUT_DATATYPE>(srcVox);
253  }
254  else{
255  // Sum up the products of the kernel element values and the input image voxels which are
256  // found in the input page covered by kernel elements. Input image voxels are found
257  // by offsetting the pointer to the input image voxel with the indexes from indexTab.
258 
259  // IntermediateType is double for scalar types and OUT_DATATYPE itself for all other types
260  IntermediateType retVal = ml_cast_from_scalar<IntermediateType>(0);
261  for (size_t c=0; c < indexTabSize; c++){
262  retVal += static_cast<IntermediateType>(inCursor[indexTab[c]]) *
263  ml_scalar_factor_cast<IntermediateType>(valTab[c]);
264  }
265 
266  // Write result into output image.
267  *outCursor = ml_cast_from_intermediate_type_without_clamping<OUT_DATATYPE>(retVal);
268 
269  } // else
270 
271  // Move read and write cursor forward.
272  ++outCursor;
273  ++inCursor;
274  } // for
275  }
276 
277 
278 
279 
280  //-------------------------------------------------------------------------------------------
298  //-------------------------------------------------------------------------------------------
299  template <typename IN_DATATYPE, typename OUT_DATATYPE, typename K_DATATYPE>
300  static void MLKernelToolsCorrelateLineWithKernelInterval(const IN_DATATYPE *inCursor,
301  OUT_DATATYPE *outCursor,
302  size_t numVox,
303  const K_DATATYPE *valTab,
304  const MLsoffset *indexTab,
305  size_t indexTabSize,
306  MLsoffset srcVoxelOffset,
307  MLdouble minVal,
308  MLdouble maxVal)
309  {
310  // Test whether we have a normal interval or an exclusive one (i.e. min > max).
311  const bool normal = minVal <= maxVal;
312 
313  typedef typename TypeTraits<OUT_DATATYPE>::IntermediateType IntermediateType;
314 
315  // Apply kernel tab to all voxels in line.
316  for (size_t i=0; i < numVox; i++){
317 
318  // Sums of weights for the kernel elements
319  MLdouble posValSum = 0; // that match the threshold criterion
320  MLdouble negValSum = 0; // that doesn't match the threshold criterion
321 
322  // IntermediateType is double for scalar types and OUT_DATATYPE itself for all other types
323  IntermediateType retVal = ml_cast_from_scalar<IntermediateType>(0);
324  for (size_t c=0; c < indexTabSize; c++){
325  IN_DATATYPE val = inCursor[indexTab[c]];
326 
327  // Get element from kernel table and multiply it with its corresponding input
328  // page voxel and add it to result value. Do this only if the voxel belongs
329  // to the kernel interval. Sum up the weights of valid and invalid voxels.
330  if (isScalarValueInRange(val, normal, minVal, maxVal)){
331  retVal += static_cast<IntermediateType>(val) *
332  ml_scalar_factor_cast<IntermediateType>(valTab[c]);
333  posValSum += valTab[c];
334  }
335  else {
336  negValSum += valTab[c];
337  }
338  }
339 
340  // If any value has been added to retVal then pretend as if all kernel voxels which did
341  // not match the kernel threshold interval hold the weighted average of those who did.
342  // Otherwise return value from input image which is under the replaced output image voxel.
343  if (MLValueIs0WOM(posValSum)) {
344  *outCursor = static_cast<OUT_DATATYPE>(inCursor[srcVoxelOffset]);
345  } else {
346  *outCursor = ml_cast_from_intermediate_type_without_clamping<OUT_DATATYPE>(retVal *
347  ml_scalar_factor_cast<IntermediateType>((posValSum + negValSum) / posValSum));
348  }
349 
350  // Move read and write cursor forward.
351  ++outCursor;
352  ++inCursor;
353  }
354  }
355 
356 
357 
358 
359  //-------------------------------------------------------------------------------------------
380  //-------------------------------------------------------------------------------------------
381  template <typename IN_DATATYPE, typename OUT_DATATYPE, typename K_DATATYPE>
382  static void MLKernelToolsCorrelateLineWithImageAndKernelInterval(const IN_DATATYPE *inCursor,
383  OUT_DATATYPE *outCursor,
384  size_t numVox,
385  const K_DATATYPE *valTab,
386  const MLsoffset *indexTab,
387  size_t indexTabSize,
388  MLsoffset srcVoxelOffset,
389  MLdouble imgIntMinVal,
390  MLdouble imgIntMaxVal,
391  MLdouble kernIntMinVal,
392  MLdouble kernIntMaxVal)
393  {
394  // Test whether we have a normal interval or an exclusive one (i.e. min > max).
395  const bool normalImgInt = imgIntMinVal <= imgIntMaxVal;
396  const bool normalKernInt = kernIntMinVal <= kernIntMaxVal;
397 
398  typedef typename TypeTraits<OUT_DATATYPE>::IntermediateType IntermediateType;
399 
400  // Scan all voxels in line.
401  for (size_t i=0; i < numVox; i++){
402 
403  // Get pointer to kernel origin in input data and the voxel corresponding to the changed voxel.
404  const IN_DATATYPE *voxPtr = inCursor;
405  IN_DATATYPE srcVox = *(voxPtr+srcVoxelOffset);
406 
407  // Test input image voxel. Is it in image interval?
408  if (! isScalarValueInRange(srcVox, normalImgInt, imgIntMinVal, imgIntMaxVal)){
409  // No, copy value from input.
410  *outCursor = static_cast<OUT_DATATYPE>(srcVox);
411  }
412  else{
413  // Yes, voxel needs to be filtered.
414 
415  // Sums of weights for the kernel elements
416  MLdouble posValSum = 0; // that match the threshold criterion
417  MLdouble negValSum = 0; // that do not match the threshold criterion
418 
419  // IntermediateType is double for scalar types and OUT_DATATYPE itself for all other types
420  IntermediateType retVal = ml_cast_from_scalar<IntermediateType>(0);
421  for (size_t c=0; c < indexTabSize; c++){
422  IN_DATATYPE val = inCursor[indexTab[c]];
423 
424  // Get element from kernel table and multiply it with its corresponding input
425  // page voxel and add it to result value. Do this only if the voxel belongs
426  // to the kernel interval. Sum up the weights of valid and invalid voxels.
427  if (isScalarValueInRange(val, normalKernInt, kernIntMinVal, kernIntMaxVal)){
428  retVal += static_cast<IntermediateType>(val) *
429  ml_scalar_factor_cast<IntermediateType>(valTab[c]);
430  posValSum += valTab[c];
431  }
432  else {
433  negValSum += valTab[c];
434  }
435  }
436 
437  // If any value has been added to retVal then pretend as if all kernel voxels which did
438  // not match the kernel threshold interval hold the weighted average of those who did.
439  // Otherwise return value from input image which is under the replaced output image voxel.
440  if (MLValueIs0WOM(posValSum)) {
441  *outCursor = static_cast<OUT_DATATYPE>(inCursor[srcVoxelOffset]);
442  } else {
443  *outCursor = ml_cast_from_intermediate_type_without_clamping<OUT_DATATYPE>(retVal *
444  ml_scalar_factor_cast<IntermediateType>((posValSum + negValSum) / posValSum));
445  }
446 
447  } // else
448 
449  // Move read and write cursor forward.
450  ++outCursor;
451  ++inCursor;
452  }
453  }
454 
455  //-------------------------------------------------------------------------------------------
466  //-------------------------------------------------------------------------------------------
467  template <typename IN_DATATYPE, typename OUT_DATATYPE, typename K_DATATYPE>
468  static void MLKernelToolsCorrelateLineEvtWithIntervals(const IN_DATATYPE *inCursor,
469  OUT_DATATYPE *outCursor,
470  size_t numVox,
471  const K_DATATYPE *valTab,
472  const MLsoffset *indexTab,
473  size_t indexTabSize,
474  MLsoffset srcVoxelOffset,
475  MLdouble imgIntMinVal,
476  MLdouble imgIntMaxVal,
477  MLdouble kernIntMinVal,
478  MLdouble kernIntMaxVal,
479  bool useImgInt,
480  bool useKernInt)
481  {
482  if (useImgInt && !useKernInt) {
483  // Image interval on but kernel interval off:
485  outCursor,
486  numVox,
487  valTab,
488  indexTab,
489  indexTabSize,
490  srcVoxelOffset,
491  imgIntMinVal,
492  imgIntMaxVal);
493  } else if (!useImgInt && useKernInt) {
494  // Image interval off but kernel interval on:
496  outCursor,
497  numVox,
498  valTab,
499  indexTab,
500  indexTabSize,
501  srcVoxelOffset,
502  kernIntMinVal,
503  kernIntMaxVal);
504  } else if (useImgInt && useKernInt) {
505  // Image interval and kernel interval on:
507  outCursor,
508  numVox,
509  valTab,
510  indexTab,
511  indexTabSize,
512  srcVoxelOffset,
513  imgIntMinVal,
514  imgIntMaxVal,
515  kernIntMinVal,
516  kernIntMaxVal);
517  } else {
518  // Convolute the line normally without using intervals.
520  outCursor,
521  numVox,
522  valTab,
523  indexTab,
524  indexTabSize);
525  }
526  } // correlateLineEvtWithIntervals
527 
529 
530 
531 
532  //---------------------------------------------------------------------------------------------
640  //---------------------------------------------------------------------------------------------
642  {
643  public:
644 
645 
646  //---------------------------------------------------------------------------------------------
649  //---------------------------------------------------------------------------------------------
650 
651  //-------------------------------------------------------------------------------------------
696  //-------------------------------------------------------------------------------------------
697  enum BorderHandling {NO_PAD = 0,
704 
705  NUM_BORDER_HANDLINGS};
706 
707  //-------------------------------------------------------------------------------------------
709  //-------------------------------------------------------------------------------------------
710  static const char* const BorderHandlingNames[];
712 
713 
714 
715 
716 
717  //-------------------------------------------------------------------------------------------
720  //-------------------------------------------------------------------------------------------
721 
729  static MLsoffset *createIndexTab(const ImageVector &inSubImgStrides, const Kernel &kernel);
730 
733  static void deleteIndexTab(MLsoffset *idxTab);
734 
740  static MLsoffset calcSrcVoxelOffset(const ImageVector &strides,
741  const ImageVector &kernelNegExt);
742 
747  const ImageVector &kernelExt,
748  BorderHandling borderHandling,
749  MLint numIterations=1);
750 
754  static void adaptWorldCoordinates(PagedImage &outImg,
755  BorderHandling borderHandling,
756  const ImageVector &negExt);
757 
767  const ImageVector &negKernelExt,
768  const ImageVector &posKernelExt,
769  bool isSeparable,
770  MLint numIterations);
771 
790  BorderHandling borderHandling,
791  const ImageVector &negExt,
792  const ImageVector &posExt,
793  bool isSeparable=false,
794  MLint numIterations=1);
795 
806  const ImageVector &negKernelExt);
807 
817  const ImageVector &negFilterExt,
818  const ImageVector &posFilterExt,
819  BorderHandling borderHandling,
820  bool isSeparable=false,
821  MLint numIterations=1);
822 
823 
833  static void fillBorders(const ImageVector &inImgExt,
834  const ImageVector &negKernelExt,
835  const ImageVector &posKernelExt,
836  KernelTools::BorderHandling borderHandling,
837  MLdouble fillValue,
838  SubImage &outSubImg,
839  SubImage &inSubImg);
840 
842 
843 
844 
845 
846  //-------------------------------------------------------------------------------------------
848  //-------------------------------------------------------------------------------------------
850  template <typename IN_DATATYPE, typename OUT_DATATYPE>
851  static void copyLine(const IN_DATATYPE *inCursor,
852  OUT_DATATYPE *outCursor,
853  size_t numVox,
854  MLsoffset srcVoxelOffset)
855  {
856  MLKernelToolsCopyLine(inCursor, outCursor, numVox, srcVoxelOffset);
857  }
858 
860  template <typename IN_DATATYPE, typename OUT_DATATYPE, typename K_DATATYPE>
861  static void correlateLine(const IN_DATATYPE *inCursor,
862  OUT_DATATYPE *outCursor,
863  size_t numVox,
864  const K_DATATYPE *valTab,
865  const MLsoffset *indexTab,
866  size_t indexTabSize)
867  {
868  MLKernelToolsCorrelateLine(inCursor, outCursor, numVox, valTab, indexTab, indexTabSize);
869  }
870 
872  template <typename IN_DATATYPE, typename OUT_DATATYPE, typename K_DATATYPE>
873  static void correlateLineWithImageInterval(const IN_DATATYPE *inCursor,
874  OUT_DATATYPE *outCursor,
875  size_t numVox,
876  const K_DATATYPE *valTab,
877  const MLsoffset *indexTab,
878  size_t indexTabSize,
879  MLsoffset srcVoxelOffset,
880  MLdouble minVal,
881  MLdouble maxVal)
882  {
883  MLKernelToolsCorrelateLineWithImageInterval(inCursor, outCursor, numVox, valTab, indexTab, indexTabSize, srcVoxelOffset, minVal, maxVal);
884  }
885 
887  template <typename IN_DATATYPE, typename OUT_DATATYPE, typename K_DATATYPE>
888  static void correlateLineWithKernelInterval(const IN_DATATYPE *inCursor,
889  OUT_DATATYPE *outCursor,
890  size_t numVox,
891  const K_DATATYPE *valTab,
892  const MLsoffset *indexTab,
893  size_t indexTabSize,
894  MLsoffset srcVoxelOffset,
895  MLdouble minVal,
896  MLdouble maxVal)
897  {
898  MLKernelToolsCorrelateLineWithKernelInterval(inCursor, outCursor, numVox, valTab, indexTab, indexTabSize, srcVoxelOffset, minVal, maxVal);
899  }
900 
902  template <typename IN_DATATYPE, typename OUT_DATATYPE, typename K_DATATYPE>
903  static void correlateLineWithImageAndKernelInterval(const IN_DATATYPE *inCursor,
904  OUT_DATATYPE *outCursor,
905  size_t numVox,
906  const K_DATATYPE *valTab,
907  const MLsoffset *indexTab,
908  size_t indexTabSize,
909  MLsoffset srcVoxelOffset,
910  MLdouble imgIntMinVal,
911  MLdouble imgIntMaxVal,
912  MLdouble kernIntMinVal,
913  MLdouble kernIntMaxVal)
914  {
915  MLKernelToolsCorrelateLineWithImageAndKernelInterval(inCursor, outCursor, numVox, valTab, indexTab, indexTabSize, srcVoxelOffset,
916  imgIntMinVal, imgIntMaxVal, kernIntMinVal, kernIntMaxVal);
917  }
918 
920  template <typename IN_DATATYPE, typename OUT_DATATYPE, typename K_DATATYPE>
921  static void correlateLineEvtWithIntervals(const IN_DATATYPE *inCursor,
922  OUT_DATATYPE *outCursor,
923  size_t numVox,
924  const K_DATATYPE *valTab,
925  const MLsoffset *indexTab,
926  size_t indexTabSize,
927  MLsoffset srcVoxelOffset,
928  MLdouble imgIntMinVal,
929  MLdouble imgIntMaxVal,
930  MLdouble kernIntMinVal,
931  MLdouble kernIntMaxVal,
932  bool useImgInt,
933  bool useKernInt)
934  {
935  MLKernelToolsCorrelateLineEvtWithIntervals(inCursor, outCursor, numVox, valTab, indexTab, indexTabSize, srcVoxelOffset,
936  imgIntMinVal, imgIntMaxVal, kernIntMinVal, kernIntMaxVal, useImgInt, useKernInt);
937  }
938 
940  template <typename DATATYPE>
941  static void applyFiltering(const ImageVector &inImgExt,
942  LineApplicator<DATATYPE> &lineApp,
943  BorderHandling borderHandling,
944  MLdouble fillValue,
947  {
948  MLKernelToolsApplyFiltering(inImgExt,lineApp, borderHandling, fillValue, outSubImg, inSubImg);
949  }
950 
952  template <typename DATATYPE>
953  static void applyFiltering(const ImageVector &inImgExt,
954  const fctLineFilter<DATATYPE> &lineFilter,
955  const ImageVector &negKernelExt,
956  const ImageVector &posKernelExt,
957  BorderHandling borderHandling,
958  MLdouble fillValue,
961  {
962  MLKernelToolsApplyFiltering(inImgExt, lineFilter, negKernelExt, posKernelExt, borderHandling, fillValue, outSubImg, inSubImg);
963  }
965 
966  }; // end of class KernelTools
967 
968 
969 
970  //-------------------------------------------------------------------------------------------
972  //-------------------------------------------------------------------------------------------
973 
974  //-------------------------------------------------------------------------------------------
989  //-------------------------------------------------------------------------------------------
990  template <typename DATATYPE>
991  static void MLKernelToolsApplyFiltering(const ImageVector &inImgExt,
992  LineApplicator<DATATYPE> &lineApp,
993  KernelTools::BorderHandling borderHandling,
994  MLdouble fillValue,
997  {
998  // Extract parameters for the internal \c _applyFiltering function from \c KernelLineApplicator object
1002  lineApp.getNegativeExtent(),
1003  lineApp.getPositiveExtent(),
1004  borderHandling,
1005  fillValue,
1006  outSubImg,
1007  inSubImg);
1008  }
1009 
1010  //-------------------------------------------------------------------------------------------
1020  //-------------------------------------------------------------------------------------------
1021  template <typename DATATYPE>
1022  static void MLKernelToolsApplyFiltering(const ImageVector &inImgExt,
1023  const fctLineFilter<DATATYPE> &lineFilter,
1024  const ImageVector &negKernelExt,
1025  const ImageVector &posKernelExt,
1026  KernelTools::BorderHandling borderHandling,
1027  MLdouble fillValue,
1028  TSubImageWithCursor<DATATYPE> &outSubImg,
1030  {
1031  // Fill border of subimages before calculating the correct area in output subimage.
1032  KernelTools::fillBorders(inImgExt, negKernelExt, posKernelExt, borderHandling, fillValue, outSubImg, inSubImg);
1033 
1034  // Calculate output image area to be calculated.
1035  SubImageBox area(KernelTools::calcAreaToBeCalculated(inImgExt, negKernelExt, posKernelExt, borderHandling));
1036 
1037  // Clamp region to be filled in output page, because e.g. in PAD_DST_FILL not the
1038  // entire output buffer needs to be calculated; the rest is filled.
1039  SubImageBox calcArea = outSubImg.getBox();
1040  calcArea = calcArea.intersect(area);
1041 
1042  // Print size and position of output page.
1043  ImageVector ov1 = calcArea.v1;
1044  ImageVector ov2 = calcArea.v2;
1045  ImageVector pOf = KernelTools::calcOutInCoordShift(borderHandling, negKernelExt);
1046 
1047 
1048  // Scan all voxels of the output page in u,t,c,z, y and x direction with a 'voxel cursor'.
1049  ImageVector p;
1050  ImageVector rowStart;
1051  MLint rowLength = ov2.x - ov1.x + 1;
1052  for (p.u=ov1.u; p.u<=ov2.u; p.u++){
1053  for (p.t=ov1.t; p.t<=ov2.t; p.t++){
1054  for (p.c=ov1.c; p.c<=ov2.c; p.c++){
1055  for (p.z=ov1.z; p.z<=ov2.z; p.z++){
1056  rowStart .set(0, 0, p.z, p.c, p.t, p.u);
1057  for (p.y=ov1.y; p.y<=ov2.y; p.y++){
1058  // Move cursors in input and output subimage to start of rows.
1059  // The input image cursor defines the current kernel placement.
1060  // The output image cursor defines the result voxel filtered from kernel and input image values.
1061  // Note that both cursors are placed in global image coordinates, and NOT in local page coordinates!
1062  rowStart .x = ov1.x;
1063  rowStart .y = p.y;
1064  outSubImg.setCursorImagePosition(rowStart);
1065  inSubImg .setCursorImagePosition(rowStart-pOf);
1066 
1067  // Apply the kernel to a line in the input image and write result into the
1068  // output image. Note that \c lineFilter is a function-like object whose
1069  // operator() (TSubImageWithCursor<DATATYPE> *, TSubImageWithCursor<DATATYPE> *, long) is called
1070  // when the object is used as function.
1071  lineFilter(&inSubImg, &outSubImg, static_cast<size_t>(rowLength));
1072  }
1073  }
1074  }
1075  }
1076  }
1077  }
1079 
1080 ML_END_NAMESPACE
1081 
1082 #endif // __mlKernelTools_H
1083 
1084 
1085 
@ 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.
Class which represents an image, which manages properties of an image and image data which is located...
Definition: mlPagedImage.h:70
This class manages/represents a rectangular 6d image region which 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:1277
void setCursorImagePosition(const ImageVector &position)
Sets cursor to the given 6d position relative to the origin of the complete image region.
Definition: mlTSubImage.h:1321
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 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 which is a 32 bit signed integer on 32 bit platforms and a 64 bit integer on 64...
Definition: mlTypeDefs.h:650
double MLdouble
Definition: mlTypeDefs.h:223
MLint64 MLint
A signed ML integer type with at least 64 bits used for index calculations on very large images even ...
Definition: mlTypeDefs.h:578
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:53
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