画像の取得/デコード
INFINICAM UC-1 SDK 画像の取得/デコード
画像の取得
バッファを確保し、現在のライブ画像を取得します。
はじめに、PUC_GetXferDataSize で現在の解像度に対するデータサイズを取得します。
result = PUC_GetXferDataSize(hDevice, &nDataSize);
if (PUC_CHK_FAILED(result))
{
return;
}
※カメラから転送される画像は圧縮画像です。上記では圧縮画像のデータサイズを取得しています。
※PUC_GetXferDataSizeで取得したサイズでバッファを確保した場合、解像度の変更毎にバッファの再確保が必要になりますので、PUC_GetMaxXferDataSizeを使用してあらかじめ最大データサイズを確保する方法が効率的です。
次に、バッファを確保し画像を取得します。
PUC_XFER_DATA_INFO xferData = { 0 };
xferData.pData = new UINT8[nDataSize];
result = PUC_GetSingleXferData(hDevice, &xferData);
if (PUC_CHK_FAILED(result))
{
return;
}
※xferData.nDataSizeには実際に転送した画像サイズ、xferData.nSequenceNoにはシーケンス番号が格納されます。
※取得した画像は圧縮されているため、表示するにはデコードが必要です。
デコード
圧縮された画像データは下記のように解凍します。
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;
}
デコードした画像は下記のようにビットマップとして保存できます。
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;
※画素はトップダウンで並んでいるため、 BITMAPINFOHEADER の高さはマイナスを指定しています。
※画像の横幅は4の倍数で確保されている必要があります。
マルチスレッドによる高速なデコード
指定された範囲をブロック単位で並列にデコードするPUC_DecodeDataMultiThread関数を用意しています。 PUC_DecodeData関数とほぼ同じ引数ですが、最後にスレッド数を指定可能です。 CPUの性能に合わせて、適切なスレッド数を指定してください。
なお、スレッドの最大数はPUC_MAX_DECODE_THREAD_COUNT個です。 それ以上の指定はできません。
また、PUC_DecodeDataMultiThread関数を並列で実行することも可能ですが、SDK内部のスレッド上限はPUC_MAX_DECODE_THREAD_COUNT個のため それを超えた場合はスレッドに空きが出るまで待機されます。
DC成分のみをデコード
圧縮された画像データのDC成分のみをデコードするには下記のようにおこないます。 画像データは8x8pixelのブロックに分割されており、 デコード範囲をX,Y方向のブロック番号を指定して実行します。
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;
}
※画像データは8x8pixelのブロックに分割されており、デコード範囲をX,Y方向のブロック番号を指定して実行します。
ハイスピードカメラの選定・販売・レンタルから
撮影・解析までお任せください
お問い合わせは
こちらから
専門知識を持った担当者が
お客様の課題や要件をお伺いします
無償デモ撮影・解析
の申し込み
ハイスピードカメラの動作や
必要性を事前に検証できます
製品価格入り資料を
ダウンロード
製品のカタログや活用事例集を
無料でダウンロードできます
電話でお問い合わせ
平日9:00~18:00