Tools

Microcontroller templates

Arduino Template

The src/crappy/tool/microcontroller.ino file is an Arduino template meant to be used in combination with the ClientServer Block. It greatly simplifies the use of this Block by leaving only a few fields for the user to complete. It mainly manages the serial communication between the PC and the microcontroller.

MicroPython Template

The src/crappy/tool/microcontroller.py file is a MicroPython template meant to be used in combination with the ClientServer Block. It greatly simplifies the use of this Block by leaving only a few fields for the user to complete. It mainly manages the serial communication between the PC and the microcontroller.

Bindings

Comedi Bind

This file contains the code for binding the C++ Comedi library in Python.

It is only used by the Comedi InOut. The bindings haven’t been tested for a while.

Py Spectrum

This file contains the code for binding the C++ Spectrum library in Python.

It is only used by the SpectrumM2I4711 InOut. The bindings haven’t been tested for a while.

Camera Configurators

Camera Configurator

class crappy.tool.camera_config.CameraConfig(camera: Camera, log_queue: Queue, log_level: int | None, max_freq: float | None)[source]

This class is a GUI allowing the user to visualize the images from a Camera before a Crappy test starts, and to tune the settings of the Camera.

It is meant to be user-friendly and interactive. It is possible to zoom on the image using the mousewheel, and to move on the zoomed image by right-clicking and dragging.

In addition to the image, the interface also displays a histogram of the pixel values, an FPS counter, a detected bits counter, the minimum and maximum pixel values, and the value and position of the pixel currently under the mouse. A checkbox allows auto-adjusting the pixel range to get a better contrast.

This class is used as is by the Camera, but also subclassed to provide more specific functionalities to other camera-related Blocks like VideoExtenso or DICVE.

This class is a child of tkinter.Tk. It relies on the Zoom and HistogramProcess tools. It also interacts with instances of the CameraSetting class.

New in version 1.4.0.

Changed in version 2.0.0: renamed from Camera_config to CameraConfig

__init__(camera: Camera, log_queue: Queue, log_level: int | None, max_freq: float | None) None[source]

Initializes the interface and displays it.

Parameters:
  • camera – The Camera object in charge of acquiring the images.

  • log_queue

    A multiprocessing.Queue for sending the log messages to the main Logger, only used in Windows.

    New in version 2.0.0.

  • log_level

    The minimum logging level of the entire Crappy script, as an int.

    New in version 2.0.0.

  • max_freq

    The maximum frequency this window is allowed to loop at. It is simply the freq attribute of the Camera Block.

    New in version 2.0.0.

main() None[source]

Constantly updates the image and the information on the GUI, until asked to stop.

New in version 1.5.10.

log(level: int, msg: str) None[source]

Record log messages for the CameraConfig window.

Also instantiates the Logger when logging the first message.

Parameters:
  • level – An int indicating the logging level of the message.

  • msg – The message to log, as a str.

New in version 2.0.0.

Camera Configurator with Boxes

class crappy.tool.camera_config.CameraConfigBoxes(camera: Camera, log_queue: Queue, log_level: int | None, max_freq: float | None)[source]

This class is a basis for the configuration GUIs featuring boxes to display or to draw.

It is a child of the base CameraConfig, and relies on the Box and SpotsBoxes tools. It implements useful methods for drawing one or several Boxes. If instantiated, this class behaves the exact same way as its parent class. It is not used as is by any Block in Crappy.

New in version 1.4.0.

Changed in version 2.0.0: renamed from Camera_config_with_boxes to CameraConfigBoxes

__init__(camera: Camera, log_queue: Queue, log_level: int | None, max_freq: float | None) None[source]

Initializes the parent class and sets the spots container.

Parameters:
  • camera – The Camera object in charge of acquiring the images.

  • log_queue

    A multiprocessing.Queue for sending the log messages to the main Logger, only used in Windows.

    New in version 2.0.0.

  • log_level

    The minimum logging level of the entire Crappy script, as an int.

    New in version 2.0.0.

  • max_freq

    The maximum frequency this window is allowed to loop at. It is simply the freq attribute of the Camera Block.

    New in version 2.0.0.

DIS Correl Configurator

class crappy.tool.camera_config.DISCorrelConfig(camera: Camera, log_queue: Queue, log_level: int | None, max_freq: float | None, patch: Box)[source]

Class similar to CameraConfig but also allowing to select the area on which the correlation will be performed.

It relies on the Box tool. It is meant to be used for configuring the DISCorrel Block.

New in version 1.4.0.

Changed in version 2.0.0: renamed from DISConfig to DISCorrelConfig

__init__(camera: Camera, log_queue: Queue, log_level: int | None, max_freq: float | None, patch: Box) None[source]

Initializes the parent class and sets the correlation Box.

Parameters:
  • camera – The Camera object in charge of acquiring the images.

  • log_queue

    A multiprocessing.Queue for sending the log messages to the main Logger, only used in Windows.

    New in version 2.0.0.

  • log_level

    The minimum logging level of the entire Crappy script, as an int.

    New in version 2.0.0.

  • max_freq

    The maximum frequency this window is allowed to loop at. It is simply the freq attribute of the Camera Block.

    New in version 2.0.0.

  • patch

    The Box container that will save the information on the patch where to perform image correlation.

    New in version 2.0.0.

DIS VE Configurator

class crappy.tool.camera_config.DICVEConfig(camera: Camera, log_queue: Queue, log_level: int | None, max_freq: float | None, patches: SpotsBoxes)[source]

Class similar to CameraConfig but also displaying the bounding boxes of the regions defined as patches.

It relies on the Box and SpotsBoxes tools. It is meant to be used for configuring the DICVE Block.

New in version 1.5.10.

Changed in version 2.0.0: renamed from DISVE_config to DICVEConfig

__init__(camera: Camera, log_queue: Queue, log_level: int | None, max_freq: float | None, patches: SpotsBoxes) None[source]

Sets the patches and initializes the parent class.

Parameters:
  • camera – The Camera object in charge of acquiring the images.

  • log_queue

    A multiprocessing.Queue for sending the log messages to the main Logger, only used in Windows.

    New in version 2.0.0.

  • log_level

    The minimum logging level of the entire Crappy script, as an int.

    New in version 2.0.0.

  • max_freq

    The maximum frequency this window is allowed to loop at. It is simply the freq attribute of the Camera Block.

    New in version 2.0.0.

  • patches – An instance of SpotsBoxes containing the patches to follow for image correlation.

Video Extenso Configurator

class crappy.tool.camera_config.VideoExtensoConfig(camera: Camera, log_queue: Queue, log_level: int | None, max_freq: float | None, detector: SpotsDetector)[source]

Class similar to CameraConfig but also displaying the bounding boxes of the detected spots, and allowing to select the area where to detect the spots by drawing a box with the left mouse button.

It relies on the Box and SpotsDetector tools. It is meant to be used for configuring the VideoExtenso Block.

New in version 1.4.0.

Changed in version 2.0.0: renamed from VE_config to VideoExtensoConfig

__init__(camera: Camera, log_queue: Queue, log_level: int | None, max_freq: float | None, detector: SpotsDetector) None[source]

Sets the args and initializes the parent class.

Parameters:
  • camera – The Camera object in charge of acquiring

  • images. (the) –

  • log_queue

    A multiprocessing.Queue for sending the log messages to the main Logger, only used in Windows.

    New in version 2.0.0.

  • log_level

    The minimum logging level of the entire Crappy script, as an int.

    New in version 2.0.0.

  • max_freq

    The maximum frequency this window is allowed to loop at. It is simply the freq attribute of the Camera Block.

    New in version 2.0.0.

  • detector

    An instance of SpotsDetector used for detecting spots on the images received from the Camera.

    New in version 2.0.0.

Changed in version 1.5.10: renamed ve argument to video_extenso

Removed in version 2.0.0: video_extenso argument

Configurator Tools

Box

class crappy.tool.camera_config.config_tools.Box(x_start: int | None = None, x_end: int | None = None, y_start: int | None = None, y_end: int | None = None, x_disp: float | None = None, y_disp: float | None = None, x_centroid: float | None = None, y_centroid: float | None = None)[source]

This class represents a box to be drawn on top of the images of a CameraConfig window or Displayer Process of a Camera Block.

It is a child of Overlay.

It can represent either the box drawn when selecting a region, or the bounding box of a tracked area.

New in version 2.0.0.

__post_init__() None[source]

Needed to have the Logger of the parent class properly initialized.

draw(img: ndarray) None[source]

Draws the Box on top of the given image, and returns the modified image.

The thickness of the drawn lines adapts to the size of the image, so that the lines are always visible even when casting the image to a smaller format.

no_points() bool[source]

Returns whether all four sides of the box are defined or not.

reset() None[source]

Resets the sides to None.

sorted() Tuple[int, int, int, int][source]

Returns the four coordinates but sorted in the order : min x, max x, min y, max y.

__init__(x_start: int | None = None, x_end: int | None = None, y_start: int | None = None, y_end: int | None = None, x_disp: float | None = None, y_disp: float | None = None, x_centroid: float | None = None, y_centroid: float | None = None) None

Simply initializes the logger to None.

Histogram Process

class crappy.tool.camera_config.config_tools.HistogramProcess(stop_event: Event, processing_event: Event, img_in: Queue, img_out: Queue, log_level: int | None, log_queue: Queue)[source]

This class is a multiprocessing.Process taking an image as an input via a multiprocessing.Pipe, and returning the histogram of that image in another Pipe.

It is used by the CameraConfig window and its children to delegate and parallelize the calculation of the histogram. It allows to gain a few frames per second on the display in the configuration window.

New in version 2.0.0.

__init__(stop_event: Event, processing_event: Event, img_in: Queue, img_out: Queue, log_level: int | None, log_queue: Queue) None[source]

Sets the arguments and initializes the parent class.

Parameters:
  • stop_event – An multiprocessing.Event signaling the Process when to stop running.

  • processing_event – An multiprocessing.Event set by the multiprocessing.Process to indicate that it’s currently processing an image. Avoids having images to process piling up.

  • img_in – The Queue through which the images to process are received.

  • img_out – The Queue through which the calculated histograms are sent back.

  • log_level – The minimum logging level of the entire Crappy script, as an int.

  • log_queue – A multiprocessing.Queue for sending the log messages to the main Logger, only used in Windows.

run() None[source]

The main method being run by the HistogramProcess.

It continuously receives images from the CameraConfig, calculates their histograms and returns them back as a nice image to integrate on the window.

log(level: int, msg: str) None[source]

Records log messages for the HistogramProcess.

Also instantiates the Logger when logging the first message.

Parameters:
  • level – An int indicating the logging level of the message.

  • msg – The message to log, as a str.

Overlay

class crappy.tool.camera_config.config_tools.Overlay[source]

This class is the base class for all the classes adding overlays on top of the images displayed by a Displayer Process of a Camera Block.

Also used for drawing overlays on top of the images in the CameraConfig window, for the children of the Camera Block supporting it.

It is mainly useful for providing the log() method, and creating a clear architecture. It is also relevant to use for type-hinting.

New in version 2.0.0.

__init__() None[source]

Simply initializes the logger to None.

draw(img: ndarray) None[source]

This method takes the image to display as an input, draws an overlay on top of it, and returns the modified image.

It is meant to be overriden by subclasses of this class.

log(log_level: int, msg: str) None[source]

Method for recording log messages from the Overlay class.

Parameters:
  • log_level – An int indicating the logging level of the message.

  • msg – The message to log, as a str.

Spots Boxes

class crappy.tool.camera_config.config_tools.SpotsBoxes(spot_1: Box | None = None, spot_2: Box | None = None, spot_3: Box | None = None, spot_4: Box | None = None, x_l0: float | None = None, y_l0: float | None = None)[source]

This class stores up to four instances of Box, defining the bounding boxes of the spots for VideoExtenso or the patches for DICVE.

It can also instantiate the Box objects by parsing a list of tuples containing enough information.

New in version 2.0.0.

set_spots(spots: List[Tuple[int, int, int, int]]) None[source]

Parses a list of tuples and instantiates the corresponding Box objects.

empty() bool[source]

Returns True if all spots are None, else False.

reset() None[source]

Resets the boxes to None.

__init__(spot_1: Box | None = None, spot_2: Box | None = None, spot_3: Box | None = None, spot_4: Box | None = None, x_l0: float | None = None, y_l0: float | None = None) None

Spots Detector

class crappy.tool.camera_config.config_tools.SpotsDetector(white_spots: bool = False, num_spots: int | None = None, min_area: int = 150, blur: int | None = 5, update_thresh: bool = False, safe_mode: bool = False, border: int = 5)[source]

This class detects round spots on a grey level image.

It takes an image from a CameraConfig window as an input of the detect_spots() method, and tries to detect the requested number of spots on it. It then stores the position and size of the detected spots, to pass them later on to the VideoExtensoTool along with other variables once the CameraConfig window is closed.

New in version 2.0.0.

__init__(white_spots: bool = False, num_spots: int | None = None, min_area: int = 150, blur: int | None = 5, update_thresh: bool = False, safe_mode: bool = False, border: int = 5) None[source]

Sets the arguments.

Parameters:
  • white_spots – If True, detects white spots over a black background. If False, detects black spots over a white background. Also passed to the VideoExtensoTool.

  • num_spots – The number of spots to detect, as an int between 1 and 4. If given, will try to detect exactly that number of spots and will fail if not enough spots can be detected. If left to None, will detect up to 4 spots, but potentially fewer.

  • min_area – The minimum area an object should have to be potentially detected as a spot. The value is given in pixels, as a surface unit. It must of course be adapted depending on the resolution of the camera and the size of the spots to detect.

  • blur – An int, odd and greater than 1, defining the size of the kernel to use when applying a median blur filter to the image before trying to detect spots. Can also be set to None, in which case no median blur filter is applied before detecting the spots. Also passed to the VideoExtensoTool.

  • update_thresh – If True, the grey level threshold for detecting the spots is re-calculated at each new image. Otherwise, the first calculated threshold is kept for the entire test. The spots are less likely to be lost with adaptive threshold, but the measurement will be more noisy. Adaptive threshold may also yield inconsistent results when spots are lost. Passed to the VideoExtensoTool and not used in this class.

  • safe_mode – If True, will stop and raise an exception as soon as overlapping spots are detected. Otherwise, will first try to reduce the detection window to get rid of overlapping. This argument should be used when inconsistency in the results may have critical consequences. Passed to the VideoExtensoTool and not used in this class.

  • border – When searching for the new position of a spot, will search in the last known bounding box of this spot plus a few additional pixels in each direction. This argument sets the number of additional pixels to use. It should be greater than the expected “speed” of the spots, in pixels / frame. But if set too high, noise or other spots might hinder the detection. Passed to the VideoExtensoTool and not used in this class.

detect_spots(img: ndarray, y_orig: int, x_orig: int) None[source]

Transforms the image to improve spot detection, detects up to 4 spots and return a SpotsBoxes object containing all the detected spots.

Parameters:
  • img – The sub-image on which the spots should be detected.

  • y_orig – The y coordinate of the top-left pixel of the sub-image on the entire image.

  • x_orig – The x coordinate of the top-left pixel of the sub-image on the entire image.

Returns:

A SpotsBoxes object containing all the detected spots.

Zoom

class crappy.tool.camera_config.config_tools.Zoom(x_low: float = 0.0, x_high: float = 1.0, y_low: float = 0.0, y_high: float = 1.0)[source]

This class stores the upper and lower limits of the image to display in the CameraConfig window.

It also allows updating them when the user changes the zoom ratio or drags the image with the mouse.

New in version 2.0.0.

reset() None[source]

Resets the zoom level to default (no zoom).

update_zoom(x: float, y: float, ratio: float) None[source]

Updates the upper and lower limits of the image when the user scrolls with the mousewheel.

The update is based on the zoom ratio and the position of the mouse on the screen.

Parameters:
  • x – The x position of the mouse on the image, as a ratio between 0 and 1.

  • y – The y position of the mouse on the image, as a ratio between 0 and 1.

  • ratio – The zoom ratio to apply. If it is greater than 1 we zoom in, otherwise we zoom out.

update_move(delta_x: float, delta_y: float) None[source]

Updates the upper and lower limits of the image when the user moves the image with a left button click.

Parameters:
  • delta_x – The x displacement to apply to the image, as a ratio of the total image width.

  • delta_y – The y displacement to apply to the image, as a ratio of the total image height.

__init__(x_low: float = 0.0, x_high: float = 1.0, y_low: float = 0.0, y_high: float = 1.0) None

Data

The folder src/crappy/tool/data/ contains various images that need to be distributed with the module. The no_image.png image is used by the CameraConfig window in case no image could be acquired yet. The speckle.png and ve_markers.tif images serve as example of samples with respectively a speckle and spots drawn on them. They are used in several examples to demonstrate the use of VideoExtenso or DICVE without requiring any camera. The pad.png image is used for demonstrating the use of the Canvas Block.

FT232H Tools

FT232H

class crappy.tool.ft232h.FT232H(mode: str, serial_nr: str | None = None, i2c_speed: float = 100000.0, spi_turbo: bool = False)[source]

A class for controlling FTDI’s USB to Serial FT232H.

Communication in SPI and I2C are implemented, along with GPIO control. The name of the methods for SPI and I2C communication are those of smbus and spidev libraries, in order to facilitate the use and the integration in a multi-backend environment. This class also allows to write a USB serial number in the EEPROM, as there’s no default serial number on the chip.

Note

The FT232H does not support clock stretching and this may cause bugs with some I2C devices. Lowering the i2c_speed may solve the problem.

Important

If using Adafruit’s board, its I2C Mode switch should of course be set to the correct value according to the chosen mode.

Important

Only for Linux users: In order to drive the FT232H, the appropriate udev rule should be set. This can be done using the udev_rule_setter utility in crappy’s util folder. It is also possible to add it manually by running:

$ echo "SUBSYSTEM==\"usb\", ATTR{idVendor}==\"0403\", MODE=\"0666\"" | sudo tee ftdi.rules > /dev/null 2>&1

in a shell opened in /etc/udev/rules.d.

Important

For controlling several FT232H from the same computer, it is first necessary to set their USB serial numbers. Otherwise, an error will be raised. This can be done using the crappy utility set_ft232h_serial_nr.py.

New in version 1.5.10.

Changed in version 2.0.0: renamed from ft232h to FT232H

__init__(mode: str, serial_nr: str | None = None, i2c_speed: float = 100000.0, spi_turbo: bool = False) None[source]

Checks the arguments validity, initializes the device and sets the locks.

Parameters:
  • mode

    The communication mode as a str, can be :

    'SPI', 'I2C', 'GPIO_only', 'Write_serial_nr'
    

    GPIOs can be driven in any mode, but faster speeds are achievable in GPIO_only mode.

  • serial_nr – The serial number of the FT232H to drive, as a str. In Write_serial_nr mode, the serial number to be written.

  • i2c_speed

    In I2C mode, the I2C bus clock frequency in Hz, as an int. Available values are :

    100E3, 400E3, 1E6
    

    or any value between 10kHz and 100kHz. Lowering below the default value may solve I2C clock stretching issues on some devices.

  • spi_turbo – If True, increases the achievable bus speed in SPI mode, but may not work with some devices.

Note

  • CS pin: The CS pin for selecting SPI devices is always D3. This pin is reserved and cannot be used as a GPIO. If you want to drive the CS line manually, it is possible not to drive the CS pin by setting the SPI parameter no_cs to True and to drive the CS line from a GPIO instead.

  • mode: It is not possible to simultaneously control slaves over SPI and I2C, due to different hardware requirements for the two protocols. Trying to do so will most likely raise an error or lead to inconsistent behavior.

log(level: int, msg: str) None[source]

Wrapper for logging messages.

Also initializes the Logger on the first message.

Parameters:
  • level – The logging level of the message, as an int.

  • msg – The message to log, as a str.

write_byte(i2c_addr: int, value: int) None[source]

Writes a single byte to an I2C slave, in register 0.

Parameters:
  • i2c_addr – The I2C address of the slave, as an int.

  • value – The value to write, as an int.

write_byte_data(i2c_addr: int, register: int, value: int) None[source]

Writes a single byte to an I2C slave, in the specified register.

Parameters:
  • i2c_addr – The I2C address of the slave, as an int.

  • register – The index of the register to be written, as an int.

  • value – The value to write, as an int.

write_word_data(i2c_addr: int, register: int, value: int) None[source]

Writes 2 bytes to an I2C slave from a single int value, starting at the specified register.

Depending on the size of the registers, the next register may be written as well.

Parameters:
  • i2c_addr – The I2C address of the slave, as an int.

  • register – The index of the first register to be written, as an int.

  • value – The value to write, as an int.

write_block_data(i2c_addr: int, register: int, data: list) None[source]

Actually calls write_i2c_block_data().

Parameters:
  • i2c_addr – The I2C address of the slave, as an int.

  • register – The index of the first register to be written, as an int.

  • data – A list of bytes to write.

write_i2c_block_data(i2c_addr: int, register: int, data: list) None[source]

Writes bytes from a list to an I2C slave, starting at the specified register.

Parameters:
  • i2c_addr – The I2C address of the slave, as an int.

  • register – The index of the first register to be written, as an int.

  • data – A list of bytes to write.

read_byte(i2c_addr: int) int[source]

Reads a single byte from an I2C slave, from the register 0.

Parameters:

i2c_addr – The I2C address of the slave, as an int.

Returns:

Value of the read register

read_byte_data(i2c_addr: int, register: int) int[source]

Reads a single byte from an I2C slave, from the specified register.

Parameters:
  • i2c_addr – The I2C address of the slave, as an int.

  • register – The index of the register to be read, as an int.

Returns:

Value of the read register

read_word_data(i2c_addr: int, register: int) int[source]

Reads 2 bytes from an I2C slave, starting at the specified register, and returns them as one single value.

Parameters:
  • i2c_addr – The I2C address of the slave, as an int.

  • register – The index of the first register to be read, as an int.

Returns:

Value of the read registers

read_i2c_block_data(i2c_addr: int, register: int, length: int) List[int][source]

Reads a given number of bytes from an I2C slave, starting at the specified register.

Parameters:
  • i2c_addr – The I2C address of the slave, as an int.

  • register – The index of the first register to be read, as an int.

  • length – The number of bytes to read, as an int.

Returns:

Values of read registers as a list

i2c_rdwr(*i2c_msgs: I2CMessage) None[source]

Exchanges messages with a slave that doesn’t feature registers.

A start condition is sent at the beginning of each transaction, but only one stop condition is sent after the last transaction.

Parameters:

*i2c_msgs – One or several I2CMessage to exchange with the slave. They are either read or write messages.

property bits_per_word: int

Number of bits per SPI words.

Can only be set to 8.

property cshigh: bool

If True, the polarity of the CS line is inverted.

property loop: bool

If True, the loopback mode is enabled.

property no_cs: bool

If True, the CS line is not driven.

property lsbfirst: bool

If True, data is sent and received LSB first.

property max_speed_hz: float

The SPI bus clock frequency in Hz.

In SPI modes 1 and 3, the actual bus clock frequency is 50% higher than the input value because the FT232H is switched to 3-phase clock mode.

property mode: int

The SPI mode used for communicating with the slave.

When changing the SPI mode, the bus clock frequency may be reloaded.

property threewire: bool

If True, indicates that the MISO and MOSI lines are connected together. Not currently implemented.

readbytes(len: int, start: bool = True, stop: bool = True) List[int][source]

Reads the specified number of bytes from an SPI slave.

Parameters:
  • len – The number of bytes to read, as an int.

  • start – If False, the CS line is not driven before reading data, and remains in its previous state.

  • stop – If False, the CS line is not driven after reading data, and remains in its previous state.

Returns:

List of read bytes

writebytes(values: list, start: bool = True, stop: bool = True) None[source]

Write bytes from a list to an SPI slave.

Parameters:
  • values – A :obj:list` of bytes to write

  • start – If False, the CS line is not driven before reading data, and remains in its previous state.

  • stop – If False, the CS line is not driven after reading data, and remains in its previous state.

writebytes2(values: list, start: bool = True, stop: bool = True) None[source]

Actually calls the writebytes() method with the same arguments.

xfer(values: list, speed: float | None = None, delay: float = 0.0, bits: int = 8, start: bool = True, stop: bool = True) List[int][source]

Simultaneously reads and write bytes to an SPI slave.

The number of bytes to read is equal to the number of bytes in the write buffer.

Parameters:
  • values – A :obj:list` of bytes to write.

  • speed – Sets the bus clock frequency in Hz before issuing the command, as a float.

  • delay – Not implemented, should be 0.0

  • bits – Not implemented, should be 8

  • start – If False, the CS line is not driven before reading data, and remains in its previous state.

  • stop – If False, the CS line is not driven after reading data, and remains in its previous state.

Returns:

List of read bytes

xfer2(values: list, speed: float = 6000000.0, delay: float = 0.0, bits: int = 8, start: bool = True, stop: bool = True) List[int][source]

Actually calls the xfer() method with the same arguments.

xfer3(values: list, speed: float = 6000000.0, delay: float = 0.0, bits: int = 8, start: bool = True, stop: bool = True) List[int][source]

Actually calls the xfer() method with the same arguments.

get_gpio(gpio_str: str) bool[source]

Reads the 3.3V-logic voltage value of the specified pin.

Parameters:

gpio_str – The name of the GPIO to be read, as a str.

Returns:

3.3V-logic value corresponding to the input voltage

set_gpio(gpio_str: str, value: int) None[source]

Sets the specified GPIO as an output and sets its output value.

Parameters:
  • gpio_str – The name of the GPIO to be set, as a str.

  • value – 1 for setting the GPIO high, 0 for setting it low.

close() None[source]

Closes the FTDI interface/port.

FT232H Server

class crappy.tool.ft232h.FT232HServer(mode: str, block_index: int, current_block: Synchronized, command_file: FileIO, answer_file: FileIO, block_lock: RLock, shared_lock: RLock, serial_nr: str | None = None, i2c_speed: float = 100000.0, spi_turbo: bool = False)[source]

A class for controlling FTDI’s USB to Serial FT232H.

This class is very similar to the FT232H except it doesn’t directly instantiate the USB device nor send commands to it directly. Instead, the commands are sent to a USBServer managing communication with the FT232H device(s).

Communication in SPI and I2C are implemented, along with GPIO control. The name of the methods for SPI and I2C communication are those of smbus and spidev libraries, in order to facilitate the use and the integration in a multi-backend environment. This class also allows to write a USB serial number in the EEPROM, as there’s no default serial number on the chip.

Note

The FT232H does not support clock stretching and this may cause bugs with some I2C devices. Lowering the i2c_speed may solve the problem.

Important

If using Adafruit’s board, its I2C Mode switch should of course be set to the correct value according to the chosen mode.

Important

Only for Linux users: In order to drive the FT232H, the appropriate udev rule should be set. This can be done using the udev_rule_setter utility in crappy’s util folder. It is also possible to add it manually by running:

$ echo "SUBSYSTEM==\"usb\", ATTR{idVendor}==\"0403\", MODE=\"0666\"" | sudo tee ftdi.rules > /dev/null 2>&1

in a shell opened in /etc/udev/rules.d.

Important

For controlling several FT232H from the same computer, it is first necessary to set their USB serial numbers. Otherwise, an error will be raised. This can be done using the crappy utility set_ft232h_serial_nr.py.

New in version 1.5.10.

Changed in version 2.0.0: renamed from ft232h_server to FT232HServer

__init__(mode: str, block_index: int, current_block: Synchronized, command_file: FileIO, answer_file: FileIO, block_lock: RLock, shared_lock: RLock, serial_nr: str | None = None, i2c_speed: float = 100000.0, spi_turbo: bool = False) None[source]

Checks the argument validity and initializes the device.

Parameters:
  • mode

    The communication mode as a str, can be :

    'SPI', 'I2C', 'GPIO_only', 'Write_serial_nr'
    

    GPIOs can be driven in any mode, but faster speeds are achievable in GPIO_only mode.

  • block_index

    The index the Block driving this FT232HServer instance has been assigned by the USBServer, as an int.

    Changed in version 2.0.0: renamed from block_number to block_index

  • current_block

    The handle to a shared multiprocessing.Value indicating which Block can currently communicate with the USBServer.

    Changed in version 2.0.0: renamed from current_file to current_block

  • command_file – A file in which the current command to be executed by the USB server is written.

  • answer_file – A file in which the answer to the current command is written.

  • block_lock – A multiprocessing.Lock assigned to this Block only, for signaling the USBServer when the command has been written in the command_file.

  • shared_lock

    A multiprocessing.Lock common to all the Block that allows the one Block holding it to communicate with the USBServer.

    Changed in version 2.0.0: renamed from current_lock to shared_lock

  • serial_nr – The serial number of the FT232H to drive, as a str. In Write_serial_nr mode, the serial number to be written.

  • i2c_speed

    In I2C mode, the I2C bus clock frequency in Hz. Available values are :

    100E3, 400E3, 1E6
    

    or any value between 10kHz and 100kHz. Lowering below the default value may solve I2C clock stretching issues on some devices.

  • spi_turbo – Increases the achievable bus speed in SPI mode, but may not work with some devices.

Note

  • CS pin: The CS pin for selecting SPI devices is always D3. This pin is reserved and cannot be used as a GPIO. If you want to drive the CS line manually, it is possible not to drive the CS pin by setting the SPI parameter no_cs to True and to drive the CS line from a GPIO instead.

  • mode: It is not possible to simultaneously control slaves over SPI and I2C, due to different hardware requirements for the two protocols. Trying to do so will most likely raise an error or lead to inconsistent behavior.

close() None[source]

Closes the FTDI interface/port.

I2C Message

class crappy.tool.ft232h.I2CMessage(type_: str, address: int, length: int | None = None, buf: list | None = None)[source]

Class that mimics the smbus2.i2c_msg class.

It is used for communication with the FT232HServer, only by the MPRLS InOut.

New in version 1.5.10.

Changed in version 2.0.0: renamed from i2c_msg_ft232h to I2CMessage

__init__(type_: str, address: int, length: int | None = None, buf: list | None = None) None[source]

Simply sets the attributes of the class, that characterizes the I2C message.

Parameters:
  • type – Either a read (‘r’) or a write (‘w’) message

  • address – The address of the I2C slave, as an int.

  • length – For a read message, the number of bytes to read as an int.

  • buf – For a write message, the list of bytes to be written.

classmethod read(address: int, length: int) I2CMessage[source]

Instantiates an I2CMessage object for reading bytes.

Parameters:
  • address – The address of the I2C slave, as an int.

  • length – The number of bytes to read, as an int.

classmethod write(address: int, buf: list) I2CMessage[source]

Instantiates an I2CMessage object for writing bytes.

Parameters:
  • address – The address of the I2C slave, as an int.

  • buf – The list of bytes to be written.

property addr: int

The address of the I2C slave.

property buf: List[int]

The list of bytes to be written, or the list of bytes read.

property len: int

The number of bytes to read.

USB Server

class crappy.tool.ft232h.USBServer(current_block: Synchronized, command_file: FileIO, answer_file: FileIO, block_dict: Dict[int, BlockObjects], stop_event: Event, log_queue: Queue, log_level: int | None)[source]

This class is a server managing communication with USB devices through the pysub library.

As pyusb is not process-safe in Python, running a server is the only option to allow multiple Block to use the library in parallel. This server simply sends the USB commands it receives to the USB devices, and returns back the answers. It features a quite complex architecture for managing the requests and properly starting up and shutting down.

The server is a child of multiprocessing.Process.

New in version 1.5.2.

Changed in version 2.0.0: renamed from Usb_server to USBServer

__init__(current_block: Synchronized, command_file: FileIO, answer_file: FileIO, block_dict: Dict[int, BlockObjects], stop_event: Event, log_queue: Queue, log_level: int | None) None[source]

Sets the arguments.

Parameters:
  • current_block – A multiprocessing.Value storing the index of the Block currently allowed to communicate with the server.

  • command_file – The handle to a file where the USB commands to send will be written.

  • answer_file – The handle to a file where to write the answers from the USB devices.

  • block_dict – A dict indicating for each index which Block it corresponds to.

  • stop_event – A multiprocessing.Event indicating the server when it should stop running.

  • log_queue – A multiprocessing.Queue for sending the log messages to the main Logger, only used in Windows.

  • log_level – The minimum logging level of the entire Crappy script, as an int.

classmethod register(ser_num: str | None = None) Tuple[int, RLock, FileIO, FileIO, RLock, Synchronized][source]

Allows a Block to register for communicating with the server. This Block is then given the necessary information for communication.

Parameters:

ser_num – The serial number of the FT232H to communicate with, as a str.

Returns:

A tuple containing the necessary information for other objects to communicate with the server. This information is for example given as arguments to FT232HServer objects.

New in version 2.0.0.

classmethod start_server(log_queue: Queue, log_level: int) None[source]

Initializes and starts the USB server Process.

Parameters:
  • log_queue

    The multiprocessing.Queue carrying the log messages from the server Process to Crappy’s centralized log handler. Only used in Windows.

    New in version 2.0.0.

  • log_level

    The minimum logging level of the entire Crappy script, as an int.

    New in version 2.0.0.

classmethod stop_server() None[source]

If the server was started, tries to stop it gently and if not successful terminates it.

New in version 2.0.0.

classmethod log(level: int, msg: str) None[source]

Wrapper for recording log messages.

Also instantiates the Logger on the first message.

Parameters:
  • level – The logging level of the message, as an int.

  • msg – The message to log, as a str.

New in version 2.0.0.

run() None[source]

The main loop of the server.

Waits for a Block to acquire control, reads its command, sends it to the correct USB device, reads the answer from the USB device and sends it back to the Block in control. Then, does the same with the next Block getting control over the server.

New in version 2.0.0.

Image Processing Tools

DIS Correl Tool

class crappy.tool.image_processing.DISCorrelTool(box: Box, fields: List[str | ndarray] | None = None, alpha: float = 3, delta: float = 1, gamma: float = 0, finest_scale: int = 1, init: bool = True, iterations: int = 1, gradient_iterations: int = 10, patch_size: int = 8, patch_stride: int = 3)[source]

This class is the core of the DISCorrel Block.

It receives images from a Camera object, and performs Dense Inverse Search correlation on each new image to get fields of interest. It relies on DISFlow for the image correlation, handles the projection of the image on the chosen fields, and calculates the residuals.

New in version 1.4.0.

Changed in version 2.0.0: renamed from DISCorrel to DISCorrelTool

__init__(box: Box, fields: List[str | ndarray] | None = None, alpha: float = 3, delta: float = 1, gamma: float = 0, finest_scale: int = 1, init: bool = True, iterations: int = 1, gradient_iterations: int = 10, patch_size: int = 8, patch_stride: int = 3) None[source]

Sets the parameters of DISFlow.

Parameters:
  • box

    An instance of the Box object containing the coordinates of the patch on which to perform image correlation.

    New in version 2.0.0.

  • fields

    The base of fields to use for the projection, given as a list of str or numpy arrays (both types can be mixed). Strings are for using automatically-generated fields, the available ones are :

    'x', 'y', 'r', 'exx', 'eyy', 'exy', 'eyx', 'exy2', 'z'
    

    If users provide their own fields as arrays, they will be used as-is to run the correlation. The user-provided fields must be of shape:

    (patch_height, patch_width, 2)
    

    Changed in version 2.0.5: provided fields can now be numpy arrays

  • alpha – Weight of the smoothness term in DISFlow, as a float.

  • delta – Weight of the color constancy term in DISFlow, as a float.

  • gamma – Weight of the gradient constancy term in DISFlow , as a float.

  • finest_scale – Finest level of the Gaussian pyramid on which the flow is computed in DISFlow (0 means full scale), as an int.

  • init – If True, the last field is used to initialize the calculation for the next one.

  • iterations – Maximum number of gradient descent iterations in the patch inverse search stage in DISFlow, as an int.

  • gradient_iterations

    Maximum number of gradient descent iterations in the patch inverse search stage in DISFlow, as an int.

    Changed in version 1.5.10: renamed from gditerations to gradient_iterations

  • patch_size – Size of an image patch for matching in DISFlow (in pixels).

  • patch_stride – Stride between neighbor patches in DISFlow. Must be less than patch size.

set_img0(img0: ndarray) None[source]

Sets the initial image to use for the correlation.

New in version 1.5.10.

set_box() None[source]

Sets the region of interest to use for the correlation, and initializes other attributes.

New in version 1.5.10.

Removed in version 2.0.0: box argument

get_data(img: ndarray, residuals: bool = False) List[float][source]

Processes the input image and returns the requested data in a list.

Parameters:
  • img – The new image to process.

  • residuals – Whether the residuals should be calculated or not for the image, as a bool.

Returns:

A list containing the data to calculate, and the residuals at the end if requested.

New in version 1.5.10.

DIS VE Tool

class crappy.tool.image_processing.DICVETool(patches: SpotsBoxes, method: str = 'Disflow', alpha: float = 3, delta: float = 1, gamma: float = 0, finest_scale: int = 1, iterations: int = 1, gradient_iterations: int = 10, patch_size: int = 8, patch_stride: int = 3, border: float = 0.2, safe: bool = True, follow: bool = True)[source]

This class is the core of the DICVE Block.

It tracks patches on images received from a Camera object, and computes a strain value at each new image.

It relies on cross-correlation algorithms to calculate the displacement. Different algorithms are available depending on the needs. This tool is mainly used to perform video-extensometry on speckled surfaces, although it could as well be of use for other applications.

New in version 1.4.0.

Changed in version 2.0.0: renamed from DISVE to DICVETool

__init__(patches: SpotsBoxes, method: str = 'Disflow', alpha: float = 3, delta: float = 1, gamma: float = 0, finest_scale: int = 1, iterations: int = 1, gradient_iterations: int = 10, patch_size: int = 8, patch_stride: int = 3, border: float = 0.2, safe: bool = True, follow: bool = True) None[source]

Sets a few attributes and initializes DISFlow if this method was selected.

Parameters:
  • patches – An instance of the SpotsBoxes class, containing the coordinates of the patches to track.

  • method

    The method to use to calculate the displacement. Disflow uses opencv’s DISOpticalFlow and Lucas Kanade uses opencv’s calcOpticalFlowPyrLK, while all other methods are based on a basic cross-correlation in the Fourier domain. Pixel precision calculates the displacement by getting the position of the maximum of the cross-correlation, and has thus a 1-pixel resolution. It is mainly meant for debugging. Parabola refines the result of Pixel precision by interpolating the neighborhood of the maximum, and has thus a sub-pixel resolution.

    New in version 1.5.9.

  • alpha – Weight of the smoothness term in DISFlow, as a float.

  • delta – Weight of the color constancy term in DISFlow, as a float.

  • gamma – Weight of the gradient constancy term in DISFlow , as a float.

  • finest_scale – Finest level of the Gaussian pyramid on which the flow is computed in DISFlow (0 means full scale), as an int.

  • iterations – Maximum number of gradient descent iterations in the patch inverse search stage in DISFlow, as an int.

  • gradient_iterations

    Maximum number of gradient descent iterations in the patch inverse search stage in DISFlow, as an int.

    Changed in version 1.5.9: renamed from gditerations to gradient_iterations

  • patch_size – Size of an image patch for matching in DISFlow (in pixels).

  • patch_stride – Stride between neighbor patches in DISFlow. Must be less than patch size.

  • border – Crop the patch on each side according to this value before calculating the displacements. 0 means no cropping, 1 means the entire patch is cropped.

  • safe – If True, checks whether the patches aren’t exiting the image, and raises an error if that’s the case.

  • follow – It True, the patches will move to follow the displacement of the image.

Removed in version 1.5.10: img0 and show_image arguments

set_img0(img0: ndarray) None[source]

Sets the reference image for the cross-correlation.

New in version 1.5.10.

calculate_displacement(img: ndarray) Tuple[List[Tuple[float, float]], float, float, List[Tuple[float, float]]][source]

Returns the displacement of every patch, calculated according to the chosen method.

Also updates the patch offsets if required, and updates the window for following the patches if any.

New in version 1.5.9.

Fields Tools

crappy.tool.image_processing.fields.get_field(field_string: str, h: int, w: int) Tuple[ndarray, ndarray][source]

Creates and returns the two fields on which the image will be projected, as numpy arrays.

This function is used by the DISCorrelTool and GPUCorrelTool tools.

Parameters:
  • field_string

    The str describing the field on which to project the image for correlation.

    Changed in version 1.5.10: renamed from s to field_string

  • h – The height of the image, as an int.

  • w – The width of the image, as an int.

New in version 1.4.0.

crappy.tool.image_processing.fields.get_res(ref: ndarray, img: ndarray, flow: ndarray) ndarray[source]

Calculates the difference between the original image and the one reconstructed from the current image and the calculated flow.

This function is used by the DISCorrelTool tool.

Parameters:
  • ref

    The reference image for calculating the optical flow.

    Changed in version 1.5.10: renamed from r to ref

  • img

    The current image for calculating the optical flow.

    Changed in version 1.5.10: renamed from a to img

  • flow

    The calculated optical flow

    Changed in version 1.5.10: renamed from b to flow

New in version 1.4.0.

GPU Correl Tool

class crappy.tool.image_processing.GPUCorrelTool(logger_name: str, context: Any | None = None, verbose: int = 0, levels: int = 5, resampling_factor: float = 2, kernel_file: str | Path | None = None, iterations: int = 4, fields: List[str | ndarray] | None = None, ref_img: ndarray | None = None, mask: ndarray | None = None, mul: float = 3)[source]

This class is the core of the GPUCorrel and GPUVE Blocks.

It receives images from a Camera, and performs GPU-accelerated image correlation on each received image. From this correlation, rigid body displacements or other fields are identified.

This class is meant to be efficient enough to run in real-time. It relies on the CorrelStage class (not documented) to perform correlation on different scales. It mainly takes a list of base fields and a reference image as inputs, and project the displacement between the current image and the reference one on the base of fields. The optimal fit is achieved by lowering the residuals with a least-squares method.

The projection on the base is performed sequentially, using the results obtained at stages with low resolution to initialize the computation on stages with higher resolution. A Newton method is used to converge towards an optimal solution.

New in version 1.4.0.

Changed in version 2.0.0: renamed from GPUCorrel to GPUCorrelTool

__init__(logger_name: str, context: Any | None = None, verbose: int = 0, levels: int = 5, resampling_factor: float = 2, kernel_file: str | Path | None = None, iterations: int = 4, fields: List[str | ndarray] | None = None, ref_img: ndarray | None = None, mask: ndarray | None = None, mul: float = 3) None[source]

Sets the args and a few parameters of pycuda.

Parameters:
  • logger_name

    The name of the parent Logger, to be used for setting the Logger of the class.

    New in version 2.0.0.

  • context

    Optionally, the pycuda context to use. If not specified, a new context is instantiated.

    New in version 1.5.10.

  • verbose – The verbose level as an integer, between 0 and 3. At level 0 no information is displayed, and at level 3 so much information is displayed that it slows the code down.

  • levels – Number of levels of the pyramid. More levels may help converging on images with large strain, but may fail on images that don’t contain low spatial frequency. Fewer levels mean that the program runs faster.

  • resampling_factor – The factor by which the resolution is divided between each stage of the pyramid. A low factor ensures coherence between the stages, but is more computationally intensive. A high factor allows reaching a finer detail level, but may lead to a coherence loss between the stages.

  • kernel_file – The path to the file containing the kernels to use for the correlation. Can be a pathlib.Path object or a str. If not provided, the default GPU Kernels are used.

  • iterations – The maximum number of iterations to run before returning the results. The results may be returned before if the residuals start increasing.

  • fields

    The base of fields to use for the projection, given as a list of str or numpy arrays (both types can be mixed). Strings are for using automatically-generated fields, the available ones are :

    'x', 'y', 'r', 'exx', 'eyy', 'exy', 'eyx', 'exy2', 'z'
    

    If users provide their own fields as arrays, they will be used as-is to run the correlation. The user-provided fields must be of shape:

    (patch_height, patch_width, 2)
    

    Changed in version 2.0.5: provided fields can now be numpy arrays

  • ref_img

    The reference image, as a 2D numpy.array with dtype float32. It can either be given at __init__(), or set later with set_orig().

    Changed in version 1.5.10: renamed from img to ref_img

  • mask – The mask used for weighting the region of interest on the image. It is generally used to prevent unexpected behavior on the border of the image.

  • mul – The scalar by which the direction will be multiplied before being added to the solution. If it’s too high, the convergence will be fast but there’s a risk to go past the solution and to diverge. If it’s too low, the convergence will be slower and require more iterations. 3 was found to be an acceptable value in most cases, but it is recommended to tune this value for each application so that the convergence is neither too slow nor too fast.

Changed in version 1.5.10: now explicitly listing the verbose, levels, resampling_factor, kernel_file, iterations, fields, mask and mul arguments

Removed in version 1.5.10: show_diff and img_size arguments

set_img_size(img_size: Tuple[int, int]) None[source]

Sets the image shape, and calls the methods that need this information for running.

set_orig(img: ndarray) None[source]

Sets the reference image, to which the following images will be compared.

prepare() None[source]

Prepares all the stages before starting the test.

get_disp(img_d: ndarray | None = None) Any[source]

To get the displacement.

This will perform the correlation routine on each stage, initializing with the previous values every time it will return the computed parameters as a list.

get_data_display() ndarray[source]

Returns the necessary data for displaying the difference between the reference and current image.

get_res(lvl: int = 0)[source]

Returns the last residual of the specified level.

static clean()[source]

Needs to be called at the end, to destroy the pycuda context properly.

GPU Kernels

The src/crappy/tool/image_processing/kernels.cu file contains the default kernels to use with pycuda. They’re used by the GPUCorrelTool if no other kernel file is provided.

Video Extenso Tool

class crappy.tool.image_processing.video_extenso.VideoExtensoTool(spots: SpotsBoxes, thresh: int, log_level: int | None, log_queue: Queue, white_spots: bool = False, update_thresh: bool = False, safe_mode: bool = False, border: int = 5, blur: int | None = 5)[source]

This class is the core of the VideoExtenso Block.

It performs spot tracking on up to 4 spots on the images acquired by the Camera, and computes the strain values at each new image. For each spot, the tracking is performed by an independent Tracker Process.

It is possible to track only one spot, in which case only the position of its center is returned and the strain values are left to 0.

New in version 1.4.0.

Changed in version 1.5.10: renamed from Video_extenso to VideoExtenso

Changed in version 2.0.0: renamed from VideoExtenso to VideoExtensoTool

__init__(spots: SpotsBoxes, thresh: int, log_level: int | None, log_queue: Queue, white_spots: bool = False, update_thresh: bool = False, safe_mode: bool = False, border: int = 5, blur: int | None = 5) None[source]

Sets the arguments and the other instance attributes.

Parameters:
  • spots

    An instance of the SpotsBoxes tool containing the coordinates of the spots to track.

    New in version 2.0.0.

  • thresh

    The grey level value of the threshold to use for discriminating spots from the background, as an :obj:int`. Passed to the Tracker and not used in this class.

    New in version 2.0.0.

  • log_level

    The minimum logging level of the entire Crappy script, as an int.

    New in version 2.0.0.

  • log_queue

    A multiprocessing.Queue for sending the log messages to the main Logger, only used in Windows.

    New in version 2.0.0.

  • white_spots – If True, detects white objects over a black background, else black objects over a white background. Passed to the Tracker and not used in this class.

  • update_thresh – If True, the grey level threshold for detecting the spots is re-calculated at each new image. Otherwise, the first calculated threshold is kept for the entire test. The spots are less likely to be lost with adaptive threshold, but the measurement will be more noisy. Adaptive threshold may also yield inconsistent results when spots are lost. Passed to the Tracker and not used in this class.

  • safe_mode – If True, the class will stop and raise an exception as soon as overlapping spots are detected. Otherwise, it will first try to reduce the detection window to get rid of overlapping. This argument should be used when inconsistency in the results may have critical consequences.

  • border – When searching for the new position of a spot, the class will search in the last known bounding box of this spot plus a few additional pixels in each direction. This argument sets the number of additional pixels to use. It should be greater than the expected “speed” of the spots, in pixels / frame. But if it’s set too high, noise or other spots might hinder the detection. Passed to the Tracker and not used in this class.

  • blur – The size in pixels (as an odd int greater than 1) of the kernel to use when applying a median blur filter to the image before the spot detection. If not given, no blurring is performed. A slight blur improves the spot detection by smoothening the noise, but also takes a bit more time compared to no blurring. Passed to the Tracker and not used in this class.

Removed in version 2.0.0: num_spots and min_area arguments

start_tracking() None[source]

Creates a Tracker Process for each detected spot, and starts it.

Also creates a multiprocessing.Pipe for each spot to communicate with the Tracker process.

stop_tracking() None[source]

Stops all the active Tracker Processes, either gently or by terminating them if they don’t stop by themselves.

get_data(img: ndarray) Tuple[List[Tuple[float, ...]], float, float] | None[source]

Takes an image as an input, performs spot detection on it, computes the strain from the newly detected spots, and returns the spot positions and strain values.

Parameters:

img – The image on which the spots should be detected.

Returns:

A list containing tuple with the coordinates of the centers of the detected spots, and the calculated x and y strain values.

Changed in version 1.5.10: renamed from get_def to get_data

Video Extenso Tracker

class crappy.tool.image_processing.video_extenso.tracker.Tracker(pipe: Connection, logger_name: str, log_level: int | None, log_queue: Queue, white_spots: bool = False, thresh: int | None = None, blur: float | None = 5)[source]

multiprocessing.Process whose task is to track a spot on an image.

It receives a subframe centered on the last known position of the spot, and returns the updated position of the detected spot. It is meant to be used in association with the VideoExtensoTool.

New in version 2.0.0.

__init__(pipe: Connection, logger_name: str, log_level: int | None, log_queue: Queue, white_spots: bool = False, thresh: int | None = None, blur: float | None = 5) None[source]

Sets the arguments.

Parameters:
  • pipe – The Connection object through which the image is received and the updated coordinates of the spot are sent back.

  • logger_name – The name of the parent Logger as a str, used for naming the Logger in this class.

  • log_level – The minimum logging level of the entire Crappy script, as an int.

  • log_queue – A multiprocessing.Queue for sending the log messages to the main Logger, only used in Windows.

  • white_spots – If True, detects white objects on a black background, else black objects on a white background.

  • thresh – If given, this threshold value will always be used for isolating the spot from the background. If not given (None), a new threshold is recalculated for each new subframe. Spots are less likely to be lost with an adaptive threshold, but it takes a bit more time.

  • blur – If not None, the subframe is first blurred before trying to detect the spot. This argument gives the size of the kernel to use for blurring. Better results are obtained with blurring, but it takes a bit more time.

run() None[source]

Continuously reads incoming subframes, tries to detect a spot and sends back the coordinates of the detected spot.

Can only be stopped either with a KeyboardInterrupt or when receiving a text message from the VideoExtensoTool.