# OPU Settings¶

## Interacting with the DMD¶

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.patches as patches
%matplotlib inline

from lightonml.datasets import MNIST
from lightonml.encoding.base import BinaryThresholdEncoder
from lightonml.random_projections.opu import OPURandomMapping
from lightonopu.opu import OPU


### Formatting¶

By default, the whole DMD is used to display a sample. Each value in the input array is displayed repeatedly in a region called macropixel. Different options are provided to build macropixels through the parameter position of OPURandomMapping. The size of macropixels is accessible as the factor attribute after fit has been called on the random mapping.

The formatting function to build macropixels is formatting_func instead: it takes a np.array of (0, 1) and dtype=uint8 of shape (n_features, ) and returns an array of the same type of shape (912 1140).

dummy_input = np.random.randint(0, 2, (32, 32)).astype('uint8')
plt.imshow(dummy_input, cmap='gray')

<matplotlib.image.AxesImage at 0x7fc09499dd30>

opu = OPU()
n_components = 10000
position = '1d_square_macro_pixels'
random_mapping = OPURandomMapping(opu=opu, n_components=n_components, position=position, disable_pbar=True)

random_mapping.fit(dummy_input.reshape(1, 32*32))

OPURandomMapping(disable_pbar=True, n_components=10000,
position='1d_square_macro_pixels', roi_position=(0, 0),
roi_shape=(1140, 912))

random_mapping.factor, random_mapping.roi_shape, random_mapping.roi_position

(961, (1140, 912), (0, 0))

h, w = random_mapping.roi_shape
y, x = random_mapping.roi_position

formatted_input = random_mapping.formatting_func(dummy_input.reshape(1, 32*32))

fig,ax = plt.subplots(1)
ax.imshow(formatted_input.reshape(1140, 912), cmap='gray')
plt.show()


### Changing DMD ROI shape and position¶

By default we use the whole DMD area to display the sample, but you can choose a specific ROI by passing the optional parameters roi_shape and roi_position to OPURandomMapping: the first parameter is the shape of the ROI and the second is the position of the upper left corner of the ROI.

Coordinates are in column order, so everything is in (height, width) and (y, x).

random_mapping = OPURandomMapping(opu=opu, n_components=n_components, position=position,
roi_shape=(600, 300), roi_position=(245, 131), disable_pbar=True)

random_mapping.fit(dummy_input.reshape(1, 32*32))

OPURandomMapping(disable_pbar=True, n_components=10000,
position='1d_square_macro_pixels', roi_position=(245, 131),
roi_shape=(600, 300))

random_mapping.factor, random_mapping.roi_shape, random_mapping.roi_position

(169, (600, 300), (245, 131))

h, w = random_mapping.roi_shape
y, x = random_mapping.roi_position

formatted_input = random_mapping.formatting_func(dummy_input.reshape(1, 32*32))

fig,ax = plt.subplots(1)
ax.imshow(formatted_input.reshape(1140, 912), cmap='gray')
rect = patches.Rectangle((x, y), w, h, linewidth=1, edgecolor='r', facecolor='none')
plt.show()


Use cases:

• Increasing the ROI increases the size of the macropixels, therefore the intensity of the signal on the camera.
• Changing the shape and the position of the ROI changes the transmission matrix, so it’s equivalent to a multiplication by a different random matrix.
• In case of inhomogeneous illumination on the DMD, to center the sample on the most illuminated region.

## Interacting with the camera¶

By default we use 1/16th of the total area of the camera as ROI, but you can change it by simple assignment.

It’s a tuple of two lists: the first is the position of the upper left corner of the ROI and the second is the shape of the ROI.

opu = OPU()
print('Max cam shape: {}'.format(opu.cam_shape_max))
print('Camera ROI: {}'.format(opu.cam_ROI))

Max cam shape: [1080, 1920]
Camera ROI: ([404, 736], [272, 480])

opu.cam_ROI = ([270, 480], [540, 960])

print('Camera ROI: {}'.format(opu.cam_ROI))

Camera ROI: ([270, 480], [540, 960])


## Frametime and exposure¶

Frametime and exposure are other two OPU parameters that can be changed: frame-time determines the speed of the system, exposure time determines the amount of light that reaches the camera.

• if you need to increase speed, you decrease the frame-time
• if you need to increase the strength of the signal you increase the exposure time
• exposure time must always be lower than frametime by a fair amount (100 $$\mu$$s)

They’re set to good default values, but you can change them when you build an OPU instance as OPU(frame_time, exposure_time). The values are in $$\mu$$s.

opu = OPU()
opu.frametime_us, opu.exposure_us

(500, 400)

opu = OPU(700, 200)
opu.frametime_us, opu.exposure_us

(700, 200)