Tutorial Posterize

In this tutorial, you will learn how to create a reusable custom filter node that iterates multiple times over an image to posterize it. This tutorial teaches you how to use the Attributes node to define the attributes of the custom node, how to define the inputs and outputs of the custom node with the Image IO, and how to evaluate an image multiple using the iterations attribute of the Node Graph node.

This tutorial assumes that you read the basic tutorials.

Sample Project

  1. Download the tutorial files posterize.zip and extract them in your PC.

  2. Open the project [Posterize5Levels.pxf] project.

    Start Node Graph

  3. Activate the Reader girl_blue node. This node reads the image from disk.

    Start Girl Blue by Daniel Sampaio Neto - pixabay

  4. Activate the To M node. This node converts the image to monochromatic color mode.

    Start Girl Mono

  5. Activate the Blur node. This node smooths the image.

    Start Girl Blur

  6. Activate the first Threshold node. This node converts the pixels with vales within [0.0 - 0.2] to white (1.0) and all other pixels to black (0.0).

    Start Girl 0.0 0.2

  7. The other 4 Threshold nodes convert the pixels with ranges [0.2 - 0.4], [0.4 - 0.6], [0.6 - 0.8] and [0.8 - 1.0].

  8. Activate the first Value Multiply node. This node multiplies all pixels by 0.1.

    Start Girl 0.1

  9. The other 4 Value Multiply nodes multiplies the other images by 0.3, 0.5, 0.7 and 0.9.

    Start Girl 0.0 0.2 Start Girl 0.1

    Start Girl 0.2 0.4 Start Girl 0.3

    Start Girl 0.4 0.6 Start Girl 0.5

    Start Girl 0.6 0.8 Start Girl 0.7

    Start Girl 0.8 1.0 Start Girl 0.9

  10. Finally, the Value Add node adds the values of all the images and composes the final image.

    Start Girl Posterize

If you need to posterize an image, you can open this project and change the path of the bitmap in the Reader node.

If you need to reuse this filter in other projects, you can add an Image IO node connected between the output of the Reader node and the input of the To M node, and a second Image IO node connected to the output of the Value Add node. This will define the input and output of the custom node. However, this will limit the effect of this Posterize custom node to only 5 levels defined by the 5 Threshold-Value Multiply nodes.

To create a custom node with a levels attribute that controls the numbers of leves we'll need to iterate through the image as many times as the number of levels.

Posterize

To create the posterize custom filter node we'll need two projects, one that converts the image to mono and smooths it and a second one that takes the smooth image, finds the pixels within the range defined by the current iteration and the number of iterations and

where the number of levels is an attribute we'll need to run a loop that extracts the pixels within a range and multiplies them by the average value of the range, and that adds the level to the final image.

Posterize Loop Body Project

The Posterize Loop Body will be a PixaFlux project that takes as input a smooth monochromatic image, finds the pixels within the range defined by the current iteration and the number of iterations, multiplies these pixels by the average value of the range, and adds the pixel values to the image that will be returned by the project.

Before the Loop Body

The Loop Body project doesn't need any images to work, but we'll need a monochromatic smooth image to test our loop body.

  1. Start a new empty project. File > New Project > Empty.

  2. Create a Reader node Generate Arrow Reader. [?] Load the girl_blue.png image using the Path button.

  3. Create a To M node Convert Arrow To M icon. Connect [Reader › image] to [image › To M]. [?]

  4. Create a Blur node Filter Arrow Blur. Connect [To M › image] to [image › Blur]. Set the radiusx and radiusy attributes to 10.0.

  5. Create an Image IO node Project Arrow Image IO. Connect [Blur › image] to [image › Image IO]. This node will define the input of the custom loop body project.

    Loop Smooth

    Start Girl Blur

    All the nodes connected to the input of the Image IO node (Reader - To M - Blur) will be ignored by the Node Graph node.

Loop Body Math

Now you'll add the Math nodes that compute the values for the Threshold and Value Multiply nodes.

  1. Create a Loop Iterations node Project Arrow Loop Iterations. This node will receive the current iteration and the number of iterations values from the Node Graph node when this project is used as a custom node.

    The iterations number value is a number equal or greater than 1, and the iteration value is a number between 1 and iterations.

    You'll need to add a few math nodes to obtain the ranges and average values from iteration and iterations.

    We'll use this formulas:

    Loop Math (Smath Studio: Free mathematical program with WYSIWYG editor).

    Add the low = (iteration - 1) / iterations nodes.

  2. Create a Number Subtract node Math Arrow Number Subtract.
    Connect [Loop Iterations › iteration] to [minuend › Number Subtract]. Set the subtrahend attribute to 1.0. This node subtracts 1.0 from the iteration value.

  3. Create a Number Divide node Math Arrow Number Divide. Connect [Number Subtract › result] to [dividend › Number Divide]. Connect [Loop Iterations › iterations] to [divisor › Number Divide]. Rename the Divide node Low.

  4. Create a Number Divide node Math Arrow Number Divide. Connect [Loop Iterations › iteration] to [dividend › Number Divide]. Connect [Loop Iterations › iterations] to [divisor › Number Divide]. Rename the Divide node High.

    Add the mid = (low + high) / 2.0 nodes.

  5. Create a Number Add node Math Arrow Number Add. Connect [Low › result] to [numbera › Number Add]. Connect [High › result] to [numberb › Number Add].

  6. Create a Number Divide node Math Arrow Number Divide. Connect [Number Add › result] to [dividend › Number Divide]. Set the attribute divisor to 2.0. Rename the Divide node Mid.

    To test the math you can edit the iteration and iterations attributes in the Loop Iterations node and hover over the outputs of the Number Subtract and Number Divide nodes, a tooltip will be displayed with the output name, type and value if numeric.

    Loop Math Node Graph

    These are the values you should read:

    |Iterations|Iteration|Low|High|Mid| |--------------|-------------|---|----|---| | 5 | 1 |0.0|0.2 |0.1| | 5 | 2 |0.2|0.4 |0.3| | 5 | 3 |0.4|0.6 |0.5| | 5 | 4 |0.6|0.8 |0.7| | 5 | 5 |0.8|1.0 |0.9|

Loop Body Image

Now you'll add the Threshold and Value Multiply nodes that will create the level image return on the current loop iteration.

  1. Create a Threshold node Adjust Arrow Threshold. Connect [Image IO › image] to [image › Threshold].

  2. Expose the attributes maximum and minimum in the Threshold node. In the Attributes Panel right click the label of the attribute and check the Expose As Input option in the manu.

  3. Connect [Low › result] to [minimun › Threshold].

  4. Connect [High › result] to [maximum › Threshold].

    Start Girl 0.4 0.6 Threshold image at iterations = 5 and iteration = 3

  5. Create a Value Multiply node Filter Arrow Blur. Connect [Threshold › image] to [image › Value Multiply].

  6. Expose the attribute value in the Value Multiply node.

  7. Connect [Mid › result] to [value › Value Multiply].

    Start Girl 0.4 0.6 Value Multiply image at iterations = 5 and iteration = 3

  8. Create an Image IO node Project Arrow Image IO. Connect [Value Multiply › image] to [image › Image IO].

    The Loop Action attribute defines how the Node Graph node handles the images returned by this node. We need that all images get added together.

  9. Set the Loop Action attribute to addition.

    This last Image IO node defines the output of this Custom Node when used in a Node Graph node.

    Loop Threshold Nodes

  10. Save this project as Posterize_Loop.pxf. This is the project that will be loaded by the Posterize main custom node.

Posterize Main Project

We'll now create the Posterize main project. This project that takes an image as input, converts it to monochromatic color, smooths it with a Blur filter and then excutes the posterize custom node in a loop. The number of iterations of the loop is defined by a levels attribute.

  1. Start a new empty project. File > New Project > Empty.

  2. Create a Reader node Generate Arrow Reader. Load the girl_blue.png image using the Path button. As with the loop body project, this Reader node will help us test our project.

  3. Create an Image IO node Project Arrow Image IO. Connect [Reader › image] to [image › Image IO]. This node will define the input of the posterize custom node project.

  4. Create a To M node Convert Arrow To M icon. Connect [Image IO › image] to [image › To M].

  5. Create a Blur node Filter Arrow Blur. Connect [To M › image] to [image › Blur].

    Loop Smooth

    Start Girl Blur

Posterize Attributes

Now we'll add and connect the attributes of the posterize filter.

  1. Create an Attributes node Project Arrow Image IO.

  2. In the Attributes panel click the Add Attribute button to add a new levels attribute. In the Add Attribute window set the new attribute properties:

    Add Attribute Levels

  3. Click Add Attribute button to add a new smooth attribute. In the Add Attribute window set the new attribute properties:

    Add Attribute Levels

  4. Expose the radiusx and radiusy on the Blur node [?].

  5. Connect [Attributes › smooth] to [radiusx › Blur]. Connect [Attributes › smooth] to [radiusy › Blur].

    Add Attribute Levels

Add the Loop Body

  1. Create an Node Graph node Project Arrow Node Graph. Click the Path button and select the Posterize_Loop.pxf.

  2. Double-click the Node Graph node to reativate it and display its Attributes.

  3. Connect [Blur › image] to [image › Node Graph].

  4. Expose the iterations attribute of the Node Graph node.

  5. Connect [Attributes › levels] to [iterations › Node Graph].

  6. Set the Attributes levels and smooth to posterize the image.

    Posterize. levels = 4. Smooth = 5.0.

  7. Create an Image IO node Project Arrow Image IO. Connect [Blur › image] to [image › Image IO]. This node will define the output of the posterize custom node project.

    Add Attribute Levels

  8. Set the Attributes levels and smooth to the values you'd like to have as default when the custom node is loaded.

  9. Save this project as Posterize.pxf.

Setting Paths as Relative

The Posterize.pxf project references the PosterizeLoop.pxf project. If these two files are moved to a different directory the Posterize.pxf needs to be able to locate the PosterizeLoop.pxf on that same directory. For this the path to the Posterize_Loop projects need to store all the paths to the files they reference as **relative paths.

  1. In the Posterize.pxf project on the top menu go to Edit > Paths Click the Make Relative button to make all paths relative to the location of the Posterize.pxf file.

    Project Paths

The Posterize_Loop.pxf project also has a reference to the image we used for testing, so you might also want to set the paths as relative on that project, although this is not needed for reusing this project as the reader node is ignored by the Posterize.pxf project.

Reusing the Posterize node

We'll now create a new project with an image and load the Posterize.pxf in a Node Graph node.

  1. Start a new empty project. File > New Project > Empty.

  2. Create a Reader node Generate Arrow Reader. Load an image from your PC.

  3. Create an Node Graph node Project Arrow Node Graph. Load the project Posterize.pxf using the Path button. Double-click the Node Graph node to reactivate it.

  4. Connect [Reader › image] to [image › Node Graph]. Set the attributes levels and smoth.

    Red Truck pixabay

    Red Truck Posterize

Conclusion

In this tutorial you learned how to build reusable custom nodes that iterate multiple times on images to create the desired effects.