Convolution
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_OLDis the simplest convolver. It implements a simple, brute-force 2D convolution algorithm.BRUTEis a brute-force convolver that performs better thatBRUTE_OLD, but still implements simple, brute-force 2D convolution. It is the default convolver used by aModelthat hasn’t been assigned one, but requires one.FFTis a convolver that uses Fast Fourier transformations to perform convolution. Its complexity is lower than theBRUTE, but its creation can be more expensive.OPENCLis 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 theBRUTE.
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.