# Aperture operators¶

Frequently image operators between gray level images rely mostly on the contrast between the pixels and not in their isolated values. To achieve this “brightness invariance” we can use Aperture Operators (ref here). This technique is implemented as a trios.FeatureExtractor as a subclass of trios.feature_extractors.RAWFeatureExtractor. Given a window W with dimensions (mtimes n), it subtracts the center pixel value from all points in the window, saturating at a value $k$. Thus, an Aperture feature extractor produces patterns in the range $$[-k,k]^N$$, where N is the size of W. It is defined as follows, where $$w_{i,j}$$ is the raw pixel value in W.

$\begin{split}a_{i,j} = \begin{cases} 0 & i=m/2, j=n/2 \\ max(-k, min(k, w_{i,j} - w_{m/2,n/2})) & \text{otherwise} \end{cases}\end{split}$

Example of use:

from trios.classifiers import SKClassifier
from sklearn.tree import DecisionTreeClassifier
from trios.feature_extractors import Aperture
import trios
import numpy as np

import trios.shortcuts.persistence as p

if __name__ == '__main__':
images = trios.Imageset([('images_gl/einstein-noise.png', 'images_gl/einstein-original.png', None)])
win = np.ones((7, 7), np.uint8)

# use Decision Tree Classifier and raw pixels as features.
ap = Aperture(win, 10, mul=0.5)
op = trios.WOperator(win, SKClassifier(DecisionTreeClassifier()), ap)
print('Training...')
op.train(images)

# save trained operator
p.save_gzip(op, 'ap-einstein.op')

print('Applying to image images_gl/einstein-noise.png')
out = op.apply(img, img)
p.save_image(out, 'out-ap-einstein.png')