![]() |
ImFusion SDK 4.3
|
On-the-fly pixel masking of images. More...
On-the-fly pixel masking of images.
Every SharedImage can hold an optional Mask defining which pixels should be ignored in algorithms supporting this concept. Therefore, the interface provides methods to check whether a certain pixel is "inside" the mask (meaning that it should be considered) or not. The decision whether a pixel is inside can be performed based on the pixel coordinate and/or the pixel value. The actual logic for the mask depends on the concrete implementation of the interface and subclasses are free to only use one of the two inputs if sufficient. For example, the IntensityMask masks out pixels depending on their actual value. The ExplicitMask on the other hand only uses the pixel coordinate to determine if the pixel is inside or not.
A mask value of 0 means the corresponding pixel is outside the mask, i.e. to be ignored. A value greater than 0 means it is inside, i.e. to be considered. Most mask will only return binary values of 0 and 1 but implementations are free to return any other uint8_t
value as well.
The Mask in SharedImage can be safely shared between several SharedImages.
In general, algorithms that want to support the mask feature should only use the abstract Mask interface. In rare cases (such as for optimisation) it can be useful to use a subclass directly. This way new mask types can be added without the need of adopting any existing algorithm. A typical use case for a mask would be to only process pixel that are inside the mask:
The image masking API also provides a GlMask variant that offers a generic way to use polymorphic masks in GLSL. In most cases GlMask can be used as any other GL::AbstractInclude. The following examples uses the GlMask to draw all pixels outside the mask in red:
GLSL:
C++:
It is also possible to include several different masks in the same GLSL shader. However, this is not possible in the same manner as in the example above because multiple AbstractIncludes would collide. For such cases, it also implements the GL::MultiIncludable interface. This provides you with the createMultiInclude() helper function to create variants with individual and unique prefixes for all of its GLSL uniforms and functions to avoid collisions of multiple GlMasks in the same shader.
The following example computes the difference of two images but only for pixels that are contained in both masks. The mask of the first image is bound to the prefix mask1
, and the one of the second image to mask2
.
GLSL:
C++:
Each multi-mask instantiated through GlMask::createMultiInclude() is bound to the original mask instance and therefore only valid as long as that one exists.
In order to create a new Mask subclass, implement the maskValue method. If the implementation does not require the pixel value (second argument), you should also override the requiresPixelValue method and return false
.
Additionally the isCompatible method has to be implemented. It should return true
if the mask can also be used for the given image or false
otherwise. Because maskValue takes pixel coordinates and not world coordinates, some masks, for example the ExplicitMask, only work on images of the same extent. Other masks like the IntensityMask, are independent of the coordinate and but depend on the actual image type.
Not all mask have to support multichannel images directly. It is up to the implementation how to process the vec4
input. An implementation could, for example, only use the first channel independent of the actual number of channels or it could mask individual color channels. In the later case, this should also be reflected by the isCompatible method (e.g. a mask for a color image probably behaves different on a grayscale image is therefor incompatible).
While it is not mandatory, it is recommended to also implement a GlMask that provides a GLSL interface to the mask. Before implementing the GlMask interface, make yourself familiar with the GL::AbstractInclude concept. The define name for the GlMask is set to IMAGE_MASK
so it is only required to implement a shader that provides the following method:
For more details on how to write a correct subclass, check the GlMask documentation.
Classes | |
class | Mask |
Base interface for implementing polymorphic image masks on the CPU. More... | |
class | CroppingMask |
Simple axis-aligned cropping mask with optional roundness. More... | |
class | ExplicitIntensityMask |
An ExplicitIntensityMask is a combination of an ExplicitMask and an IntensityMask. More... | |
class | ExplicitMask |
An ExplicitMask holds an individual mask value for every pixel. More... | |
class | GlMask |
Base interface for implementing polymorphic image masks using OpenGL. More... | |
class | IntensityMask |
Masks pixels with a specific value or values outside a specific range. More... | |
class | SkippingMask |
Basic mask where only every N-th pixel is considered inside. More... | |
class | FanMask |
Mask for images, that shows only those pixels which are inside the configured FrameGeometry. More... | |