402 lines
12 KiB
C
402 lines
12 KiB
C
// GrabSequence.c
|
|
|
|
/* @brief: This example shows users how to use IKapC library to grab sequence images with GigEVision camera. */
|
|
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <vector>
|
|
|
|
#include "IKapC.h"
|
|
|
|
// The number of buffers.
|
|
#define STREAM_BUFFER_COUNT 5
|
|
|
|
// Camera device handle.
|
|
ITKDEVICE g_hCamera = NULL;
|
|
|
|
// Data stream handle.
|
|
ITKSTREAM g_hStream = NULL;
|
|
|
|
// Image buffer handle.
|
|
std::vector <ITKBUFFER> g_vectorBuffer;
|
|
|
|
// Current frame index.
|
|
int g_nCurFrameIndex = 0;
|
|
|
|
// The number of grabbing frames.
|
|
int g_nFrameCount = 10;
|
|
|
|
// Buffer data.
|
|
char *g_bufferData = NULL;
|
|
|
|
/* @brief: Determine whether the function is called successfully.
|
|
* @param[in] errc: Function return value. */
|
|
#define CHECK(errc) if (ITKSTATUS_OK != errc) printErrorAndExit(errc)
|
|
|
|
/* @brief: Configure camera device. */
|
|
void ConfigureCamera();
|
|
|
|
/* @brief: Create data stream and buffer. */
|
|
void CreateStreamAndBuffer();
|
|
|
|
/* @brief: Configure data stream. */
|
|
void ConfigureStream();
|
|
|
|
/* @brief: Unregister callback functions. */
|
|
void UnRegisterCallback();
|
|
|
|
/* @brief: This function is registered as a callback function. When data stream starts, the function will be called.
|
|
* @param[in] eventType: Event type.
|
|
* @param[in] pContext: Input parameter. */
|
|
void IKAPC_CC cbStartOfStream(uint32_t eventType, void *pContext);
|
|
|
|
/* @brief: This function is registered as a callback function. When data stream ends, the function will be called.
|
|
* @param[in] eventType: Event type.
|
|
* @param[in] pContext: Input parameter. */
|
|
void IKAPC_CC cbEndOfStream(uint32_t eventType, void *pContext);
|
|
|
|
/* @brief: This function is registered as a callback function. When grabbing a frame of image finished, the function will be called.
|
|
* @param[in] eventType: Event type.
|
|
* @param[in] pContext: Input parameter. */
|
|
void IKAPC_CC cbOnEndOfFrame(uint32_t eventType, void *pContext);
|
|
|
|
/* @brief: This function is registered as a callback function. When grabbing images time out, the function will be called.
|
|
* @param[in] eventType: Event type.
|
|
* @param[in] pContext: Input parameter. */
|
|
void IKAPC_CC cbOnTimeOut(uint32_t eventType, void *pContext);
|
|
|
|
/* @brief: This function is registered as a callback function. When grabbing frame lost, the function will be called.
|
|
* @param[in] eventType: Event type.
|
|
* @param[in] pContext: Input parameter. */
|
|
void IKAPC_CC cbOnFrameLost(uint32_t eventType, void *pContext);
|
|
|
|
/* @brief: Print error message and exit the program.
|
|
* @param[in] errc: Function return value. */
|
|
void printErrorAndExit(ITKSTATUS errc);
|
|
|
|
/* @brief: Users enter Enter to exit the program. */
|
|
void pressEnterToExit();
|
|
|
|
int main(void)
|
|
{
|
|
// Return value of IKapC functions.
|
|
ITKSTATUS res = ITKSTATUS_OK;
|
|
|
|
// The number of available devices.
|
|
uint32_t numDevices = 0;
|
|
|
|
// The index of device to be opened.
|
|
uint32_t devIndex = 0;
|
|
|
|
// Initialize IKapC runtime environment.
|
|
res = ItkManInitialize();
|
|
CHECK(res);
|
|
|
|
// Configure camera device.
|
|
ConfigureCamera();
|
|
|
|
// Create data stream and buffer.
|
|
CreateStreamAndBuffer();
|
|
|
|
// Configure data stream.
|
|
ConfigureStream();
|
|
|
|
// Start grabbing images.
|
|
res = ItkStreamStart(g_hStream, g_nFrameCount);
|
|
CHECK(res);
|
|
|
|
// Wait for grabbing images finished.
|
|
res = ItkStreamWait(g_hStream);
|
|
CHECK(res);
|
|
|
|
// Unregister callback functions.
|
|
UnRegisterCallback();
|
|
|
|
// Free data stream and buffers.
|
|
for (auto it = g_vectorBuffer.begin(); it != g_vectorBuffer.end(); it++)
|
|
{
|
|
ItkStreamRemoveBuffer(g_hStream, *it);
|
|
ItkBufferFree(*it);
|
|
}
|
|
std::vector<ITKBUFFER>().swap(g_vectorBuffer);
|
|
ItkDevFreeStream(g_hStream);
|
|
|
|
// Close camera device.
|
|
res = ItkDevClose(g_hCamera);
|
|
CHECK(res);
|
|
|
|
if (g_bufferData != NULL)
|
|
free(g_bufferData);
|
|
|
|
// Release IKapC runtime environment.
|
|
ItkManTerminate();
|
|
|
|
pressEnterToExit();
|
|
return EXIT_SUCCESS;
|
|
}
|
|
|
|
// Configure camera device.
|
|
void ConfigureCamera()
|
|
{
|
|
ITKSTATUS res = ITKSTATUS_OK;
|
|
uint32_t numCameras = 0;
|
|
|
|
// Enumerate the number of available cameras. Before opening the camera, ItkManGetDeviceCount() function must be called.
|
|
res = ItkManGetDeviceCount(&numCameras);
|
|
CHECK(res);
|
|
|
|
// When there is no connected cameras.
|
|
if (numCameras == 0)
|
|
{
|
|
printf("No camera.\n");
|
|
ItkManTerminate();
|
|
pressEnterToExit();
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
// Open GigEVision camera.
|
|
for (uint32_t i = 0; i < numCameras; i++)
|
|
{
|
|
ITKDEV_INFO di;
|
|
|
|
// Get camera device information.
|
|
res = ItkManGetDeviceInfo(i, &di);
|
|
printf("Using camera: serial: %s, name: %s, interface: %s.\n", di.SerialNumber, di.FullName, di.DeviceClass);
|
|
|
|
// When the device is GigEVision camera and the serial number is proper.
|
|
if (strcmp(di.DeviceClass, "GigEVision") == 0 && strcmp(di.SerialNumber, "") != 0)
|
|
{
|
|
ITKGIGEDEV_INFO gvInfo;
|
|
|
|
// Open camera.
|
|
res = ItkDevOpen(i, ITKDEV_VAL_ACCESS_MODE_EXCLUSIVE, &g_hCamera);
|
|
CHECK(res);
|
|
|
|
// Get GigEVision camera device information.
|
|
res = ItkManGetGigEDeviceInfo(i, &gvInfo);
|
|
CHECK(res);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Create data stream and buffer.
|
|
void CreateStreamAndBuffer()
|
|
{
|
|
ITKSTATUS res = ITKSTATUS_OK;
|
|
|
|
// The number of data stream.
|
|
uint32_t streamCount = 0;
|
|
|
|
// Image width.
|
|
int64_t nWidth = 0;
|
|
|
|
// Image height.
|
|
int64_t nHeight = 0;
|
|
|
|
// Pixel format.
|
|
uint32_t nFormat = ITKBUFFER_VAL_FORMAT_MONO8;
|
|
|
|
// Image size.
|
|
int64_t nImageSize = 0;
|
|
|
|
// Pixel format name.
|
|
char pixelFormat[16];
|
|
|
|
// Pixel format name length.
|
|
uint32_t pixelFormatLen = 16;
|
|
|
|
// Get the number of data stream.
|
|
res = ItkDevGetStreamCount(g_hCamera, &streamCount);
|
|
CHECK(res);
|
|
|
|
if (streamCount == 0)
|
|
{
|
|
fprintf(stderr, "Camera does not have image stream channel.");
|
|
ItkManTerminate();
|
|
pressEnterToExit();
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
// Get image width.
|
|
res = ItkDevGetInt64(g_hCamera, "Width", &nWidth);
|
|
CHECK(res);
|
|
|
|
// Get image height.
|
|
res = ItkDevGetInt64(g_hCamera, "Height", &nHeight);
|
|
CHECK(res);
|
|
|
|
// Get pixel format.
|
|
res = ItkDevToString(g_hCamera, "PixelFormat", pixelFormat, &pixelFormatLen);
|
|
CHECK(res);
|
|
|
|
if (strcmp(pixelFormat, "Mono8") == 0)
|
|
nFormat = ITKBUFFER_VAL_FORMAT_MONO8;
|
|
else if (strcmp(pixelFormat, "Mono10") == 0)
|
|
nFormat = ITKBUFFER_VAL_FORMAT_MONO10;
|
|
else if (strcmp(pixelFormat, "Mono10Packed") == 0)
|
|
nFormat = ITKBUFFER_VAL_FORMAT_MONO10PACKED;
|
|
else if (strcmp(pixelFormat, "BayerGR8") == 0)
|
|
nFormat = ITKBUFFER_VAL_FORMAT_BAYER_GR8;
|
|
else if (strcmp(pixelFormat, "BayerRG8") == 0)
|
|
nFormat = ITKBUFFER_VAL_FORMAT_BAYER_RG8;
|
|
else if (strcmp(pixelFormat, "BayerGB8") == 0)
|
|
nFormat = ITKBUFFER_VAL_FORMAT_BAYER_GB8;
|
|
else if (strcmp(pixelFormat, "BayerBG8") == 0)
|
|
nFormat = ITKBUFFER_VAL_FORMAT_BAYER_BG8;
|
|
else
|
|
{
|
|
fprintf(stderr, "Camera does not support pixel format %s.", pixelFormat);
|
|
ItkManTerminate();
|
|
pressEnterToExit();
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
// Create image buffer.
|
|
ITKBUFFER hBuffer;
|
|
res = ItkBufferNew(nWidth, nHeight, nFormat, &hBuffer);
|
|
CHECK(res);
|
|
g_vectorBuffer.push_back(hBuffer);
|
|
|
|
// Get buffer size.
|
|
res = ItkBufferGetPrm(hBuffer, ITKBUFFER_PRM_SIZE, &nImageSize);
|
|
CHECK(res);
|
|
|
|
// Create buffer data saving.
|
|
g_bufferData = (char*)malloc(nImageSize);
|
|
if (g_bufferData == NULL)
|
|
{
|
|
pressEnterToExit();
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
// Allocate data stream source.
|
|
res = ItkDevAllocStream(g_hCamera, 0, hBuffer, &g_hStream);
|
|
CHECK(res);
|
|
|
|
// Add buffers to data stream.
|
|
for (int i = 1; i < STREAM_BUFFER_COUNT; i++)
|
|
{
|
|
res = ItkBufferNew(nWidth, nHeight, nFormat, &hBuffer);
|
|
CHECK(res);
|
|
res = ItkStreamAddBuffer(g_hStream, hBuffer);
|
|
CHECK(res);
|
|
g_vectorBuffer.push_back(hBuffer);
|
|
}
|
|
}
|
|
|
|
// Configure data stream.
|
|
void ConfigureStream()
|
|
{
|
|
ITKSTATUS res = ITKSTATUS_OK;
|
|
|
|
// Transfer mode.
|
|
uint32_t xferMode = ITKSTREAM_VAL_TRANSFER_MODE_SYNCHRONOUS_WITH_PROTECT;
|
|
|
|
// Grab mode.
|
|
uint32_t startMode = ITKSTREAM_VAL_START_MODE_NON_BLOCK;
|
|
|
|
// Time out time.
|
|
uint32_t timeOut = -1;
|
|
|
|
// Set grab mode.
|
|
res = ItkStreamSetPrm(g_hStream, ITKSTREAM_PRM_START_MODE, &startMode);
|
|
CHECK(res);
|
|
|
|
// Set transfer mode.
|
|
res = ItkStreamSetPrm(g_hStream, ITKSTREAM_PRM_TRANSFER_MODE, &xferMode);
|
|
CHECK(res);
|
|
|
|
// Set time out time.
|
|
res = ItkStreamSetPrm(g_hStream, ITKSTREAM_PRM_TIME_OUT, &timeOut);
|
|
CHECK(res);
|
|
|
|
// Register callback functions.
|
|
res = ItkStreamRegisterCallback(g_hStream, ITKSTREAM_VAL_EVENT_TYPE_START_OF_STREAM, cbStartOfStream, g_hStream);
|
|
CHECK(res);
|
|
res = ItkStreamRegisterCallback(g_hStream, ITKSTREAM_VAL_EVENT_TYPE_END_OF_STREAM, cbEndOfStream, g_hStream);
|
|
CHECK(res);
|
|
res = ItkStreamRegisterCallback(g_hStream, ITKSTREAM_VAL_EVENT_TYPE_END_OF_FRAME, cbOnEndOfFrame, g_hStream);
|
|
CHECK(res);
|
|
res = ItkStreamRegisterCallback(g_hStream, ITKSTREAM_VAL_EVENT_TYPE_TIME_OUT, cbOnTimeOut, g_hStream);
|
|
CHECK(res);
|
|
res = ItkStreamRegisterCallback(g_hStream, ITKSTREAM_VAL_EVENT_TYPE_FRAME_LOST, cbOnFrameLost, g_hStream);
|
|
CHECK(res);
|
|
}
|
|
|
|
// Unregister callback functions.
|
|
void UnRegisterCallback()
|
|
{
|
|
ITKSTATUS res = ITKSTATUS_OK;
|
|
|
|
res = ItkStreamUnregisterCallback(g_hStream, ITKSTREAM_VAL_EVENT_TYPE_START_OF_STREAM);
|
|
res = ItkStreamUnregisterCallback(g_hStream, ITKSTREAM_VAL_EVENT_TYPE_END_OF_STREAM);
|
|
res = ItkStreamUnregisterCallback(g_hStream, ITKSTREAM_VAL_EVENT_TYPE_END_OF_FRAME);
|
|
res = ItkStreamUnregisterCallback(g_hStream, ITKSTREAM_VAL_EVENT_TYPE_TIME_OUT);
|
|
res = ItkStreamUnregisterCallback(g_hStream, ITKSTREAM_VAL_EVENT_TYPE_FRAME_LOST);
|
|
}
|
|
|
|
// This function is registered as a callback function. When data stream starts, the function will be called.
|
|
void IKAPC_CC cbStartOfStream(uint32_t eventType, void *pContext)
|
|
{
|
|
printf("On start of stream. \n");
|
|
}
|
|
|
|
// This function is registered as a callback function. When data stream ends, the function will be called.
|
|
void IKAPC_CC cbEndOfStream(uint32_t eventType, void *pContext)
|
|
{
|
|
printf("On end of stream. \n");
|
|
}
|
|
|
|
// This function is registered as a callback function. When grabbing a frame of image finished, the function will be called.
|
|
void IKAPC_CC cbOnEndOfFrame(uint32_t eventType, void* pContext)
|
|
{
|
|
ITKSTATUS res = ITKSTATUS_OK;
|
|
unsigned bufferStatus = 0;
|
|
int64_t nImageSize = 0;
|
|
int nBufferIndex = g_nCurFrameIndex % STREAM_BUFFER_COUNT;
|
|
ITKBUFFER hBuffer = g_vectorBuffer[nBufferIndex];
|
|
|
|
res = ItkBufferGetPrm(hBuffer, ITKBUFFER_PRM_STATE, &bufferStatus);
|
|
CHECK(res);
|
|
|
|
// When buffer is full or buffer is not full but cannot grab a complete frame of image.
|
|
if (bufferStatus == ITKBUFFER_VAL_STATE_FULL || bufferStatus == ITKBUFFER_VAL_STATE_UNCOMPLETED)
|
|
{
|
|
// Read buffer data.
|
|
res = ItkBufferGetPrm(hBuffer,ITKBUFFER_PRM_SIZE, &nImageSize);
|
|
CHECK(res);
|
|
res = ItkBufferRead(hBuffer, 0, g_bufferData, (uint32_t)nImageSize);
|
|
CHECK(res);
|
|
}
|
|
|
|
printf("On end of %d frame.\n", ++g_nCurFrameIndex);
|
|
}
|
|
|
|
// This function is registered as a callback function. When grabbing images time out, the function will be called.
|
|
void IKAPC_CC cbOnTimeOut(uint32_t eventType, void *pContext)
|
|
{
|
|
printf("on time out. \n");
|
|
}
|
|
|
|
// This function is registered as a callback function. When grabbing frame lost, the function will be called.
|
|
void IKAPC_CC cbOnFrameLost(uint32_t eventType, void *pContext)
|
|
{
|
|
printf("on frame lost. \n");
|
|
}
|
|
|
|
// Print error message and exit the program.
|
|
void printErrorAndExit(ITKSTATUS errc)
|
|
{
|
|
fprintf(stderr, "Error Code:%08X\n", errc);
|
|
ItkManTerminate();
|
|
pressEnterToExit();
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
// Users enter Enter to exit the program.
|
|
void pressEnterToExit(void)
|
|
{
|
|
fprintf(stderr, "\nPress enter to exit.\n");
|
|
while (getchar() != '\n');
|
|
} |