Tools

Camera configuration

class crappy.tool.cameraConfig.Camera_config(camera)[source]

Class creating a graphical interface to configure a camera.

Note

It will launch create_window() when instanciated. Just call:

>>> import crappy
>>> camera = crappy.camera.Fake_camera()
>>> crappy.tool.Camera_config(camera)

It takes a single arg: the camera class (it must inherit from crappy.camera.Camera).

apply_settings() None[source]

Callback for the apply button.

As its name suggests, it will apply all the edited settings.

convert_img() None[source]

Converts the image to uint if necessary, then to a PhotoImage.

make_new_window(ey: float, ex: float) None[source]

Hang on, it is not that complicated: given the location of the zoom event this will compute the new zoom window.

It is represented by 4 floats between 0 and 1 miny, minx, maxy, maxx, default is 0, 0, 1, 1.

move(event) None[source]

Moving the image when dragging it with the mouse.

move_window(y: int, x: int) None[source]

Given the movement of the mouse, it will recompute the zoom_window.

on_resize() None[source]

Recomputes the new shape of the resized image.

resized() bool[source]

Returns True if window has been resized and saves the new coordinates

start_move(event) None[source]

To save the coordinates before actually moving.

zoom(event) None[source]

For windows, only one type of wheel event.

zoom_in(event) None[source]

Called when scrolling in.

zoom_out(event) None[source]

Called when scrolling out.

class crappy.tool.cameraConfig.Hist_generator(pipe: multiprocessing.connection.Connection)[source]

Process to generate the histogram of images.

Note

It only takes a Pipe at __init__(), all the data will be transferred through it. See run() for more info.

run() None[source]

Expects a tuple of 3 args through the pipe:

  • out_size (tuple): The dimensions of the output histogram image.

  • hist_range (tuple, e.g.: (0,256) for full scale uint8): The lower and upper value of the histogram.

  • img: A numpy array with the image. If not single channel, it will be converted to a single channel.

Comedi Bind

More documentation coming soon !

class crappy.tool.comedi_bind.comedi_range[source]
class crappy.tool.comedi_bind.comedi_t[source]

Discorrel tool

More documentation coming soon !

Discorrel configuration

More documentation coming soon !

class crappy.tool.discorrelConfig.DISConfig(camera)[source]

Disve tool

More documentation coming soon !

Fields

More documentation coming soon !

crappy.tool.fields.remap(a: numpy.ndarray, r: numpy.ndarray) numpy.ndarray[source]

Remaps a using given r the displacement as a result from correlation.

FT232H

class crappy.tool.ft232h.Find_serial_number(serial_number: str)[source]

A class used for finding USB devices matching a given serial number, using the usb.core.find method.

class crappy.tool.ft232h.ft232h(mode: str, serial_nr: Optional[str] = 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.

class BitMode(value)[source]

Commands for changing the bit mode.

__init__(mode: str, serial_nr: Optional[str] = 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 (str) –

    The communication mode, 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 (str, optional) – The serial number of the FT232H to drive. In Write_serial_nr mode, the serial number to be written.

  • i2c_speed (str, optional) –

    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 (str, optional) – Increases the achievable bus speed, 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.

property bits_per_word: int

Number of bits per SPI words.

Can only be set to 8.

close() None[source]

Closes the FTDI interface/port.

property cshigh: bool

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

get_gpio(gpio_str: str) int[source]

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

Parameters

gpio_str (str) – Name of the GPIO to be read

Returns

3.3V-logic value corresponding to the input voltage

i2c_rdwr(*i2c_msgs) 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 – Messages to exchange with the slave. They are either read or write messages.

property loop: bool

If True, the loopback mode is enabled.

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 no_cs: bool

If True, the CS line is not driven.

read_byte(i2c_addr: int) int[source]

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

Parameters

i2c_addr (int) – I2C address of the slave

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 (int) – I2C address of the slave

  • register (int) – Index of the register to be read

Returns

Value of the read register

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

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

Parameters
  • i2c_addr (int) – I2C address of the slave

  • register (int) – Index of the first register to be read

  • length (int) – Number of bytes to read

Returns

Values of read registers as a list

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 (int) – I2C address of the slave

  • register (int) – Index of the first register to be read

Returns

Value of the read registers

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

Reads the specified number of bytes from an SPI slave.

Parameters
  • len (int) – Number of bytes to read

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

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

Returns

List of read bytes

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

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

Parameters
  • gpio_str (str) – Name of the GPIO to be set

  • value (int) – 1 for setting the GPIO high, 0 for setting it low

property threewire: bool

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

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

Actually calls write_i2c_block_data().

Parameters
  • i2c_addr (int) – I2C address of the slave

  • register (int) – Index of the first register to be written

  • data (list) – List of bytes to write

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

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

Parameters
  • i2c_addr (int) – I2C address of the slave

  • value (int) – The value to write

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 (int) – I2C address of the slave

  • register (int) – Index of the register to be written

  • value (int) – The value 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 (int) – I2C address of the slave

  • register (int) – Index of the first register to be written

  • data (list) – List of bytes to write

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 (int) – I2C address of the slave

  • register (int) – Index of the first register to be written

  • value (int) – The value to write

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

Write bytes from a list to an SPI slave.

Parameters
  • values (list) – List of bytes to write

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

  • stop (bool) – 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: Optional[float] = None, delay: float = 0.0, bits: int = 8, start: bool = True, stop: bool = True) list[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 (list) – List of bytes to write

  • speed (float) – Sets the bus clock frequency before issuing the command (in Hz)

  • delay (float) – Not implemented, should be 0.0

  • bits (int) – Not implemented, should be 8

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

  • stop (bool) – 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[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[source]

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

crappy.tool.ft232h.ft232h_i2c_timings

alias of crappy.tool.ft232h.I2CTimings

class crappy.tool.ft232h.ft232h_server(mode: str, block_number: int, queue: multiprocessing.context.BaseContext.Queue, namespace: multiprocessing.managers.Namespace, command_event: multiprocessing.context.BaseContext.Event, answer_event: multiprocessing.context.BaseContext.Event, next_block: multiprocessing.context.BaseContext.Event, done_event: multiprocessing.context.BaseContext.Event, serial_nr: Optional[str] = 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 USB server managing communication with the different FT232H devices.

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.

class BitMode(value)[source]

Commands for changing the bit mode.

__init__(mode: str, block_number: int, queue: multiprocessing.context.BaseContext.Queue, namespace: multiprocessing.managers.Namespace, command_event: multiprocessing.context.BaseContext.Event, answer_event: multiprocessing.context.BaseContext.Event, next_block: multiprocessing.context.BaseContext.Event, done_event: multiprocessing.context.BaseContext.Event, serial_nr: Optional[str] = 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 (str) –

    The communication mode, 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_number (int) – The blocks number that was assigned to this instance of the class at the first contact with the USB server.

  • queue (multiprocessing.Queue) – The queue in which the class will put its block number so that the USB server knows it is requesting control.

  • namespace (multiprocessing.managers.Namespace) – The Namespace object used by the USB server for receiving commands ans sending answers.

  • command_event (multiprocessing.Event) – An event object used by the USB server to know when a new command was written by a block.

  • answer_event (multiprocessing.Event) – An event object used by this class to know when the USB server sent back an answer.

  • next_block (multiprocessing.Event) – An event object, set by the USB server to tell the blocks waiting for the control that now is maybe their chance.

  • done_event (multiprocessing.Event) – An event object set by the block currently in control of the server to tell it that it is done sending commands.

  • serial_nr (str, optional) – The serial number of the FT232H to drive. In Write_serial_nr mode, the serial number to be written.

  • i2c_speed (str, optional) –

    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 (str, optional) – Increases the achievable bus speed, 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.

property bits_per_word: int

Number of bits per SPI words.

Can only be set to 8.

close() None[source]

Closes the FTDI interface/port.

property cshigh: bool

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

get_gpio(gpio_str: str) int[source]

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

Parameters

gpio_str (str) – Name of the GPIO to be read

Returns

3.3V-logic value corresponding to the input voltage

i2c_rdwr(*i2c_msgs) 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 – Messages to exchange with the slave. They are either read or write messages.

property loop: bool

If True, the loopback mode is enabled.

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 no_cs: bool

If True, the CS line is not driven.

read_byte(i2c_addr: int) int[source]

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

Parameters

i2c_addr (int) – I2C address of the slave

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 (int) – I2C address of the slave

  • register (int) – Index of the register to be read

Returns

Value of the read register

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

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

Parameters
  • i2c_addr (int) – I2C address of the slave

  • register (int) – Index of the first register to be read

  • length (int) – Number of bytes to read

Returns

Values of read registers as a list

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 (int) – I2C address of the slave

  • register (int) – Index of the first register to be read

Returns

Value of the read registers

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

Reads the specified number of bytes from an SPI slave.

Parameters
  • len (int) – Number of bytes to read

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

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

Returns

List of read bytes

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

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

Parameters
  • gpio_str (str) – Name of the GPIO to be set

  • value (int) – 1 for setting the GPIO high, 0 for setting it low

property threewire: bool

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

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

Actually calls write_i2c_block_data().

Parameters
  • i2c_addr (int) – I2C address of the slave

  • register (int) – Index of the first register to be written

  • data (list) – List of bytes to write

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

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

Parameters
  • i2c_addr (int) – I2C address of the slave

  • value (int) – The value to write

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 (int) – I2C address of the slave

  • register (int) – Index of the register to be written

  • value (int) – The value 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 (int) – I2C address of the slave

  • register (int) – Index of the first register to be written

  • data (list) – List of bytes to write

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 (int) – I2C address of the slave

  • register (int) – Index of the first register to be written

  • value (int) – The value to write

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

Write bytes from a list to an SPI slave.

Parameters
  • values (list) – List of bytes to write

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

  • stop (bool) – 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: Optional[float] = None, delay: float = 0.0, bits: int = 8, start: bool = True, stop: bool = True) list[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 (list) – List of bytes to write

  • speed (float) – Sets the bus clock frequency before issuing the command (in Hz)

  • delay (float) – Not implemented, should be 0.0

  • bits (int) – Not implemented, should be 8

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

  • stop (bool) – 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[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[source]

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

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

Class that mimics the i2c_msg class of the smbus2 module.

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

Simply sets the attributes of the class, that characterise the i2c message.

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

  • address (int) – The address of the I2C slave.

  • length (int, optional) – For a read message, the number of bytes to read.

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

property addr: int

The address of the I2C slave.

property buf: list

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

property len: int

The number of bytes to read.

classmethod read(address: int, length: int) collections.abc.Iterable[source]

Instantiates an i2c_msg_ft232h object for reading bytes.

Parameters
  • address (int) – The address of the I2C slave.

  • length (int) – The number of bytes to read.

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

Instantiates an i2c_msg_ft232h object for writing bytes.

Parameters
  • address (int) – The address of the I2C slave.

  • buf (list) – The list of bytes to be written.

GPU Correl

class crappy.tool.gpucorrel.CorrelStage(img_size: tuple, **kwargs)[source]

Run a correlation routine on an image, at a given resolution.

Note

Multiple instances of this class are used for the pyramidal correlation in Correl().

Can but is not meant to be used as is.

debug(n: int, *s: Any) None[source]

To print debug messages.

Note

First argument is the level of the message.

The others arguments will be displayed only if the self.debug var is superior or equal.

Also, flag and indentation reflect respectively the origin and the level of the message.

get_disp(img_d=None)[source]

The method that actually computes the weight of the fields.

prepare() None[source]

Computes all necessary tables to perform correlation.

Note

This method must be called everytime the original image or fields are set.

If not done by the user, it will be done automatically when needed.

resample_d(new_y: int, new_x: int)[source]

Resamples tex_d and returns it in a gpuarray.

resample_orig(new_y: int, new_x: int, dev_out) None[source]

To resample the original image.

Note

Reads orig.texture and writes the interpolated newX*newY image to the devOut array.

set_fields(fields_x, fields_y) None[source]

Method to give the fields to identify with the routine.

Note

This is necessary only once and can be done multiple times, but the routine have to be initialized with prepare(), causing a slight overhead.

Takes a tuple or list of 2 (gpu)arrays[Nfields,x,y] (one for displacement along x and one along y).

set_image(img_d) None[source]

Set the image to compare with the original.

Note

Calling this method is not necessary: you can do .get_disp(image). This will automatically call this method first.

set_orig(img)[source]

To set the original image from a given CPU or GPU array.

Warning

If it is a GPU array, it will NOT be copied.

Note

The most efficient method is to write directly over self.devOrig with some kernel and then run update_orig().

update_orig() None[source]

Needs to be called after self.img_d has been written directly.

class crappy.tool.gpucorrel.GPUCorrel(img_size: tuple, **kwargs)[source]

Identify the displacement between two images.

This class is the core of the Correl block. It is meant to be efficient enough to run in real-time.

It relies on CorrelStage to perform correlation on different scales.

Requirements

  • The computer must have a Nvidia video card with compute capability >= 3.0

  • CUDA 5.0 or higher (only tested with CUDA 7.5)

  • pycuda 2014.1 or higher (only tested with pycuda 2016.1.1)

Presentation

This class takes a list of fields. These fields will be the base of deformation in which the displacement will be identified. When given two images, it will identify the displacement between the original and the second image in this base as closely as possible lowering square-residual using provided displacements.

This class is highly flexible and performs on GPU for faster operation.

Usage

At initialization, Correl needs only one unnamed argument: the working resolution (as a tuple of int), which is the resolution of the images it will be given. All the images must have exactly these dimensions. The dimensions must be given in this order: (y,x) (like openCV images)

At initialization or after, this class takes a reference image. The deformations on this image are supposed to be all equal to 0.

It also needs a number of deformation fields (technically limited to ~500 fields, probably much less depending on the resolution and the amount of memory on the graphics card).

Finally, you need to provide the deformed image you want to process. It will then identify parameters of the sum of fields that lowers the square sum of differences between the original image and the second one displaced with the resulting field.

This class will resample the images and perform identification on a lower resolution, use the result to initialize the next stage, and again util it reaches the last stage. It will then return the computed parameters. The number of levels can be set with levels=x.

The latest parameters returned (if any) are used to initialize computation when called again, to help identify large displacement. It is particularly adapted to slow deformations.

To lower the residual, this program computes the gradient of each parameter and uses Newton method to converge as fast as possible. The number of iterations for the resolution can also be set.

Parameters
  • img_size (tuple) – tuple of 2 int, (y,x), the working resolution

  • verbose (int) –

    Use verbose=x to choose the amount of information printed to the console:

    • 0: Nothing except for errors

    • 1: Only important info and warnings

    • 2: Major info and a few values periodically (at a bearable rate)

    • 3: Tons of info including details of each iteration

    Note that verbose=3 REALLY slows the program down. To be used only for debug.

  • fields (list) –

    Use fields=[...] to set the fields. This can be done later with set_fields(), however in case when the fields are set later, you need to add Nfields=x to specify at __init__() the number of expected fields in order to allocate all the necessary memory on the device.

    The fields should be given as a list of tuple of 2 numpy.ndarrays or gpuarray.GPUArray of the size of the image, each array corresponds to the displacement in pixel along respectively X and Y.

    You can also use a str instead of the tuple for the common fields:

    • Rigid body and linear deformations:

      • ’x’: Movement along X

      • ’y’: Movement along Y

      • ’r’: Rotation (in the trigonometric direction)

      • ’exx’: Stretch along X

      • ’eyy’: Stretch along Y

      • ’exy’: Shear

      • ’z’: Zoom (dilatation) (=exx+eyy)

      Note that you should not try to identify exx, eyy AND z at the same time (one of them is redundant).

    • Quadratic deformations:

      These fields are more complicated to interpret but can be useful for complicated solicitations such as biaxial stretch. U and V represent the displacement along respectively x and y.

      • ’uxx’: U(x,y) = x²

      • ’uyy’: U(x,y) = y²

      • ’uxy’: U(x,y) = xy

      • ’vxx’: V(x,y) = x²

      • ’vyy’: V(x,y) = y²

      • ’vxy’: V(x,y) = xy

    All of these default fields are normalized to have a max displacement of 1 pixel and are centered in the middle of the image. They are generated to have the size of your image.

    You can mix strings and tuples at your convenience to perform your identification.

    Example

    fields=['x', 'y', (MyFieldX, MyFieldY)]
    

    where MyfieldX and MyfieldY are numpy arrays with the same shape as the images

    Example of memory usage: On a 2048x2048 image, count roughly 180 + 100*Nfields MB of VRAM

  • img

    The original image. It must be given as a 2D numpy.ndarray. This block works with dtype=np.float32. If the dtype of the given image is different, it will print a warning and the image will be converted. It can be given at __init__() with the kwarg img=MyImage or later with set_orig(MyImage).

    Note

    You can reset it whenever you want, even multiple times but it will reset the def parameters to 0.

    Once fields and original image are set, there is a short preparation time before correlation can be performed. You can do this preparation yourself by using prepare(). If not called, it will be done automatically when necessary, inducing a slight overhead at the first call of get_disp() after setting/updating the fields or original image.

  • levels (int, optional) – Number of levels of the pyramid. More levels can help converging with large and quick deformations but may fail on images without low spatial frequency. Fewer levels mean that the program will run faster.

  • resampling_factor (float, optional) – The resolution will be divided by this parameter between each stage of the pyramid. Low, can allow coherence between stages but is more expensive. High, reaches small resolutions in less levels and is faster but be careful not to loose consistency between stages.

  • iterations (int, optional) – The MAXIMUM number of iteration to be ran before returning the values. Note that if the residual increases before reaching x iterations, the block will return anyway.

  • mask (optional) – To set the mask, to weight the zone of interest on the images. It is particularly useful to prevent undesired effects on the border of the images. If no mask is given, a rectangular mask will be used, with border of 5% the size of the image.

  • show_diff (bool, optional) – Will open a cv2 window and print the difference between the original and the displaced image after correlation. 128 Gray means no difference, lighter means positive and darker negative.

  • kernel_file (str, optional) – Where crappy_install_dir is the root directory of the installation of crappy (crappy.__path__).

  • mul (float, optional) –

    This parameter is critical. The direction will be multiplied by this scalar before being added to the solution. It defines how “fast” we move towards the solution. High value, fast convergence but risk to go past the solution and diverge (the program does not try to handle this and if the residual rises, iterations will stop immediately). Low value, probably more precise but slower and may require more iterations.

    After multiple tests, 3 was found to be a pretty acceptable value. Don’t hesitate to adapt it to your case. Use verbose=3 and see if the convergence is too slow or too fast.

Note

The compared image can be given directly when querying the displacement as a parameter to get_disp() or before, with set_image(). You can provide it as a np.ndarray just like orig, or as a pycuda.gpuarray.GPUArray.

static clean()[source]

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

debug(n: int, *s: Any) None[source]

To print debug info.

First argument is the level of the message. It wil be displayed only if the self.debug is superior or equal.

get_disp(img_d=None)[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_fields(y: Optional[int] = None, x: Optional[int] = None) tuple[source]

Returns the fields, resampled to size (y,x).

get_res(lvl: int = 0)[source]

Returns the last residual of the specified level (0 by default).

Usually, the correlation is correct when res < ~1e9-10 but it really depends on the images: you need to find the value that suit your own images, depending on the resolution, contrast, correlation method etc… You can use write_diff_file() to visualize the difference between the two images after correlation.

set_orig(img) None[source]

To set the original image.

This is the reference with which the second image will be compared.

write_diff_file(level: int = 0)[source]

To see the difference between the two images with the computed parameters.

It writes a single channel picture named “diff.png” where 128 gray is exact equality, lighter pixels show positive difference and darker pixels a negative difference. Useful to see if correlation succeeded and to identify the origin of non convergence.

crappy.tool.gpucorrel.interp_nearest(ary: numpy.ndarray, ny: int, nx: int) numpy.ndarray[source]

Used to interpolate the mask for each stage.

Py SPCM

More documentation coming soon !

exception crappy.tool.pyspcm.SpectrumError[source]

USB server

class crappy.tool.usb_server.Usb_server(serial_nr: str, backend: str)[source]

Class for starting a server controlling communication with the FT232H devices.

The In / Out objects wishing to communicate through an FT232H inherit from this class.

__del__() None[source]

Stops the server upon deletion of the In / Out object.

__init__(serial_nr: str, backend: str) None[source]

Simply receives the attributes from the In / Out object.

Parameters
  • serial_nr (int) – The serial number of the FT232H to use.

  • backend (str) – The server won’t be started if the chosen backend is not 'ft232h'.

start_server() tuple[source]

Starts the server for communicating with the FT232H devices.

If the server is already started, doesn’t start it twice. Then initializes the connection with the server and receives a block number.

Returns

The different multiprocessing objects needed as arguments by the FT232H in order to run properly.

Video extenso

exception crappy.tool.videoextenso.LostSpotError[source]
class crappy.tool.videoextenso.Tracker(pipe: multiprocessing.connection.Connection, white_spots: bool = False, thresh: str = 'auto', safe_mode: bool = True, blur: float = 0)[source]

Process tracking a spot for videoextensometry.

fallback(img: numpy.ndarray) Union[dict, int][source]

Called when the spots are lost.

run() None[source]

Method to be run in sub-process; can be overridden in sub-class

class crappy.tool.videoextenso.Video_extenso(white_spots: bool = False, update_thresh: bool = False, num_spots: Union[str, int] = 'auto', safe_mode: bool = False, border: int = 5, min_area: float = 150, blur: float = 5)[source]

The basic VideoExtenso class.

It will detect the spots, save the initial position, and return the measured deformation in the most simple way:

  • It will always return a list of the spots coordinates (in pixel).

  • It will return Exx, Eyy, projections of the length of the bounding box of the spot on each axis, divided by its original length.

Note

Can detect 2,3 or 4 spots.

__init__(white_spots: bool = False, update_thresh: bool = False, num_spots: Union[str, int] = 'auto', safe_mode: bool = False, border: int = 5, min_area: float = 150, blur: float = 5) None[source]

Sets the arguments.

Parameters
  • white_spots – Set to True if the spots are lighter than the surroundings, else set to False.

  • update_thresh – Should the threshold be updated in each round ? If so there are lower chances to lose the spots but there will be more noise in the measurement.

  • num_spots

    The number of spots to detect. Helps for spot detection and allows to force detection of a given number of spots (“auto” works fine most of the time). Can be set to:

    "auto", 2, 3, 4
    

  • safe_mode – If set to False, it will try hard to catch the spots when losing them. Could result in incoherent values without crash. Set to True when security is a concern.

  • border – The number of pixels that will be added to the limits of the boundingbox.

  • min_area – Filters regions with an area smaller than this value among the selected regions.

  • blur – Median blur to be added to the image to smooth out irregularities and make detection more reliable.

detect_spots(img: numpy.ndarray, oy: int, ox: int) None[source]

Detects the spots in img, subframe of the full image.

Note

ox and oy represent the offset of the subframe in the full image.

enlarged_window(window: tuple, shape: tuple) tuple[source]

Returns the slices to get the window around the spot.

get_def(img: numpy.ndarray) list[source]

The “heart” of the videoextenso.

Will keep track of the spots and return the computed deformation.

start_tracking() None[source]

Will spawn a process per spot, which goal is to track the spot and send the new coordinate after each update.

crappy.tool.videoextenso.overlapping(box1: numpy.ndarray, box2: numpy.ndarray) bool[source]

Returns True if box1 and box2 are overlapping or included in each other

Video extenso configuration

More documentation coming soon !

class crappy.tool.videoextensoConfig.VE_config(camera, ve)[source]