Example of acquisition from Camera API
This example shows how to acquire data from a sensor using the perClass Mira Camera API. The sensor used is a Headwall MV.C VNIR. The example is generic and should work unchanged with other line-scan cameras when linked to their respective perClass acquisition plugin. If the camera is not a VNIR camera, then it may also be required to change the resampling wavelengths.
The example shows how to:
- Query the version of the acquisition library (line 12-17)
- Initialize the acquisition plugin (line 19-23)
- Scan for available devices and print their names (line 25-31)
- Open a device (line 33-35)
- Test if a device is line-scan or snapshot (line 37-42)
- Initialize acquisition (line 44-50)
- Setup wavelength resampling to specific output wavelengths irrespective of a device (line 52-58)
- Query frame geometry, data type, and layout (line 60-72)
- Set exposure and frame rate (line 74-75)
- Allocate a buffer for 100 frames (line 77-84)
- Acquire 100 frames into the buffer (line 86-101)
- Write the buffer contents to a file (line 106-116)
In order to compile this example, save it as example.c, and then use the command for the operating system to compile on:
On Windows using the Microsoft Visual C/C++ compiler:
> cl example.c -I "C:\Program Files\perClass Mira\include" "C:\Program Files\perClass Mira\lib\miraacq_ximea_1.13.1.lib"
On Linux using GCC:
> gcc example.c -o example -I"/opt/perClass/Mira/include" -L"/opt/perClass/Mira/lib" -lmiraacq_ximea_1.13.1
Note that we point to the lib sub-directory of the perClass Mira installation for includes and directly link with the acquisition plugin for the camera (XIMEA plugin for MV.C VNIR).
- #include <stdint.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include "miraacq.h"
- int main(int argc, const char* argv[])
- {
- int res = MIRA_OK;
- uint16_t* pBuf = NULL;
- int api, step, rev;
- const char* pAPIVersionStr = miraacq_GetAPIVersion(&api, &step, &rev);
- printf("Example of acquiring data using perClass Mira Acquisition Plugin\nVersion: %d.%d.%d (%s)\n", api, step, rev, pAPIVersionStr);
- const char* pVersionStr = miraacq_GetVersion();
- printf("Version: '%s'\n", pVersionStr);
- makernel* pma = miraacq_Init(".");
- printf("Init: %s", miraacq_GetErrorMsg(pma));
- if (pma == NULL) {
- goto Error;
- }
- MIRAACQ_CHECK(miraacq_ScanDevices(pma));
- const int deviceCount = miraacq_GetDeviceCount(pma);
- printf("\n%d devices:\n", deviceCount);
- for (int i = 0; i < deviceCount; i++) {
- printf(" %d : %s\n", i, miraacq_GetDeviceName(pma, i));
- }
- int deviceInd = 0;
- MIRAACQ_CHECK(miraacq_OpenDevice(pma, deviceInd));
- printf("Device opened: %d '%s'\n", deviceInd, miraacq_GetDeviceName(pma, deviceInd));
- int isSnapshot = miraacq_DeviceIsSnapshot(pma);
- if (isSnapshot) {
- printf("A line-scan device required by this example\n");
- MIRAACQ_CHECK(miraacq_CloseDevice(pma, deviceInd));
- goto Error;
- }
- printf("Initializing the acquisition...");
- res = miraacq_InitializeAcquisition(pma);
- printf("done res=%d\n", res);
- if (res != MIRA_OK) {
- MIRAACQ_CHECK(miraacq_CloseDevice(pma, deviceInd));
- goto Error;
- }
- printf("Setting resampling from 400 to 1000, step 2\n");
- int bands = ((1000 - 400) / 2) + 1;
- MIRAACQ_CHECK(miraacq_SetResamplingWavelengthCount(pma, bands));
- for (int i = 0; i < bands; i++) {
- MIRAACQ_CHECK(miraacq_SetResamplingWavelength(pma, i, 400 + (2 * i)));
- }
- MIRAACQ_CHECK(miraacq_SetResampling(pma, 1));
- printf("Geometry: width=%d bands=%d lines=%d dataType=%d dataLayout=%d frameSize=%d\n",
- miraacq_GetFrameWidth(pma),
- miraacq_GetFrameBands(pma),
- miraacq_GetFrameHeight(pma),
- miraacq_GetFrameDataType(pma),
- miraacq_GetFrameDataLayout(pma),
- miraacq_GetFrameSize(pma));
- if (miraacq_GetFrameDataType(pma) != ACQ_DATATYPE_UINT16) {
- printf("UINT16 data type expected by this example\n");
- MIRAACQ_CHECK(miraacq_CloseDevice(pma, deviceInd));
- goto Error;
- }
- MIRAACQ_CHECK(miraacq_SetExposure(pma, 4.0));
- MIRAACQ_CHECK(miraacq_SetFrameRate(pma, 100.0));
- const int frames = 100;
- int frameSize = miraacq_GetFrameSize(pma);
- pBuf = malloc(frames * frameSize);
- if (pBuf == NULL) {
- printf("Failed to allocate memory for %d frames\n", frames);
- MIRAACQ_CHECK(miraacq_CloseDevice(pma, deviceInd));
- goto Error;
- }
- MIRAACQ_CHECK(miraacq_StartAcquisition(pma));
- uint16_t* ptr = pBuf;
- size_t frameID = 0;
- // offset to the next frame in uint16 units (a frame has width x bands units)
- int nextFrameOffset = miraacq_GetFrameWidth(pma) * miraacq_GetFrameBands(pma);
- printf("Acquiring %d frames:\n", frames);
- for (int i = 0; i < frames; i++) {
- MIRAACQ_CHECK(miraacq_GetFrame(pma, ptr, &frameID, 1000));
- ptr += nextFrameOffset;
- }
- printf("Stopping acquisition\n");
- MIRAACQ_CHECK(miraacq_StopAcquisition(pma));
- printf("Closing device\n");
- MIRAACQ_CHECK(miraacq_CloseDevice(pma, deviceInd));
- printf("Writing data to file: ");
- FILE* pFile = fopen("out.bin", "wb");
- if (pFile == NULL) {
- printf("Cannot open file for writing\n");
- goto Error;
- }
- size_t countWritten = fwrite(pBuf, (size_t)frameSize, frames, pFile);
- printf("%zu bytes written to file\n", countWritten * frameSize);
- fclose(pFile);
- Error:
- if (res != MIRA_OK) {
- printf("Error %d: %s", miraacq_GetErrorCode(pma), miraacq_GetErrorMsg(pma));
- }
- miraacq_Release(pma);
- if (pBuf != NULL) free(pBuf);
- return 0;
- }