Creating the SingleImage (Color) Project
These are the steps to create a program that captures one frame of compressed data from a GbE-2 (color model), performs Bayer conversion (debayering) and white balance adjustment to decode it in color, and saves it as a file in the PPM format (Portable Pixmap), which can be viewed with standard image viewing software.
-
Write the source code
Open the main file (e.g.
GbE2_SingleImageColor.cpp) and replace its contents with the following code.#include <stdio.h>#include <stdlib.h>#include <PUCLIB.h> // Load the PUCLIB headerint main() {printf("Starting INFINICAM GbE-2 SingleImage (Color) capture...\n");// 1. Initialize the SDKPUCRESULT 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 networkPUC_DETECT_FILTER filter = { 0 };filter.nDeviceTypeFlags = PUC_DETECT_TARGET_GBE2; // Specify GbE-2PUC_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 devicePUC_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. Determine the color model and set the white balance gainsPUC_COLOR_TYPE colorType = PUC_COLOR_MONO;PUC_GetColorType(hDevice, &colorType);if (colorType != PUC_COLOR_COLOR) {printf("Note: The connected camera was detected as a monochrome model.\n");}// Set the white balance gain for each of the R, G, and B channels (1.0 = no change)PUC_SetWhiteBalanceGain(1.0, 1.0, 1.0);// 5. Get the resolutionUINT32 width = 0, height = 0;ret = PUC_GetResolution(hDevice, &width, &height);if (ret != PUC_SUCCEEDED) {printf("Error: Failed to get the resolution. ErrorCode: %d\n", ret);PUC_CloseDevice(hDevice);return EXIT_FAILURE;}printf("Resolution: %u x %u pixels (color)\n", width, height);// 6. Retrieve the quantization table in bulk (used for decoding)unsigned short qVals[PUC_Q_COUNT] = { 0 };ret = PUC_GetQuantization2(hDevice, qVals);if (ret != PUC_SUCCEEDED) {printf("Error: Failed to get the quantization table. ErrorCode: %d\n", ret);PUC_CloseDevice(hDevice);return EXIT_FAILURE;}// 7. Get the transfer data size and allocate buffersUINT32 xferDataSize = 0;ret = PUC_GetXferDataSize(hDevice, &xferDataSize);if (ret != PUC_SUCCEEDED) {printf("Error: Failed to get the transfer data size. ErrorCode: %d\n", ret);PUC_CloseDevice(hDevice);return EXIT_FAILURE;}// Allocate the buffer to store the compressed dataunsigned char* pCompressedBuffer = (unsigned char*)malloc(xferDataSize);// Allocate the buffer to store the color-decoded data (RGB 24-bit = 3 bytes per pixel)// Align the row byte count (width * 3) to a 4-byte boundaryUINT32 lineBytes = ((width * 3) + 3) & ~3;unsigned long decodedBufferSize = (unsigned long)lineBytes * height;unsigned char* pDecodedBuffer = (unsigned char*)malloc(decodedBufferSize);if (pCompressedBuffer == NULL || pDecodedBuffer == NULL) {printf("Error: Memory allocation failed.\n");free(pCompressedBuffer);free(pDecodedBuffer);PUC_CloseDevice(hDevice);return EXIT_FAILURE;}// 8. Capture one frame of dataPUC_XFER_DATA_INFO xferDataInfo = { 0 };xferDataInfo.pData = pCompressedBuffer;xferDataInfo.nDataSize = xferDataSize;printf("Capturing one frame...\n");ret = PUC_GetSingleXferData(hDevice, &xferDataInfo);if (ret == PUC_SUCCEEDED) {// 9. Decode the compressed data in color// The SDK automatically applies Bayer conversion (debayering) and white balance adjustment internally,// and expands the data as RGB data (1 pixel = 3 bytes).ret = PUC_DecodeData(pDecodedBuffer, 0, 0, width, height, lineBytes, pCompressedBuffer, qVals);if (ret == PUC_SUCCEEDED) {// 10. Save the decoded color image in PPM (P6) formatconst char* filename = "captured_color_image.ppm";FILE* fp = NULL;if (fopen_s(&fp, filename, "wb") == 0 && fp != NULL) {// Write the PPM header (P6 / width / height / max gray value 255)fprintf(fp, "P6\n%u %u\n255\n", width, height);// Write the valid color image data (RGB 3 bytes/px) one row at a timefor (UINT32 y = 0; y < height; y++) {fwrite(pDecodedBuffer + (y * lineBytes), sizeof(unsigned char), width * 3, fp);}fclose(fp);printf("SUCCESS: Saved the PPM color image file (%s)\n", filename);} else {printf("Error: Failed to save the file.\n");}} else {printf("Error: Failed to decode the image data. ErrorCode: %d\n", ret);}} else {printf("Error: Failed to capture the image data. ErrorCode: %d\n", ret);}// 11. Free the memory and close the devicefree(pCompressedBuffer);free(pDecodedBuffer);PUC_CloseDevice(hDevice);return EXIT_SUCCESS;} -
Build and run
- Press
Ctrl+Shift+Bto build the project. - Make sure
puclib.dlland related files are placed in the same folder as the executable (.exe). - Run with
Ctrl+F5. Ifcaptured_color_image.ppmis generated directly under the project folder, it has succeeded.
- Press
What Is the PPM Format?
Section titled “What Is the PPM Format?”The PPM (Portable Pixmap) format is an uncompressed full-color image format standardized by the Netpbm project. It consists of a text-based header and binary pixel data with 8 bits per RGB channel (24-bit color total).
Basic file structure (P6 format)
Section titled “Basic file structure (P6 format)”P6800 600255[Binary RGB pixel data (width x height x 3 bytes)]- Magic number (
P6): Indicates that this is a binary full-color (RGB 24-bit) image. - Image width and height: Specifies the resolution in pixels, e.g.
800 600. - Maximum brightness value (
255): Specifies the maximum gray level of each color channel (R, G, B). - Pixel data: Immediately after the newline, the brightness data follows as-is in R, G, B order (1 pixel = 3 bytes).
