Linear and polynomial filters

A filter file contains the name of the filter and a filter kernel description. The line containing the name of the filter starts with the character 'N'. The kernel is described as a sum of volterra coefficients. Every coefficient needs a line in the filter file beginning with the letter 'P' followed by a floating-point scaling factor. The remaining part of the line is used to describe the volterra coefficient.
As most of you probably know, a volterra coefficient is the product of different pixels. The coordinates are given relatively to the output pixel's position. Therefore, a filter like:
N Copy
P 1.0 0 0
simply copies the image, since it says: Take the pixel at position (0,0) relatively to the output position and scale it with 1.0.
A filter to delete the image would be:

N Delete
P 0.0 0 0

which is basically the same filter weighted with zero.
Now let's generate a real linear filter:

N Mean4
P 0.25 -1 0
P 0.25 1 0
P 0.25 0 -1
P 0.25 0 1

This is a smoothing filter. It takes the four neighbors of a pixel (left, right, top, bottom), weights them with 1/4 and sums them up. A volterra filter of fourth order just multiplying the same pixels would look like this:

N 4th_order_demo
P 1.0 -1 0 1 0 0 -1 0 1

Of course, this filter has a completely different effect.

Morphologic filters

The new thing about PolyMorph are the 'Volterra Morphology Filters'. A Morphologic filter is based on ranking and selecting the pixels in the neighborhood of the output position. The Median is basically a special case of such filters. To turn a filter into a morphology filter, just add a line beginning with S followed by a floating point between 0.0 and 1.0. 'S' means 'Selection', the value denotes the type of selection. A value of 0.0 means minimum, 1.0 means maximum, 0.5 means median.
If we need a 3x3 median filter, we simply target all neighbors weighted with 1.0 and insert S 0.5:

N Median_3x3
P 1 -1 -1
P 1 0 -1
P 1 1 -1
P 1 -1 0
P 1 0 0
P 1 1 0
P 1 -1 1
P 1 0 1
P 1 1 1
M 0.5

The same can be done with volterra filters. We could select the maximum between the two types of four-neighbor products:

P 1.0 -1 -1 1 1 -1 1 1 -1
P 1.0 0 1 0 -1 1 0 -1 0
M 1.0

Recursive definitions

It's possible to use recursive filter definitions. Since every filter hast it's own name, it's easy to build a filter working on top of other filters.
Let's take a look at the following filter:

N Edge_mark
P 1.0 0 0 Morphology_edge_3x3 0 0

This filter simply multiplies the result of an edge filter with the current image. The numbers after the filter name declaration simply define a volterra product (in this case, it just takes the relative position 0 0 without further processing). It is also possible to process results from other filters:

N Maximum_of_2_kernel_squares
P 1.0 Kernel_name_1 0 0 0 0
P 1.0 Kernel_name_2 0 0 0 0
M 1.0

This takes the filter results from two other kernels, squares them and delivers the maximum of the two values.

Rank filters

Version 0.6 of xenomorph introduces rank filters. A rank filter returns the position of a pixel or an operation (a P line) in a sorted sequence of other operations. This does not really involve sorting, since we are only interested in the position of a single value, not in the sorted sequence. In the xenomorph implementation, it returns the rank of the first product (the first P line) compared to all other lines. A primitive filter like the following returns the rank of the central pixel compared to it's eight neighbours:

N Rank_8
P 1.0 0 0
P 1.0 -1 -1
P 1.0 0 -1
P 1.0 1 -1
P 1.0 -1 0
P 1.0 1 0
P 1.0 -1 1
P 1.0 0 1
P 1.0 1 1
R 0.125

The second line contains the central pixel weighted with 1.0. The following seven lines contain it's eight neighboring pixels, also weighted with 1.0. Since the filter returns values between 0 and 8, the output is scaled by 1/8. This is done on the last line, which is telling xenomoprh that this is a ranking operation.

Including the filters

The software will search in your home-directory for the subdirectory ".KERNELS". The directory-tree contained in this directory will build the filter menu. Therefore, every subdirectory inside of .KERNELS will create another submenu, while the filter names are created by the naming strings found inside of the kernel files. You can easily extend the menu by creating new subdirectories and inserting your own filter kernel files. After restarting the software, the new filters should be available.

Hidden filters

Since version 0.6, filters can be hidden from the user. This makes sense if the filter is only used as a part of another filter. Simply save the filter with suffix *.hid, and it will be included into the filter namespace, but not into the selection menu.

If somebody creates a nice collection of filter files with good descriptions, please send them to me, I would like to include them.