Skip to content

senxor.proc

senxor.proc

Image processing utilities for Senxor devices.

process_senxor_data(bytes_data, *, adc=False)

Process the senxor bytes data to a frame.

normalize(image, in_range=None, out_range=None, dtype=np.float32)

Normalize image intensity to a desired range and data type using NumPy.

Supported dtypes:

  • np.floating
  • np.uint8
  • np.uint16
  • np.int16
  • np.int32

Parameters:

Name Type Description Default

image

ndarray

Input image.

required

in_range

tuple or None

Min and max intensity values of the input image. If None, the min and max of the input image are used. Default is None. Providing (min, max) is recommended, because this can avoid re-computation.

None

out_range

tuple or None

Min and max intensity values of the output image.

The function does not validate the out_range parameter if it is specified, be careful.

If None:

  • If dtype is specified as a floating-point type, (0.0, 1.0) is used.
  • If dtype is specified as an integer type, the min/max of dtype are used.
  • If dtype is None:
    • If image.dtype is a floating-point type, (0.0, 1.0) is used.
    • If image.dtype is an integer type, the min/max of image.dtype are used.

Default is None.

None

dtype

dtype or None

Desired output data type. If None, the input image's data type is used. Default is np.float32.

float32

Returns:

Type Description
ndarray

Normalized image with the specified range and data type.

Examples:

This function normalizes any image or numerical array, scaling its intensity values to a desired output range and data type.

  1. Normalizing a float array to an 8-bit image (0 to 255):
>>> data_float = np.array([[-0.5, 0.0, 0.5], [1.0, 1.5, 2.0]], dtype=np.float32)
>>> print(data_float)
    [[-0.5  0.   0.5]
    [ 1.   1.5  2. ]]
>>> normalized_uint8 = normalize(data_float, dtype=np.uint8)
>>> print(normalized_uint8)
    [[  0  64 127]
    [191 255 255]]
>>> print(normalized_uint8.dtype)
uint8
  1. Normalizing an 8-bit image to float (0.0 to 1.0):
>>> image_uint8 = np.array([[0, 100, 200], [50, 150, 255]], dtype=np.uint8)
>>> print(image_uint8)
    [[  0 100 200]
    [ 50 150 255]]
>>> normalized_float = normalize(image_uint8, dtype=np.float32)
>>> print(normalized_float)
    [[0.   0.39215686 0.78431373]
    [0.19607843 0.58823529 1.        ]]
>>> print(normalized_float.dtype)
float32
  1. If the min/max value of in_range is more/less than the min/max image intensity, then the intensity levels are clipped:
>>> image = np.array([51, 102, 153], dtype=np.float32)
>>> normalize(image, in_range=(0, 255))
array([0.2, 0.4, 0.6], dtype=float32)
Notes
  1. Avoiding re-computation: If you've already computed min/max, provide them via in_range to avoid re-computation.
  2. Preserving original contrast: To prevent stretching, set in_range to the original data's known intensity bounds or full dtype range.
  3. Maintaining precision: For multi-step processing, use floating-point types (np.float32/np.float64) for intermediate steps. Only normalize to np.uint8 as the very last step for display or saving.

enlarge(image, scale)

Enlarge an image by an integer scale factor using nearest neighbor (no interpolation).

Parameters:

Name Type Description Default

image

ndarray

Input image array (2D or 3D).

required

scale

int

Integer scale factor for enlargement (must be >= 1).

required

Returns:

Type Description
ndarray

Enlarged image array.

resample_lut(lut, n)

Resample a LUT to a new length.

Accepts (m, 3) or (m, 1, 3) uint8 arrays. Returns the same format with length n.

Parameters:

Name Type Description Default

lut

ndarray

Input LUT, shape (m, 3) or (m, 1, 3), dtype uint8.

required

n

int

Target length.

required

Returns:

Type Description
ndarray

Resampled LUT, same format as input, length n.

Raises:

Type Description
(TypeError, ValueError)

If input is not a valid LUT.

Examples:

>>> lut = np.array([[0, 0, 0], [255, 255, 255]], dtype=np.uint8)
>>> resample_lut(lut, 5).shape
(5, 3)

apply_colormap(image, lut, in_range=None, to_int=True, resample_size=256, norm=False)

Apply a colormap to a grayscale image using numpy. Return a uint8/float32 RGB image, depending on the to_int.

Parameters:

Name Type Description Default

image

ndarray

The image to apply the colormap to. Should be a 2D array.

required

lut

ndarray

The colormap to apply. Should be a 2D array of shape (N, 3) or (N, 1, 3).

required

in_range

tuple | None

The input range of the image. If None, the image's min/max are used. providing (min, max) is recommended, because this can avoid re-computation.

None

to_int

bool

If True, the color image will be converted to uint8 after applying the colormap. If False and image.dtype is not uint8, the color image will be normalized to float32.

True

resample_size

int

The colormap will be resampled to this size. For image formats with more detail, such as float32, increasing resample_size can help preserve more of the original image's fidelity. However, the actual effectiveness depends on the characteristics of the input image. Default is 256.

256

norm

bool

Whether to normalize the image before applying the colormap. Default is False.

False

Examples:

>>> image = np.array([[0, 100, 200], [50, 150, 255]], dtype=np.uint8)
>>> lut = get_colormaps("viridis", namespace="cv", n=256)
>>> color_image = apply_colormap(image, lut)
>>> print(color_image.dtype)
uint8
>>> image = np.array([[0, 100, 200], [50, 150, 255]], dtype=np.float32)
>>> lut = get_colormaps("viridis", namespace="cv", n=256)
>>> color_image = apply_colormap(image, lut, to_int=False)
>>> print(color_image.dtype)
float32

parse_header(header)

Parse the header of the senxor data.

Parameters:

Name Type Description Default

header

ndarray

The header of the senxor data. Must be a 1D numpy array of uint16.

required

Returns:

Name Type Description
SenxorHeader dataclass

Dataclass with the following attributes:

  • frame_counter: int, the frame counter value
  • vdd: float, the VDD(Voltage) value
  • die_temp: float, the die temperature value in °C
  • timestamp: int, the timestamp value
  • maxVal: float, the maximum temperature value in °C
  • minVal: float, the minimum temperature value in °C
  • crc: int, the CRC(Cyclic Redundancy Check) value

Examples:

>>> header, frame = dev.read()
>>> if header is not None:
>>>     parsed_header = parse_header(header)
>>>     print(parsed_header.frame_counter)
32