4.2. Page-Based Approaches

4.2.1. Page-Based Concept

Used if voxel coordinates are not necessary and voxel operations are local. (LUT, windowing, some color model changes, thresholding, inversion, arithmetics on voxel data, etc.).

Figure 4.1. Page-Based Concept

Page-Based Concept

Advantages:

  • Fast image data access by pointer incrementation

  • Short implementation

Disadvantages:

  • Voxel coordinates are not directly available

  • Neighbour voxels are only available with precautions

  • Not very useful for complicated algorithms

  • Precautions necessary because pages could reach outside the image, i.e., voxels outside the image might be processed.

Example 4.1. Implementing a Page-Based Algorithm

template <typename DATATYPE>
void AddExample::calculateOutputSubImage(TSubImage<DATATYPE> *outSubImg,
                                 int              /*outIndex*/,
                                 TSubImage<DATATYPE> *inSubImg1,
                                 TSubImage<DATATYPE> *inSubImg2)
{
  // Get pointers to memory buffers of input and output subimage.
  DATATYPE* outSubImgVP_beg = outSubImg->getImagePointer(outSubImg->getBox().v1);
  DATATYPE* outSubImgVP_end = outSubImg->getImagePointer(outSubImg->getBox().v2);
  DATATYPE* inSubImg1VP     = inSubImg1->getImagePointer(inSubImg1->getBox().v1);
  DATATYPE* inSubImg2VP     = inSubImg2->getImagePointer(inSubImg2->getBox().v1);

  // Loop over all voxels in memory buffers even if pages reache outside the image.
  for (DATATYPE* outSubImgVP = outSubImgVP_beg;
       outSubImgVP <= outSubImgVP_end;
       outSubImgVP++, inSubImg1VP++, inSubImg2VP++)
  {
    (*outSubImgVP) = (*inSubImg1VP)  + (*inSubImg2VP);
  }
}

4.2.2. Voxel-Based Concept

Useful for all pixel-based algorithms already mentioned in Section 4.2.1, “Page-Based Concept” (LUT, windowing, some color model changes, thresholding, inversion, arithmetics) or if voxel coordinates are essential and operations are local (rasterization of implicit Objects, SubImage, etc.), e.g. mlAddExampleOp.

Figure 4.2. Voxel-Based Concept

Voxel-Based Concept

Advantages:

  • Fast access by 6 nested loops and pointer incrementation in inner loop

  • Voxel coordinates are available

  • Conceptually good implementation, recommended for page processing

Disadvantages:

  • Neighbor voxels only available with precautions

  • Not very useful for advanced algorithms

Example 4.2. Implementing a Voxel-Based Algorithm

template <typename DATATYPE>
  void PosExample::calculateOutputSubImage(TSubImage<DATATYPE> *outSubImg, int outIndex,
                                   TSubImage<DATATYPE> *inSubImg)
{
  // Get extent of output image and clamp the extent of the box of outSubImg
  // against
  // it to be sure that no voxels outside the image are processed.

  SubImageBox box    = outSubImg->getValidRegion();

  // Iterate over all valid voxels of inSubImg and outSubImg.
  ImageVector p = box.v1;
  for (p.u = box.v1.u;  p.u <= box.v2.u;  ++p.u) {
    for (p.t = box.v1.t;  p.t <= box.v2.t;  ++p.t) {
      for (p.c = box.v1.c;  p.c <= box.v2.c;  ++p.c) {
        for (p.z = box.v1.z;  p.z <= box.v2.z;  ++p.z) {
          for (p.y = box.v1.y;  p.y <= box.v2.y;  ++p.y) {

            // Get/Set position of row starts as pointers to memory
            // positions in inSubImg and outSubImg buffers.

            p.x = box.v1.x;
            DATATYPE* iP = inSubImg ->getImagePointer(p);
            DATATYPE* oP = outSubImg->getImagePointer(p);

            // Process all voxels in row with pointers. Be sure to
            // include last voxel in row with "<= box.v2.x", because
            // v2 is still part of box region.

            for (;  p.x <= box.v2.x;  ++p.x)
            {
              *oP = calcFromIp(p.x, *iP); // Calculate voxel from position & input
              ++iP; ++oP;                 // Move input and output pointer forward
            }
          }
        }
      }
    }
  }
}

See Section 3.1.9, “Implementing calculateOutputSubImage()”, Section 7.2.3, “Examples with Registered Voxel Types” and programming examples released with MeVisLab for further examples.


4.2.3. Slice-Based Concept

Useful for arbitrary 2D algorithms. The page extent is set to slice extent, or for calculations of an output page, the entire input slice is requested in calculateInputSubImageBox().

Figure 4.3. Slice-Based Concept

Slice-Based Concept

Advantages:

  • Very fast random access (with getValue/setValue or like page-based or voxel-based concept)

  • Easy to implement

  • Paging still works fine if x and y extents are not too large

Disadvantages:

  • PageExt == SliceExt: can easily degenerate and become very expensive (e.g., on large mammograms or satellite images), also page extent is propagated to appended images

  • InputTile == SliceExt, output page is normal: many slice requests become necessary to compose the output slice

Consider whether e.g., the VirtualVolume or a kernel-based concept could replace this concept to avoid these disadvantages.

Example 4.3. Implementing a Slice-Based Algorithm

void SliceFilter::calculateOutputImageProperties(int /*outIndex*/, PagedImage* outImage)
{
  // Set extent of pages in z, c, t and u dimension to 1.
  // Thus only axial slices will be calculated by the module.
  // Avoid too small pages.

  ImageVector pExt = getInputImage(0)->getPageExtent();
  if (pExt.x < 64){ pExt.x = 64; }
  if (pExt.y < 64){ pExt.y = 64; }
  outImage->setPageExtent(ImageVector(pExt.x, pExt.y, 1,1,1,1));
}

SubImageBox SliceFilter::calculateInputSubImageBox(int /*inIndex*/,
                                         const SubImageBox& outSubImgBox,
                                         int /*outIndex*/)
{
  // Request slice with image x/y extent. All other
  // parameters are given by the page extent.

  SubImageBox inBox = outSubImgBox;
  inBox.v1.x = 0;
  inBox.v1.y = 0;
  inBox.v2.x = getInputImage(0)->getImageExtent().x-1;
  inBox.v2.y = getInputImage(0)->getImageExtent().y-1;
  return inBox;
}


4.2.4. Kernel-Based Concept

An important class of image filters is based on the so-called kernel-based image filtering. This class is used when a fixed region around a voxel is needed to calculate output voxel (edge detector operations, morphological operations, noise filters, smoothing, texture filters, etc.).

Advantages:

  • Fast access to kernel range in 6D is possible with paging so it fits well into page concept

  • Many algorithm categories can be implemented

Disadvantages:

  • Base class is a bit more complex

  • Image borders require consideration (supported by base classes, though)

See Kernel Progamming for more information.