Retrieving and Decoding Images

INFINICAM UC-1 SDK Retrieving and Decoding Images

Retrieving images

Allocate a buffer and retrieve the current live image.
First, retrieve the data size for the current resolution with “PUC_GetXferDataSize”.

result = PUC_GetXferDataSize(hDevice, &nDataSize);
if (PUC_CHK_FAILED(result))
{
return;
}

※The image transferred from the camera is a compressed image. In the example above, the data size of the compressed image will be retrieved.

※When allocating a buffer for the size retrieved with PUC_GetXferDataSize, the buffer will need to be reallocated every time the resolution is changed. Using PUC_GetMaxXferDataSize to allocate the maximum data size in advance facilitates this process.

Next, allocate a buffer and retrieve the image.

PUC_XFER_DATA_INFO xferData = { 0 };

xferData.pData = new UINT8[nDataSize];

result = PUC_GetSingleXferData(hDevice, &xferData);
if (PUC_CHK_FAILED(result))
{
return;
}

※The size of the actual transferred image is stored to xferData.nDataSize, and the sequence number is stored to xferData.nSequenceNo.

※As the retrieved image has been compressed, it will need to be decoded in order to view it.

Decoding

Unpack the compressed image data as described below.

UINT32 nWidth, nHeight, nLineBytes;
USHORT q[PUC_Q_COUNT];
UINT8* pDecodeBuf;

result = PUC_GetResolution(hDevice, &nWidth, &nHeight);
if (PUC_CHK_FAILED(result))
{
return;
}

for (UINT32 i = 0; i < PUC_Q_COUNT; i++)
{
result = PUC_GetQuantization(hDevice, i, &q[i]);
if (PUC_CHK_FAILED(result))
{
return;
}
}

nLineBytes = nWidth % 4 == 0 ? nWidth : nWidth + (4 – nWidth % 4);
pDecodeBuf = new UINT8[nLineBytes * nHeight];

result = PUC_DecodeData(pDecodeBuf, 0, 0, nWidth, nHeight, nLineBytes, xferData.pData, q);
if (PUC_CHK_FAILED(result))
{
return;
}

The decoded image can be saved as a bitmap as shown below.

UINT32 nInfoBytes;
BITMAPINFO* pBitmapInfo;
DWORD nPixelBytes;
BITMAPFILEHEADER fileHeader;
FILE* fp;

nInfoBytes = sizeof(BITMAPINFOHEADER) + (sizeof(RGBQUAD) * 256);
pBitmapInfo = (BITMAPINFO*)new BYTE[nInfoBytes];
nPixelBytes = nLineBytes * nHeight;

memset(pBitmapInfo, 0, nInfoBytes);
pBitmapInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
pBitmapInfo->bmiHeader.biWidth = nWidth;
pBitmapInfo->bmiHeader.biHeight = -(INT32)nHeight;
pBitmapInfo->bmiHeader.biPlanes = 1;
pBitmapInfo->bmiHeader.biBitCount = 8;
pBitmapInfo->bmiHeader.biCompression = BI_RGB;
pBitmapInfo->bmiHeader.biSizeImage = nPixelBytes;
pBitmapInfo->bmiHeader.biClrUsed = 256;

for (int i = 0; i < 256; i++)
{
pBitmapInfo->bmiColors[i].rgbRed = (BYTE)i;
pBitmapInfo->bmiColors[i].rgbGreen = (BYTE)i;
pBitmapInfo->bmiColors[i].rgbBlue = (BYTE)i;
}

memset(&fileHeader, 0, sizeof(fileHeader));
fileHeader.bfType = (‘M’ << 8) + ‘B’;
fileHeader.bfSize = sizeof(BITMAPFILEHEADER) + nInfoBytes + nPixelBytes;
fileHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + nInfoBytes;

_tfopen_s(&fp, _T(“test.bmp”), _T(“wb”));
fwrite(&fileHeader, sizeof(BITMAPFILEHEADER), 1, fp);
fwrite(pBitmapInfo, nInfoBytes, 1, fp);
fwrite(pDecodeBuf, nPixelBytes, 1, fp);
fclose(fp);

delete[] pBitmapInfo;

※As pixels are arranged top to bottom, the height of the “BITMAPINFOHEADER” is specified with a minus.

※The width of the image must be a multiple of 4.

Fast decoding with multi-threading

The PUC_DecodeDataMultiThread function is provided to decode the specified range in block units in parallel. The arguments are almost the same as for the PUC_DecodeData function, but the number of threads can be specified at the end. Specify the appropriate number of threads according to the performance of the CPU.

The maximum number of threads is PUC_MAX_DECODE_THREAD_COUNT. You cannot specify more than that.

It is also possible to execute the PUC_DecodeDataMultiThread function in parallel, but since the SDK’s internal thread limit is PUC_MAX_DECODE_THREAD_COUNT, so if this limit is exceeded, the function will wait until there is room in the thread.”

Decode only DC data

Unpack DC data from the compressed image data as described below. The image data is divided into 8 x 8 pixels blocks. Specify the decode range with block number in the X and Y directions and execute.

UINT32 nBlockCountX, nBlockCountY, nLineBytes;
UINT8* pDecodeDCBuf;
nLineBytes = nWidth % 4 == 0 ? nWidth : nWidth + (4 – nWidth % 4);
nBlockCountX = nLineBytes % 8 == 0 ? nLineBytes / 8 : (nLineBytes + 7) / 8;
nBlockCountY = nHeight % 8 == 0 ? nHeight / 8 : (nHeight + 7) / 8;

pDecodeDCBuf = new UINT8[nBlockCountX * nBlockCountY];

result = PUC_DecodeDCData(pDecodeDCBuf, 0, 0, nBlockCountX, nBlockCountY, xferData.pData);
if (PUC_CHK_FAILED(result))
{
return;
}

※The image data is divided into 8×8 pixel blocks, and the decoding range is executed by specifying the block numbers in the X and Y directions.

> INFINICAM Product page

ハイスピードカメラの選定・販売・レンタルから
撮影・解析までお任せください

お問い合わせは
こちらから

専門知識を持った担当者が
お客様の課題や要件をお伺いします

無償デモ撮影・解析
の申し込み

ハイスピードカメラの動作や
必要性を事前に検証できます

製品価格入り資料を
ダウンロード

製品のカタログや活用事例集を
無料でダウンロードできます

電話でお問い合わせ

平日9:00~18:00

03-3518-6271