Chapter 4. Implementing Kernel-Based Algorithms

Table of Contents

4.1. General Approach
4.2. Border Handling in Kernel Operations
4.3. Kernel Classes
4.3.1. KernelBaseModule
4.3.2. KernelModule
4.3.3. Kernel
4.4. KernelTools
4.5. Kernel Example for Page-Based Image Filtering
4.6. Traps and Pitfalls in Kernel Programming

Many image filters are based on the so-called kernel-based image filtering. The following section will explain how to implement such filters efficiently.

Main sections are

4.1. General Approach

When a fixed region around a voxel is needed to calculate output voxels (edge detector operations, morphological operations, noise filters, smoothing, texture filters, ...) we talk about a kernel-based filter.

Examples are the modules KernelExample, Convolution, RankFilter, Morphology.

Figure 4.1. Kernel-Based: Used Page Extent

Kernel-Based: Used Page Extent

Figure 4.2. Kernel-Based: Applying the Algorithm

Kernel-Based: Applying the Algorithm

Advantages:

  • Fast access to kernel range in 6D is possible with paging -> 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)

For a kernel-based image processing approach, some measures must be taken:

  • Adjust the extent of output image in Module::calculateOutputImageProperties()

  • Calculate the extent of input pages in Module::calculateInputSubImageBox()

  • Apply border handling in Module::calculateOutputSubImage()

  • Apply kernel to page in Module::calculateOutputSubImage()

These measures include many complex steps which are supported by the following classes:

  • KernelBaseModule

    This is a class for page-based kernel operations. Fields for the border handling mode and fill value are automatically created. Macros are available for simple implementation and usage of the kernel algorithm template.

  • KernelModule

    Defines a convenience class for kernel base image filtering. Many convenience methods are available to configure the module with certain field combinations so that derived modules do not have to implement most inputs like kernel extent, fill value, kernel input and output connectors, image and kernel intervals, etc.

  • Kernel

    Manages a kernel matrix with value access, creation, manipulation and (de)coding as a string as well as value copy and assignment, etc.

    The class Kernel manages a 6D kernel which can be applied to images. It handles a set of coordinates (see Kernel::getCoordTab()) and values for those coordinates (see getValueTab()). This permits the specification of kernels with gaps or only a very few defined elements. Thus big kernels with only a few elements can be manipulated and applied fast. A set of operations is available on a kernel instance which includes arithmetics on the kernel values, gauss presets, normalization, different kernel set/get routines to create/save partially defined kernels, get/set methods to load/save kernels as strings or arrays, and much more.

    This Kernel class is implemented as a template dependent on KDATATYPE to have different precisions for kernel elements. Usually, the kernel is instantiated with MLdouble as KDATATYPE. This type is also given as typedef KernelDataType which should be used e.g., when pointers to the table of kernel elements are needed. This class can be instantiated with MLfloat or MLldouble as KDATATYPE; however, the Kernel base classes always use KernelDataType.

    Note that using integer types for the kernels is not really useful since pure integer kernel operations are rare and some operations would suffer because rounding errors occur.