Quali sono le differenze nella programmazione di mvBlueFOX e mvBlueFOX3?

mvBlueFOX, mvBlueFOX-M, mvBlueFOX-MLC, mvBlueFOX-IGC, mvBlueFOX3

Per tutti i prodotti MATRIX VISION è disponibile un'interfaccia driver unificata chiamata mvIMPACT Acquire. L'unica differenza tra

è il cosiddetto Interface Layout.

Per la serie mvBlueFOX si utilizza uno specifico Interface Layout di MATRIX Vision chiamato "DeviceSpecific".
Al contrario, le mvBlueFOX3 si basano sugli standard di elaborazione immagini USB3 Vision e "GenICam".

USB3 Vision controlla la comunicazione su USB 3.0 tra periferiche di acquisizione immagini e l'applicazione. Lo standard GenICam unifica l'accesso ai parametri della periferica. Inoltre, lo standard denomina i parametri ed i valori tramite la Standard Feature Naming Convention. E' possibile trovare la versione attuale di SFNC sul sito di EMVA.

Che cosa significa questo per un programmatore e per l'adozione di "vecchio" codice quando si cambia la telecamera?

Innanzitutto, è possibile riutilizzare gran parte del codice scritto con mvIMPACT Acquire. Ad es, le parti dove si

  • indirizza ed inizializza la periferica
  • acquisiscono le immagini

rrimangono le stesse. Questa sono tutte funzioni e classi comuni, che sono disponibili per tutti gli Interface Layouts.

L'unica parte che cambia è la modalità per leggere e settare i parametri della telecamera.

Questo include anche i programmi HRTC. In GenICam è possibile creare programmi HRTC utilizzando Counters e Timers. Il seguente esempio motra come settare il tempo di esposizione tramite il DeviceSpecific Interface Layout:

#include <iostream>
#include <mvIMPACT_CPP/mvIMPACT_acquire.h>
 
using namespace std;
using namespace mvIMPACT::acquire;

//-----------------------------------------------------------------------------
int main( int /*argc*/, char* /*argv*/[] )
//-----------------------------------------------------------------------------
{
  DeviceManager devMgr;
  Device* pDev = devMgr.getDeviceByFamily("mvBlueFOX");
  if (pDev == 0)
  {
	  cout << "There is currently no mvBlueFOX2 device connected," << endl;
	  cout << "or the mvBlueFOX2 drivers have not been" << endl;
	  cout << "correctly installed." << endl;
          cout << "Skipping mvBlueFOX2 single image capture..." << endl;
	  return 1;
  }
  cout << "Using Device: " << pDev->product.readS() << endl;
  cout << "Serial: " << pDev->serial.readS() << endl << endl ;
  pDev->interfaceLayout.write(dilDeviceSpecific);
  pDev->open();

  // -----------------DeviceSpecific part with property adjusting-----------
  CameraSettingsBlueFOX cs( pDev );
  cs.expose_us.write(10000);
  // --------------------------DeviceSpecific part END----------------------

  FunctionInterface fi( pDev );
  fi.imageRequestSingle();
  const int iMaxWaitTime_ms = -1;
  int requestNr = fi.imageRequestWaitFor( iMaxWaitTime_ms );
  const Request* pRequest = fi.getRequest( requestNr );
  cout << "Image captured( " << pRequest->imagePixelFormat.readS() 
       << " " << pRequest->imageWidth.read() 
       << "x" << pRequest->imageHeight.read() 
       << " )" << endl;
  fi.imageRequestUnlock( requestNr );
}

Per utilizzare questo codice con telecamere mvBlueFOX3, bisogna adattare la parte relativa alla parametrizzazione all' Interface Layout GenICam. Le linee in rosso possono essere riutilizzate:

#include <iostream>
#include <mvIMPACT_CPP/mvIMPACT_acquire.h>
#include <mvIMPACT_CPP\mvIMPACT_acquire_GenICam.h>
 
using namespace std;
using namespace mvIMPACT::acquire;
using namespace mvIMPACT::acquire::GenICam;

//-----------------------------------------------------------------------------
int main( int /*argc*/, char* /*argv*/[] )
//-----------------------------------------------------------------------------
{
  DeviceManager devMgr;
  Device* pDev = devMgr.getDeviceByFamily("mvBlueFOX3");
  if (pDev == 0)
  {
	  cout << "There is currently no mvBlueFOX3 device connected," << endl;
	  cout << "or the mvBlueFOX3 drivers have not been" << endl;
	  cout << "correctly installed." << endl;
          cout << "Skipping mvBlueFOX3 single image capture..." << endl;
	  return 1;
  }
  cout << "Using Device: " << pDev->product.readS() << endl;
  cout << "Serial: " << pDev->serial.readS() << endl << endl ;
  // Note the different InterfaceLayout selection
  pDev->interfaceLayout.write(dilGenICam);
  pDev->open();

  // -----------------------GenICam part with property adjusting-------------
  // Note the different class name. This is a GenICam Class.
  AcquisitionControl ac(pDev);
  ac.exposureTime.write(10000);
  // ------------------------------GenICam part END--------------------------

  FunctionInterface fi( pDev );
  fi.imageRequestSingle();
  const int iMaxWaitTime_ms = -1;
  int requestNr = fi.imageRequestWaitFor( iMaxWaitTime_ms );
  const Request* pRequest = fi.getRequest( requestNr );
  cout << "Image captured( " << pRequest->imagePixelFormat.readS() 
       << " " << pRequest->imageWidth.read() 
       << "x" << pRequest->imageHeight.read() 
       << " )" << endl;
  fi.imageRequestUnlock( requestNr );
}

Questo codice è semplificato. Per esempio, è possibile collegare solo una periferica. Altrimenti il programma non saprebbe quale utilizzare. Esempi di programmazione più dettagliati sono disponibili nei manuali della API per: C,  C++, .NET.

L'utilizzo dell'Interface Layout GenICam offre ulteriori vantaggi:

E' possibile utilizzare lo stesso codice con qualsiasi periferica compatibile con USB3 Vision / GigE Vision / GenICam! Questa è la principale ragione per cui è stato sviluppato un driver unificato mvGenTL_Acquire per tutti questi prodotti.

Potrebbero anche non essere necessariamente telecamere MATRIX VISION. Modificando, ad esempio, la seguente linea nel codice precedente da

Device* pDev = devMgr.getDeviceByFamily("mvBlueFOX3");

a

Device* pDev = devMgr.getDeviceByFamily("GigEVision");

sarà possibile utilizzare una telecamera compatibile con GigE Vision come la mvBlueCOUGAR-X con lo stesso codice.

E' quindi possibile capire trarre beneficio dagli standard in questione. Si ha libera scelta per l'hardware senza essere legato ad uno specifico produttore. Per questo motivo è fondamentale considerare la compatibilità con gli standard quandi si scelgono le periferiche per le proprie applicazioni.

Torna indietro