Skip to content
⚡ Developer documentation for INFINICAM, the real-time high-speed camera (UC-1.1 / GbE-2)

torchvision Tensor Conversion & Preprocessing (GbE-2 / Python)

Steps for creating a program that uses the common module puclib.py created in HelloWorld to convert image data read from the GbE-2 into a PyTorch Tensor, and apply preprocessing (resizing, smoothing, tensor normalization) for input into a deep-learning model using torchvision.transforms.

  1. Create the script

    In the same folder as puclib.py, create gbe2_torchvision_single_process.py and write the following code.

    gbe2_torchvision_single_process.py
    from ctypes import c_uint32, c_ushort, c_ubyte, c_void_p, byref
    import numpy as np
    import torch
    import torchvision.transforms as T
    from torchvision.utils import save_image
    # Import from the common module puclib.py
    from puclib import (
    load_sdk, PUC_SUCCEEDED, PUC_DETECT_TARGET_GBE2,
    PUC_Q_COUNT, PUC_DETECT_FILTER, PUC_DETECT_INFO, PUC_XFER_DATA_INFO
    )
    def main():
    print("Starting INFINICAM GbE-2 torchvision tensor-conversion processing...")
    # 1. Load and initialize the SDK
    puclib = load_sdk()
    if puclib.PUC_Initialize() != PUC_SUCCEEDED:
    print("Error: Failed to initialize the SDK.")
    return
    # 2. Search for and open the device
    detect_filter = PUC_DETECT_FILTER(nDeviceTypeFlags=PUC_DETECT_TARGET_GBE2)
    detect_info = PUC_DETECT_INFO()
    if puclib.PUC_DetectDevice2(byref(detect_filter), byref(detect_info)) != PUC_SUCCEEDED or detect_info.nDeviceCount == 0:
    print("Error: No GbE-2 camera was found.")
    return
    h_device = c_void_p()
    if puclib.PUC_OpenDevice2(0, byref(h_device)) != PUC_SUCCEEDED:
    print("Error: Failed to open the device.")
    return
    # 3. Retrieve the resolution, quantization table, and transfer size
    width, height = c_uint32(), c_uint32()
    puclib.PUC_GetResolution(h_device, byref(width), byref(height))
    w, h = width.value, height.value
    q_vals = (c_ushort * PUC_Q_COUNT)()
    puclib.PUC_GetQuantization2(h_device, q_vals)
    xfer_data_size = c_uint32()
    puclib.PUC_GetXferDataSize(h_device, byref(xfer_data_size))
    print(f"Resolution: {w} x {h} pixels")
    # 4. Allocate buffers
    comp_buffer = (c_ubyte * xfer_data_size.value)()
    line_bytes = (w + 3) & ~3 # 4-byte boundary alignment
    decoded_buffer = (c_ubyte * (line_bytes * h))()
    # 5. Perform the single-frame capture
    xfer_info = PUC_XFER_DATA_INFO()
    xfer_info.pData = comp_buffer
    xfer_info.nDataSize = xfer_data_size.value
    print("Capturing one frame...")
    if puclib.PUC_GetSingleXferData(h_device, byref(xfer_info)) == PUC_SUCCEEDED:
    # 6. Decode processing
    ret = puclib.PUC_DecodeData(
    decoded_buffer, 0, 0, w, h, line_bytes, comp_buffer, q_vals
    )
    if ret == PUC_SUCCEEDED:
    # 7. Convert into a NumPy array
    img_np = np.ctypeslib.as_array(decoded_buffer).reshape((h, line_bytes))[:, :w]
    # 8. Convert into a PyTorch Tensor, normalized to [0.0, 1.0] & reshaped to (1, H, W)
    tensor_img = torch.from_numpy(img_np).float().unsqueeze(0) / 255.0
    print(f"Tensor shape before conversion: {list(tensor_img.shape)} (Channels x Height x Width)")
    # 9. Define the torchvision pipeline (resize to 224x224 + noise suppression)
    transform_pipeline = T.Compose([
    T.Resize((224, 224), antialias=True),
    T.GaussianBlur(kernel_size=(5, 5), sigma=(1.0, 2.0))
    ])
    # Apply the preprocessing
    processed_tensor = transform_pipeline(tensor_img)
    print(f"Tensor shape after preprocessing: {list(processed_tensor.shape)}")
    # 10. Save the resulting Tensor as an image file
    filename = "torchvision_processed_result.png"
    save_image(processed_tensor, filename)
    print(f"SUCCESS: Saved the processed Tensor as an image ({filename})")
    else:
    print(f"Error: Failed to decode the image data. ErrorCode: {ret}")
    else:
    print("Error: Failed to retrieve the image data.")
    # 11. Close
    puclib.PUC_CloseDevice(h_device)
    if __name__ == "__main__":
    main()
  2. Run the script

    Terminal window
    python gbe2_torchvision_single_process.py

    After execution finishes, torchvision_processed_result.png, preprocessed from the input size into the size used by AI inference models (224x224), is generated.


PyTorch / torchvision Integration Highlights

Section titled “PyTorch / torchvision Integration Highlights”

1. Zero-copy tensor conversion (torch.from_numpy)

Section titled “1. Zero-copy tensor conversion (torch.from_numpy)”

Using torch.from_numpy(), the memory region of the NumPy array decoded by the SDK can be cast into a torch.Tensor at high speed, without reallocating memory.

tensor_img = torch.from_numpy(img_np).float().unsqueeze(0) / 255.0
  • .unsqueeze(0): Expands the 2D tensor of (Height, Width) into the 3D (Channels, Height, Width) format conventionally used by torchvision.
  • / 255.0: Normalizes 8-bit integer data (0 to 255) into floating-point values (0.0 to 1.0) commonly used in machine learning.

2. Unifying the data pipeline (torchvision.transforms.Compose)

Section titled “2. Unifying the data pipeline (torchvision.transforms.Compose)”

By chaining the resizing, cropping, and convolution steps required for model input into a single pipeline with T.Compose, the camera image can be converted into inference-ready dataset format the moment it is captured.