Controls Usage Examples¶
Setup¶
Initialize a new camera to get access to its controls:
from quarklib import Camera
cam = Camera()
Basic reading/writing¶
Each control (both groups and leaves) have a read() and a write(val) methods.
print(cam.digital_gain.red.read())
cam.digital_gain.red.write(3.5)
cam.digital_gain.red.write(4.5) # raises ValueError because the value is outside the allowed range
cam.color_conversion.ccm.offset.write(np.array([0.2, 0.5, 0.2, 0.5]))
cam.pattern_generator.write("gradation") # set the generated pattern
cam.pattern_generator.write("invalid") # also raises a ValueError
Control metadata¶
Each control has a formatter property which returns either a single AbstractFormatter (for leaf controls) or a dict[str, AbstractFormatter | dict] (for group controls). The formatter objects provide information on the control’s value limits. They are used internally when reading/writing controls to convert to/from the raw format used in V4L2 and the format used by the user (e.g. floats that are represented as fixed point numbers on the camera).
# Red gain - a Q2.14 fixed point number.
fmt = cam.controls.digital_gain.red.formatter
print(fmt) # prints some basic information.
print(fmt.valid_set) # get the valid values, described as an interval of (min, max, step).
# validate the provided value. For floats, the validation only checks if the value is
# within the min and max value and simply rounds to the nearest representable value.
print(fmt.validate_value(1.5))
print(fmt.clamp_value) # Fully clamp the value to the allowed interval.
# Pattern generator - a menu value.
fmt2 = cam.controls.pattern_generator
print(fmt2.valid_set) # prints the list of possible menu values.
fmt2.validate_value("sequence 2") # succeeds only if the value matches exactly one valid value.
fmt2.clamp_value("seq 2") # Finds the closest match. Might be good for user input.
Grouped reading/writing¶
All controls that represent arrays can be manipulated using the indexing syntax provided by NumPy. Not that this still reads/writes the whole value (as required by V4L2) but it still means that the library user won’t have to worry about storing temporary values.
Certain group controls, those that represent arrays that are shape-compatible, also provide an indexing syntax that allows reading/writing across multiple V4L2 controls using a single read/write.
These concepts are best demonstrated with examples:
# Write the identity matrix to the top-left part of the ccm matrix:
# The actual control is 4x4 but the indexing only writes to a
# 3x3 corner.
cam.controls.color_conversion.ccm.matrix[:3, :3] = np.eye(3)
# Groups that contain numeric children with shapes that can be stacked,
# also supports this indexing operation.
# Here we get the red and green values for the digital_gain control group:
cam.controls.digital_gain[:2]
# The CCM consists of two matrices, forming an affine transformation when combined.
# It can be accessed like so:
cam.controls.color_conversion.ccm[0, :] = np.ones((5,))
# Indexing over the full range of values is equivalent to calling read/write, i.e., the
# following operations are pairwise equivalent:
# These both read all values
x = cam.controls.color_conversion.ccm.read()
x = cam.controls.color_conversion.ccm[:,:]
# These both write all values
cam.controls.color_conversion.ccm.write(x)
cam.controls.color_conversion.ccm[:,:] = x