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 likeVideoExtenso
orDICVE
.This class is a child of
tkinter.Tk
. It relies on theZoom
andHistogramProcess
tools. It also interacts with instances of theCameraSetting
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 mainLogger
, 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 theCamera
Block.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 theBox
andSpotsBoxes
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 mainLogger
, 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 theCamera
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 theDISCorrel
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 mainLogger
, 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 theCamera
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
andSpotsBoxes
tools. It is meant to be used for configuring theDICVE
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 mainLogger
, 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 theCamera
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
andSpotsDetector
tools. It is meant to be used for configuring theVideoExtenso
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 acquiringimages. (the) –
log_queue –
A
multiprocessing.Queue
for sending the log messages to the mainLogger
, 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 theCamera
Block.New in version 2.0.0.
detector –
An instance of
SpotsDetector
used for detecting spots on the images received from theCamera
.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 orDisplayer
Process of aCamera
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.
- 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.
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 amultiprocessing.Pipe
, and returning the histogram of that image in anotherPipe
.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 theProcess
when to stop running.processing_event – An
multiprocessing.Event
set by themultiprocessing.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 mainLogger
, 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.
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 aCamera
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.
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 forVideoExtenso
or the patches forDICVE
.It can also instantiate the Box objects by parsing a list of tuples containing enough information.
New in version 2.0.0.
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 thedetect_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 theVideoExtensoTool
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. IfFalse
, detects black spots over a white background. Also passed to theVideoExtensoTool
.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 toNone
, 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 toNone
, in which case no median blur filter is applied before detecting the spots. Also passed to theVideoExtensoTool
.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 theVideoExtensoTool
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 theVideoExtensoTool
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.
- 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.
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
andspidev
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
toTrue
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.
- write_byte(i2c_addr: int, value: int) None [source]
Writes a single byte to an I2C slave, in register 0.
- write_byte_data(i2c_addr: int, register: int, value: int) None [source]
Writes a single byte to an I2C slave, in the specified register.
- 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.
- write_block_data(i2c_addr: int, register: int, data: list) None [source]
Actually calls
write_i2c_block_data()
.
- 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.
- 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.
- 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.
- 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.
- 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 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.
- writebytes(values: list, start: bool = True, stop: bool = True) None [source]
Write bytes from a list to an SPI slave.
- 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
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 aUSBServer
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
andspidev
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 theUSBServer
, as anint
.Changed in version 2.0.0: renamed from block_number to block_index
current_block –
The handle to a shared
multiprocessing.Value
indicating whichBlock
can currently communicate with theUSBServer
.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 thisBlock
only, for signaling theUSBServer
when the command has been written in the command_file.shared_lock –
A
multiprocessing.Lock
common to all theBlock
that allows the one Block holding it to communicate with theUSBServer
.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
toTrue
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.
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 theMPRLS
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.
- classmethod read(address: int, length: int) I2CMessage [source]
Instantiates an
I2CMessage
object for reading bytes.
- classmethod write(address: int, buf: list) I2CMessage [source]
Instantiates an
I2CMessage
object for writing bytes.
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 multipleBlock
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 theBlock
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 whichBlock
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 mainLogger
, 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 toFT232HServer
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:
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
ofstr
ornumpy
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
andGPUCorrelTool
tools.- Parameters:
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
andGPUVE
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 astr
. 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
ofstr
ornumpy
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 withset_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.
- 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.
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 independentTracker
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 mainLogger
, 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 theTracker
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 theTracker
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 theTracker
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
containingtuple
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 astr
, 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 mainLogger
, 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 theVideoExtensoTool
.