Image convolution in libprofit happens optionally as part of a Model evaluation. Internally, the Model uses a Convolver to perform convolution.

Supported convolution methods

Convolvers are objects that carry out convolution (via their Convolver::convolve() method). Depending on the size of the problem, and on the libraries available on the system, different convolver types will be available to be used:

  • BRUTE_OLD is the simplest convolver. It implements a simple, brute-force 2D convolution algorithm.
  • BRUTE is a brute-force convolver that performs better that BRUTE_OLD, but still implements simple, brute-force 2D convolution. It is the default convolver used by a Model that hasn’t been assigned one, but requires one.
  • FFT is a convolver that uses Fast Fourier transformations to perform convolution. Its complexity is lower than the BRUTE, but its creation can be more expensive.
  • OPENCL is a brute-force convolver implemented in OpenCL. It offers both single and double floating-point precision and its performance is usually better that that of the BRUTE.

Creating a Convolver

Instead of manually selecting the class that should be used, users create Convolver instances via the create_convolver() function. create_convolver() lets the user specify which type of convolver should be created (either using an enumeration, or a standard string value), and a set of creation preferences that apply differently to different types of Convolvers.

If a Model needs to perform convolution and a Convolver has been set on its Model::convolver member then that convolver is used. If no convolver has been set, it creates a new BRUTE and uses that to perform the convolution.

Using a convolver

Once created, users can call the Convolver::convolve() method directly on the resulting convolver, (or assign it to a Model instance for it to use it). The Convolver::convolve() methods needs at least three parameters: an image, a kernel and a mask. Convolvers will convolve the image with the kernel only for the pixels in which the mask is set, or for all pixels if an empty mask is passed. This implies that the mask, if not empty, must have the same dimensions that the image.

Image cropping

Some convolvers internally work with images that are larger than the original source image (mostly due to efficiency reasons). After this internal image expansion occurs, and the convolution takes place, the resulting image is usually cropped at the corresponding point to match original source image size and positioning before being returned to the user.

However, users might want to pick into this internal, non-cropped result of the convolution process. To do this, an additional crop parameter in the Convolver::convolve() method determines whether the convolver should return the original, and potentially bigger, image. When a non-cropped image is returned, an additional offset_out parameter can be given to find out the offset at which cropping would have started. The cropping dimensions do not need to be queried, as they always are the same of the original source image given to the convolver.

Model convolution

During model evaluation (i.e., a call to Model::evaluate()) users might want to be able to retrieve the non-cropped result of the internal convolution that takes place during model evaluation (as explained in Image cropping).

To do this, users must first call Model::set_crop() with a false argument. When calling Model::evaluate(), users must then also give a Point argument to retrieve the offset at which cropping should be done to remove the image padding added by the convolution process.