This example shows how to acquire data from a sensor using perClass Mira Camera API. The sensor used is Headwall MV.C VNIR. The example is generic and should work unchanged with other line-scan cameras when linked to the respective perClass acquisition plugin.


The example shows how to:

  • inquire on the version of acquisition library (line 13)
  • initialize the acquisition plugin (line 20)
  • scan for available devices and return their names (line 25-31)
  • open a device (line 33)
  • test if a device is a line-scan or snapshot (line 36)
  • setup wavelength resampling to specific output wavelengths irrespective of a device (line 43-49)
  • initialize acquisition (line 51)
  • query frame geometry, data type and layout (60-72)
  • set exposure and frame rate (lines 74-76)
  • acquire 100 frames, store data in memory (line 94-100)


In order to compile the example with command line Microsoft Visual C/C++ compiler use:


> cl ex05.c -I "C:\Program Files\perClass Mira\lib" "C:\Program Files\perClass Mira\lib\miraacq_ximea_1.7.1.lib"


Note, that we point to the lib sub-dir of perClass Mira installation for includes and directly link with the acuisition plugin for your camera (Ximea plugin for MV.C VNIR).


  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <stdint.h>
  4. #include "miraacq.h"
  5.  
  6. int main(int argc,const char* argv[])
  7. {
  8.     int res=MIRA_OK;
  9.     uint16_t* pBuf=NULL;
  10.     FILE* fid=NULL;
  11.  
  12.     int api,rev,step;
  13.     const char* str=miraacq_GetAPIVersion(&api,&rev,&step);
  14.     printf("Example of acquiring data using perClass Mira Acquisition Plugin\nVersion: %d.%d.%d (%s)\n",api,rev,step,str);
  15.  
  16.     const char* str2=miraacq_GetVersion();
  17.     printf("Version: '%s'\n",str2);
  18.  
  19.     makernel* pma=miraacq_Init(".");
  20.     printf("Init: %s", miraacq_GetErrorMsg(pma));
  21.     if( pma==NULL ) {
  22.       goto Error;
  23.     }
  24.  
  25.     MIRAACQ_CHECK( miraacq_ScanDevices(pma) );
  26.  
  27.     const int devCount=miraacq_GetDeviceCount(pma);
  28.     printf("\n%d devices:\n",devCount);
  29.     for(int i=0;i<devCount;i++) {
  30.         printf("%d : %s\n",i, miraacq_GetDeviceName(pma,i));
  31.     }
  32.     int deviceInd=0;
  33.     MIRAACQ_CHECK( miraacq_OpenDevice(pma,deviceInd) );
  34.     printf("Device opened: %d '%s'\n",deviceInd,miraacq_GetDeviceName(pma,deviceInd));
  35.  
  36.     int isSnapshot=miraacq_DeviceIsSnapshot(pma);
  37.     if( isSnapshot ) {
  38.       printf("Line-scan device required by this example\n");
  39.       MIRAACQ_CHECK( miraacq_CloseDevice(pma,deviceInd) );
  40.       goto Error;
  41.     }
  42.  
  43.     printf("Setting resampling from 400 to 1000, step 2\n");
  44.     int bands=(1000-400)/2;
  45.     MIRAACQ_CHECK( miraacq_SetResamplingWavelengthCount(pma,bands) );
  46.     for(int i=0;i<bands;i++) {
  47.       MIRAACQ_CHECK( miraacq_SetResamplingWavelength(pma,i,400+(2*i)) );
  48.     }
  49.     MIRAACQ_CHECK( miraacq_SetResampling(pma,1) );
  50.  
  51.     printf("Initializing the acquisition...");
  52.     res=miraacq_InitializeAcquisition(pma);
  53.     printf("done res=%d\n",res);
  54.     fflush(0);
  55.     if( res!=MIRA_OK ) {
  56.       MIRAACQ_CHECK( miraacq_CloseDevice(pma,deviceInd) );
  57.       goto Error;
  58.     }
  59.  
  60.     printf("Geometry: width=%d bands=%d lines=%d dataType=%d dataLayout=%d frameSize=%d\n",
  61.    miraacq_GetFrameWidth(pma),
  62.    miraacq_GetFrameBands(pma),
  63.    miraacq_GetFrameHeight(pma),
  64.    miraacq_GetFrameDataType(pma),
  65.    miraacq_GetFrameDataLayout(pma),
  66.    miraacq_GetFrameSize(pma)  );
  67.  
  68.     if( miraacq_GetFrameDataType(pma)!=ACQ_DATATYPE_UINT16 ) {
  69.       printf("UINT16 data type expected by this example\n");
  70.       MIRAACQ_CHECK(miraacq_CloseDevice(pma,deviceInd));
  71.       goto Error;
  72.     }
  73.  
  74.     MIRAACQ_CHECK( miraacq_SetExposure(pma,4.0) );
  75.  
  76.     MIRAACQ_CHECK( miraacq_SetFrameRate(pma,100.0) );
  77.  
  78.     const int frames=100;
  79.     int frameSize=miraacq_GetFrameSize(pma);
  80.     pBuf=malloc( frames*frameSize );
  81.     if( pBuf==NULL ) {
  82.       MIRAACQ_CHECK(miraacq_CloseDevice(pma,deviceInd));
  83.       goto Error;
  84.     }
  85.  
  86.     MIRAACQ_CHECK( miraacq_StartAcquisition(pma) );
  87.  
  88.     uint16_t* ptr=pBuf;
  89.     size_t frameID=0;
  90.  
  91.     // offset to the next frame in uint16 units (a frame has width x bands units)
  92.     int nextFrameOffset= miraacq_GetFrameWidth(pma)*miraacq_GetFrameBands(pma);
  93.  
  94.     printf("Acquiring %d frames:\n",frames);
  95.     for(int i=0;i<frames;i++) {
  96.  
  97.       MIRAACQ_CHECK( miraacq_GetFrame(pma,ptr,&frameID,1000) );
  98.  
  99.       ptr+=nextFrameOffset;
  100.     }
  101.  
  102.     printf("Stopping acquisition\n");
  103.     MIRAACQ_CHECK( miraacq_StopAcquisition(pma) );
  104.  
  105.     printf("Writing data to file:\n");
  106.     FILE* pFile=fopen("out.bin","wb");
  107.     if( pFile==NULL ) {
  108.       printf("Cannot open file for writing\n");
  109.       MIRAACQ_CHECK(miraacq_CloseDevice(pma,deviceInd));
  110.       goto Error;      
  111.     }
  112.  
  113.     size_t countWritten=fwrite(pBuf,(size_t)frameSize,frames,pFile);
  114.     printf("%zu bytes written to file\n",countWritten*frameSize);
  115.  
  116.     fclose(pFile);
  117.  
  118. Error:
  119.     if( res!=MIRA_OK ) {
  120.         printf("Error %d: %s",miraacq_GetErrorCode(pma),miraacq_GetErrorMsg(pma));
  121.     }
  122.  
  123.     miraacq_Release(pma);
  124.  
  125.     if( pBuf!=NULL) free(pBuf);
  126.  
  127.     return 0;
  128. }
  129.