HDK
|
A pixel filter is a variation of a regular filter, but with one major restriction. The output pixel must depend only on the corresponding input pixel's value - no neighboring pixels may be used, nor pixels from other planes or frames.
This restriction allows pixel filters to be highly optimized, as a string of pixel filters in a network can be collapsed into one operation.
This example adds a constant vector value to all pixels in the image.
This defines the tab switcher for a pixel filter operation. It creates the Mask and Frame Scope tabs.
This next portion creates the parameters (one), local variables (none) and the input labels for the node.
Pixel operations derive from COP2_PixelOp, which in turn derives from COP2_MaskOp (masking), COP2_PixelBase (plane/frame scoping) and COP2_Node.
COP2_PixelOp does all the cooking work and provides a few parameters to control where to quantize and if the operation should be done in unpremultiplied space. Its parent class, COP2_MaskOp, allows the operation to be masked by another image wired to the mask input. This class derives from COP2_PixelBase, which provides plane and frame scoping of the operation.
The operation itself is defined by class derived from RU_PixelFunction, in this case, a simple vector add:
The next virtual method describes how your pixel function behaves. If the operation does the exact same operation on all components, such as inverting the pixel, then eachComponentDifferent() can return false. In this case, we are adding a vector to the pixel, so the operation does differ per component.
Pixel functions can be defined as scalar or vector operations. A vector operation requires all components at once, whereas in a scalar operation, they can be processed independently. In this example, adding a vector to our pixel does not require the other components as input values (though if we were taking the luminance of the pixel, we would).
This is the actual pixel function itself. There is a function definition, add, which must be the same as the function signature here, and a virtual getPixelFunction() method which returns a pointer to our pixel function.
If instead we were doing a vector pixel function (like luminance), the vector function would need to be defined along with an override of getVectorFunction() to return our vector function. Not all components of the input vector may be present (if it's a scalar or vector3), and not all components may have been scoped by the user. If scope[] is false for any of the components, you can read from the component, but you cannot write to it.
Finally, the pixel function class contains any data necessary to perform the operation. In this case, it's just the vector we want to add.
Back to COP2_PixelAdd now, the main method in a pixel operation COP is the addPixelFunction() method. The method must be overridden to return an instance of your pixel function.
This method defines the vector that is added to the input image, and creates a new pixel function with these values. The effect variable is defined by the parameters in the Frame Scope tab, and it is normally 1. If it isn't 1, we lessen (or increase) the effect of the addend vector by multiplying it by the effect.
Optionally, getOperationInfo() can be overridden to provide a short description of what your operator is doing in operator info popup.
Finally, the pixel operation needs to be registered like any other COP. The number of inputs is 1-2 - one required plus an optional mask input.