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

SingleImage + ROI Decode

These are the steps to create a program that captures one frame of compressed data from a GbE-2 and, without using a callback function, decodes only a specified region (ROI: Region of Interest), saving it in the PGM format (Portable Graymap).

  1. Write the source code

    Open the main file (e.g. GbE2_SingleImage_ROI.cpp) and replace its contents with the following code.

    #include <stdio.h>
    #include <stdlib.h>
    #include <PUCLIB.h> // Load the PUCLIB header
    int main() {
    printf("Starting INFINICAM GbE-2 ROI decode processing...\n");
    // 1. Initialize the SDK
    PUCRESULT ret = PUC_Initialize();
    if (ret != PUC_SUCCEEDED) {
    printf("Error: Failed to initialize the SDK. ErrorCode: %d\n", ret);
    return EXIT_FAILURE;
    }
    // 2. Search for a GbE-2 device on the network
    PUC_DETECT_FILTER filter = { 0 };
    filter.nDeviceTypeFlags = PUC_DETECT_TARGET_GBE2; // Specify GbE-2
    PUC_DETECT_INFO detectInfo = { 0 };
    ret = PUC_DetectDevice2(&filter, &detectInfo);
    if (ret != PUC_SUCCEEDED || detectInfo.nDeviceCount == 0) {
    printf("Error: No GbE-2 camera was found. ErrorCode: %d\n", ret);
    return EXIT_FAILURE;
    }
    // 3. Open the first detected device
    PUC_HANDLE hDevice = NULL;
    ret = PUC_OpenDevice2(0, &hDevice);
    if (ret != PUC_SUCCEEDED) {
    printf("Error: Failed to open the device. ErrorCode: %d\n", ret);
    return EXIT_FAILURE;
    }
    // 4. Get the resolution of the full image and the quantization table
    UINT32 fullWidth = 0, fullHeight = 0;
    PUC_GetResolution(hDevice, &fullWidth, &fullHeight);
    unsigned short qVals[PUC_Q_COUNT] = { 0 };
    PUC_GetQuantization2(hDevice, qVals);
    printf("Full resolution: %u x %u pixels\n", fullWidth, fullHeight);
    // 5. Set the ROI (Region of Interest) parameters
    // Note: Since the data is compressed in 8x8 block units, the coordinates and size must always be specified as multiples of 8
    UINT32 roiX = 200; // Decode start X coordinate (0 or a multiple of 8)
    UINT32 roiY = 150; // Decode start Y coordinate (0 or a multiple of 8)
    UINT32 roiWidth = 400; // ROI width (a multiple of 8)
    UINT32 roiHeight = 300; // ROI height (a multiple of 8)
    printf("ROI settings: position (%u, %u), size %u x %u pixels\n", roiX, roiY, roiWidth, roiHeight);
    // 6. Get the transfer data size and allocate buffers
    UINT32 xferDataSize = 0;
    PUC_GetXferDataSize(hDevice, &xferDataSize);
    // Allocate the buffer for the full compressed data
    unsigned char* pCompressedBuffer = (unsigned char*)malloc(xferDataSize);
    // Allocate the buffer for the ROI-decoded data (only enough for the ROI size being extracted)
    UINT32 roiLineBytes = (roiWidth + 3) & ~3; // Align to a 4-byte boundary
    unsigned long roiDecodedSize = (unsigned long)roiLineBytes * roiHeight;
    unsigned char* pRoiDecodedBuffer = (unsigned char*)malloc(roiDecodedSize);
    if (pCompressedBuffer == NULL || pRoiDecodedBuffer == NULL) {
    printf("Error: Memory allocation failed.\n");
    free(pCompressedBuffer);
    free(pRoiDecodedBuffer);
    PUC_CloseDevice(hDevice);
    return EXIT_FAILURE;
    }
    // 7. Capture one frame's worth of compressed data
    PUC_XFER_DATA_INFO xferDataInfo = { 0 };
    xferDataInfo.pData = pCompressedBuffer;
    xferDataInfo.nDataSize = xferDataSize;
    printf("Capturing...\n");
    ret = PUC_GetSingleXferData(hDevice, &xferDataInfo);
    if (ret == PUC_SUCCEEDED) {
    // 8. Decode only the specified ROI region
    // nX, nY specify the extraction position; nWidth, nHeight specify the decoding size
    ret = PUC_DecodeData(
    pRoiDecodedBuffer, // [out] Destination for the ROI-decoded data
    roiX, roiY, // [in] Decode start coordinates (multiples of 8)
    roiWidth, roiHeight,// [in] Width and height to decode (multiples of 8)
    roiLineBytes, // [in] Bytes per row of the output buffer
    pCompressedBuffer, // [in] The captured compressed data
    qVals // [in] The quantization table
    );
    if (ret == PUC_SUCCEEDED) {
    // 9. Save the decoded ROI image in PGM (P5) format
    const char* filename = "roi_captured_image.pgm";
    FILE* fp = NULL;
    if (fopen_s(&fp, filename, "wb") == 0 && fp != NULL) {
    // Write the PGM header (use the ROI size for the width and height)
    fprintf(fp, "P5\n%u %u\n255\n", roiWidth, roiHeight);
    // Write the valid image data one row at a time
    for (UINT32 y = 0; y < roiHeight; y++) {
    fwrite(pRoiDecodedBuffer + (y * roiLineBytes), sizeof(unsigned char), roiWidth, fp);
    }
    fclose(fp);
    printf("SUCCESS: Saved the ROI cropped image (PGM) (%s)\n", filename);
    } else {
    printf("Error: Failed to save the file.\n");
    }
    } else {
    printf("Error: ROI decode processing failed. ErrorCode: %d\n", ret);
    }
    } else {
    printf("Error: Failed to capture the image data. ErrorCode: %d\n", ret);
    }
    // 10. Free the memory and close the device
    free(pCompressedBuffer);
    free(pRoiDecodedBuffer);
    PUC_CloseDevice(hDevice);
    return EXIT_SUCCESS;
    }
  2. Build and run

    1. Build with Ctrl + Shift + B.
    2. Run with Ctrl + F5.
    3. If a cropped 400x300 pixel image, roi_captured_image.pgm, is output in the execution directory, it has succeeded.

Benefits and Configuration Rules of ROI Decoding

Section titled “Benefits and Configuration Rules of ROI Decoding”

Because only the necessary region is decoded on a pinpoint basis, rather than decoding the entire image, the computational cost (CPU load) can be significantly reduced. This is ideal for applications that need to quickly analyze and save only the region of interest.