Path: blob/master/modules/videoio/src/cap_giganetix.cpp
16339 views
////////////////////////////////////////////////////////////////////////////////////////1//2// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.3//4// By downloading, copying, installing or using the software you agree to this license.5// If you do not agree to this license, do not download, install,6// copy or use the software.7//8//9// Intel License Agreement10// For Open Source Computer Vision Library11//12// Copyright (C) 2000, Intel Corporation, all rights reserved.13// Third party copyrights are property of their respective owners.14//15// Redistribution and use in source and binary forms, with or without modification,16// are permitted provided that the following conditions are met:17//18// * Redistribution's of source code must retain the above copyright notice,19// this list of conditions and the following disclaimer.20//21// * Redistribution's in binary form must reproduce the above copyright notice,22// this list of conditions and the following disclaimer in the documentation23// and/or other materials provided with the distribution.24//25// * The name of Intel Corporation may not be used to endorse or promote products26// derived from this software without specific prior written permission.27//28// This software is provided by the copyright holders and contributors "as is" and29// any express or implied warranties, including, but not limited to, the implied30// warranties of merchantability and fitness for a particular purpose are disclaimed.31// In no event shall the Intel Corporation or contributors be liable for any direct,32// indirect, incidental, special, exemplary, or consequential damages33// (including, but not limited to, procurement of substitute goods or services;34// loss of use, data, or profits; or business interruption) however caused35// and on any theory of liability, whether in contract, strict liability,36// or tort (including negligence or otherwise) arising in any way out of37// the use of this software, even if advised of the possibility of such damage.38//39//4041//42// The code has been contributed by Vladimir N. Litvinenko on 2012 Jul43// mailto:[email protected]44//4546#include "precomp.hpp"47#include <GigEVisionSDK.h>48#include <GigEVisionSDK.cpp>4950#ifdef _WIN3251#include <io.h>52#else53#include <stdio.h>54#endif5556#ifdef NDEBUG57#define CV_WARN(message)58#else59#define CV_WARN(message) fprintf(stderr, "warning: %s (%s:%d)\n", message, __FILE__, __LINE__)60#endif6162#define QTGIG_HEARTBEAT_TIME (12000.0)63#define QTGIG_MAX_WAIT_TIME (2.0)64#define QTGIG_IMG_WAIT_TIME (3.0)6566/*----------------------------------------------------------------------------*/67/**68\internal69\fn bool wrprInitGigEVisionAPI();70\brief Wrapper to GigEVisionAPI function gige::InitGigEVisionAPI ()71\return true -- success72See \a wrprExitGigEVisionAPI7374*/75bool76wrprInitGigEVisionAPI()77{78CV_FUNCNAME("wrprInitGigEVisionAPI");79__BEGIN__;8081try {82gige::InitGigEVisionAPI ();83} catch(...) {84CV_ERROR(CV_StsError, "GigEVisionAPI: initialization (InitGigEVisionAPI()) failed.\n");85}86__END__;87return true;88}8990/*----------------------------------------------------------------------------*/91/**92\internal93\fn void wrprExitGigEVisionAPI()94\brief Wrapper to GigEVisionAPI function gige::ExitGigEVisionAPI ()95\return true -- success96See \a wrprInitGigEVisionAPI9798*/99bool100wrprExitGigEVisionAPI()101{102CV_FUNCNAME("wrprExitGigEVisionAPI");103__BEGIN__;104105try {106gige::ExitGigEVisionAPI ();107} catch(...) {108CV_ERROR(CV_StsError, "GigEVisionAPI: finalization (ExitGigEVisionAPI()) failed.\n");109return false;110}111__END__;112return true;113}114115116/*----------------------------------------------------------------------------*/117/**118\internal119\fn gige::IGigEVisionAPI wrprGetGigEVisionAPI()120\brief Wrapper to GigEVisionAPI function gige::GetGigEVisionAPI ()121\return item of gige::IGigEVisionAPI type122See \a wrprInitGigEVisionAPI, \a gige::IGigEVisionAPI123*/124gige::IGigEVisionAPI125wrprGetGigEVisionAPI()126{127128gige::IGigEVisionAPI b_ret = 0;129130CV_FUNCNAME("wrprGetGigEVisionAPI");131__BEGIN__;132133try {134b_ret = gige::GetGigEVisionAPI ();135} catch(...) {136CV_ERROR(CV_StsError, "GigEVisionAPI: API instance (from GetGigEVisionAPI()) failed.\n");137}138139__END__;140141return b_ret;142}143144145/*----------------------------------------------------------------------------*/146/**147\internal148\fn bool wrprUnregisterCallback( const gige::IGigEVisionAPI* api, gige::ICallbackEvent* eventHandler)149\brief Wrapper to GigEVisionAPI function150\param api151\param eventHandler152\return true - success, else - false153See \a wrprInitGigEVisionAPI, \a gige::IGigEVisionAPI154155*/156bool157wrprUnregisterCallback( const gige::IGigEVisionAPI* api, gige::ICallbackEvent* eventHandler)158{159bool b_ret = api != NULL;160161if(b_ret) b_ret = api->IsValid ();162163CV_FUNCNAME("wrprUnregisterCallback");164__BEGIN__;165166if(b_ret)167{168if(eventHandler != NULL)169{170try {171b_ret = ((gige::IGigEVisionAPIInterface*)api)->UnregisterCallback (eventHandler);172} catch(...) {173CV_ERROR(CV_StsError, "GigEVisionAPI: API unregister callback function (from UnregisterCallback()) failed.\n");174b_ret = false;175}176}177}178__END__;179180return (b_ret);181}182183184/*----------------------------------------------------------------------------*/185/**186\internal187\fn bool wrprDeviceIsConnect( gige::IDevice& device )188\brief Wrapper to GigEVisionAPI function IDevice::IsConnected()189\param device - selected device190\return true - device connected191*/192bool193wrprDeviceIsConnect( gige::IDevice& device )194{195bool b_ret = device != NULL;196197CV_FUNCNAME("wrprDeviceIsConnect");198__BEGIN__;199200if(b_ret)201{202try {203b_ret = device->IsConnected ();204} catch (...) {205CV_ERROR(CV_StsError, "GigEVisionAPI: API device connection state (from IsConnected()) failed.\n");206b_ret = false;207}208}209__END__;210211return (b_ret);212}213214215/*----------------------------------------------------------------------------*/216/**217\internal218\fn bool wrprDeviceIsValid( gige::IDevice& device )219\brief Wrapper to GigEVisionAPI function IDevice::Connect()220\param device - selected device221\return true - device valid222223*/224bool225wrprDeviceIsValid( gige::IDevice& device )226{227bool b_ret = device != NULL;228229CV_FUNCNAME("wrprDeviceIsConnect");230__BEGIN__;231232if(b_ret)233{234try {235b_ret = device.IsValid ();236} catch (...) {237CV_ERROR(CV_StsError, "GigEVisionAPI: API device validation state (from IsValid()) failed.\n");238b_ret = false;239}240}241__END__;242243return (b_ret);244}245246247/*----------------------------------------------------------------------------*/248/**249\internal250\fn bool wrprDeviceDisconnect ( gige::IDevice& device )251\brief Wrapper to GigEVisionAPI function IDevice::Disconnect()252\param device - selected device253\return true - device valid254255*/256bool257wrprDeviceDisconnect ( gige::IDevice& device )258{259bool b_ret = device != NULL;260261CV_FUNCNAME("wrprDeviceDisconnect");262__BEGIN__;263264if(b_ret)265{266try {267device->Disconnect ();268} catch (...) {269CV_ERROR(CV_StsError, "GigEVisionAPI: API device disconnect (from Disconnect()) failed.\n");270b_ret = false;271}272}273274__END__;275276return (b_ret);277}278279280/*----------------------------------------------------------------------------*/281/*----------------------------------------------------------------------------*/282/**283\internal284\class CvCaptureCAM_Giganetix285\brief Capturing video from camera via Smartec Giganetix (use GigEVisualSDK library).286*/287288class CvCaptureCAM_Giganetix : public CvCapture289{290public:291CvCaptureCAM_Giganetix();292virtual ~CvCaptureCAM_Giganetix();293294virtual bool open( int index );295virtual void close();296virtual double getProperty(int) const CV_OVERRIDE;297virtual bool setProperty(int, double) CV_OVERRIDE;298virtual bool grabFrame() CV_OVERRIDE;299virtual IplImage* retrieveFrame(int) CV_OVERRIDE;300virtual int getCaptureDomain() CV_OVERRIDE301{302return CV_CAP_GIGANETIX;303}304305bool start ();306bool stop ();307308protected:309310void init ();311void grabImage ();312313gige::IGigEVisionAPI m_api;314bool m_api_on;315gige::IDevice m_device;316bool m_active;317318IplImage* m_raw_image;319UINT32 m_rawImagePixelType;320bool m_monocrome;321322};323/*----------------------------------------------------------------------------*/324/*----------------------------------------------------------------------------*/325void326CvCaptureCAM_Giganetix::init ()327{328m_monocrome = m_active = m_api_on = false;329m_api = 0;330m_device = 0;331m_raw_image = 0;332m_rawImagePixelType = 0;333}334335/*----------------------------------------------------------------------------*/336CvCaptureCAM_Giganetix::CvCaptureCAM_Giganetix()337{338init ();339340m_api_on = wrprInitGigEVisionAPI ();341342if(m_api_on)343{344if((m_api = wrprGetGigEVisionAPI ()) != NULL)345{346m_api->SetHeartbeatTime (QTGIG_HEARTBEAT_TIME);347}348}349}350351/*----------------------------------------------------------------------------*/352CvCaptureCAM_Giganetix::~CvCaptureCAM_Giganetix()353{354close();355}356/*----------------------------------------------------------------------------*/357void358CvCaptureCAM_Giganetix::close()359{360stop ();361362(void)wrprDeviceDisconnect(m_device);363364(void)wrprExitGigEVisionAPI ();365366if(m_raw_image) cvReleaseImageHeader(&m_raw_image);367368init ();369}370371/*----------------------------------------------------------------------------*/372bool373CvCaptureCAM_Giganetix::open( int index )374{375bool b_ret = m_api_on;376377CV_FUNCNAME("CvCaptureCAM_Giganetix::open");378__BEGIN__;379380if(b_ret)381b_ret = m_api.IsValid ();382383if(b_ret )384{385m_api->FindAllDevices (QTGIG_MAX_WAIT_TIME);386387//TODO - serch device as DevicesList member388gige::DevicesList DevicesList = m_api->GetAllDevices ();389390m_device = 0;391b_ret = false;392393for (int i = 0; i < (int) DevicesList.size() && !b_ret; i++)394{395b_ret = (i == index);396if(b_ret)397{398m_device = DevicesList[i];399b_ret = m_device->Connect ();400401if(b_ret)402{403b_ret =404m_device->SetStringNodeValue("AcquisitionStatusSelector", "AcquisitionActive")405&&406m_device->SetStringNodeValue ("TriggerMode", "Off")407&&408m_device->SetStringNodeValue ("AcquisitionMode", "Continuous")409&&410m_device->SetIntegerNodeValue ("AcquisitionFrameCount", 20)411;412}413}414} // for415}416417if(!b_ret)418{419CV_ERROR(CV_StsError, "Giganetix: Error cannot find camera\n");420close ();421} else {422start ();423}424425__END__;426427return b_ret;428}429430/*----------------------------------------------------------------------------*/431void432CvCaptureCAM_Giganetix::grabImage ()433{434CV_FUNCNAME("CvCaptureCAM_Giganetix::grabImage");435__BEGIN__;436437if(wrprDeviceIsValid(m_device) && wrprDeviceIsConnect(m_device))438{439if(!m_device->IsBufferEmpty ())440{441gige::IImageInfo imageInfo;442m_device->GetImageInfo (&imageInfo);443assert(imageInfo.IsValid());444445if (m_device->GetPendingImagesCount() == 1)446{447UINT32 newPixelType;448UINT32 newWidth, newHeight;449450imageInfo->GetPixelType(newPixelType);451imageInfo->GetSize(newWidth, newHeight);452453//TODO - validation of image exists454bool b_validation = m_raw_image != NULL;455if(b_validation)456{457b_validation =458m_raw_image->imageSize == (int)(imageInfo->GetRawDataSize ())459&&460m_rawImagePixelType == newPixelType;461} else {462if(m_raw_image) cvReleaseImageHeader(&m_raw_image);463}464465m_rawImagePixelType = newPixelType;466m_monocrome = GvspGetBitsPerPixel((GVSP_PIXEL_TYPES)newPixelType) == IPL_DEPTH_8U;467468try {469if (m_monocrome)470{471//TODO - For Mono & Color BayerRGB raw pixel types472if (!b_validation)473{474m_raw_image = cvCreateImageHeader (cvSize((int)newWidth, (int)newHeight),IPL_DEPTH_8U,1);475m_raw_image->origin = IPL_ORIGIN_TL;476m_raw_image->dataOrder = IPL_DATA_ORDER_PIXEL;477m_raw_image->widthStep = newWidth;478}479// Copy image.480// ::memcpy(m_raw_image->imageData, imageInfo->GetRawData (), imageInfo->GetRawDataSize ());481482//TODO - Set pointer to image !483m_raw_image->imageData = (char*)(imageInfo->GetRawData ());484}485486if (!m_monocrome && newPixelType == GVSP_PIX_RGB8_PACKED)487{488//TODO - 24 bit RGB color image.489if (!b_validation)490{491m_raw_image = cvCreateImageHeader (cvSize((int)newWidth, (int)newHeight), IPL_DEPTH_32F, 3);492m_raw_image->origin = IPL_ORIGIN_TL;493m_raw_image->dataOrder = IPL_DATA_ORDER_PIXEL;494m_raw_image->widthStep = newWidth * 3;495}496m_raw_image->imageData = (char*)(imageInfo->GetRawData ());497}498} catch (...) {499CV_ERROR(CV_StsError, "Giganetix: failed to queue a buffer on device\n");500close ();501}502} else {503//TODO - all other pixel types504m_raw_image = 0;505CV_WARN("Giganetix: Undefined image pixel type\n");506}507m_device->PopImage (imageInfo);508m_device->ClearImageBuffer ();509}510}511512__END__;513}514515/*----------------------------------------------------------------------------*/516bool517CvCaptureCAM_Giganetix::start ()518{519CV_FUNCNAME("CvCaptureCAM_Giganetix::start");520__BEGIN__;521522m_active = wrprDeviceIsValid(m_device) && wrprDeviceIsConnect(m_device);523524if(m_active)525{526(void)m_device->SetIntegerNodeValue("TLParamsLocked", 1);527(void)m_device->CommandNodeExecute("AcquisitionStart");528m_active = m_device->GetBooleanNodeValue("AcquisitionStatus", m_active);529}530531if(!m_active)532{533CV_ERROR(CV_StsError, "Giganetix: Cannot open camera\n");534close ();535}536537__END__;538539return m_active;540}541542/*----------------------------------------------------------------------------*/543bool544CvCaptureCAM_Giganetix::stop ()545{546if (!m_active) return true;547548CV_FUNCNAME("CvCaptureCAM_Giganetix::stop");549__BEGIN__;550551if(wrprDeviceIsValid(m_device) && wrprDeviceIsConnect(m_device))552{553(void)m_device->GetBooleanNodeValue("AcquisitionStatus", m_active);554555if(m_active)556{557(void)m_device->CommandNodeExecute("AcquisitionStop");558(void)m_device->SetIntegerNodeValue("TLParamsLocked", 0);559m_device->ClearImageBuffer ();560(void)m_device->GetBooleanNodeValue("AcquisitionStatus", m_active);561}562}563564if(m_active)565{566CV_ERROR(CV_StsError, "Giganetix: Improper closure of the camera\n");567close ();568}569__END__;570571return !m_active;572}573574/*----------------------------------------------------------------------------*/575bool576CvCaptureCAM_Giganetix::grabFrame()577{578bool b_ret =579wrprDeviceIsValid(m_device)580&&581wrprDeviceIsConnect(m_device);582583if(b_ret) grabImage ();584585return b_ret;586}587588589/*----------------------------------------------------------------------------*/590IplImage*591CvCaptureCAM_Giganetix::retrieveFrame(int)592{593return (594wrprDeviceIsValid(m_device) && wrprDeviceIsConnect(m_device) ?595m_raw_image :596NULL597);598}599600/*----------------------------------------------------------------------------*/601double602CvCaptureCAM_Giganetix::getProperty( int property_id ) const603{604double d_ret = -1.0;605INT64 i;606607if(wrprDeviceIsConnect(m_device))608{609switch ( property_id )610{611case CV_CAP_PROP_FRAME_WIDTH:612m_device->GetIntegerNodeValue ("Width", i);613d_ret = i;614break;615case CV_CAP_PROP_FRAME_HEIGHT:616m_device->GetIntegerNodeValue ("Height", i);617d_ret = i;618break;619case CV_CAP_PROP_GIGA_FRAME_OFFSET_X:620m_device->GetIntegerNodeValue ("OffsetX", i);621d_ret = i;622break;623case CV_CAP_PROP_GIGA_FRAME_OFFSET_Y:624m_device->GetIntegerNodeValue ("OffsetY", i);625d_ret = i;626break;627case CV_CAP_PROP_GIGA_FRAME_WIDTH_MAX:628m_device->GetIntegerNodeValue ("WidthMax", i);629d_ret = i;630break;631case CV_CAP_PROP_GIGA_FRAME_HEIGH_MAX:632m_device->GetIntegerNodeValue ("HeightMax", i);633d_ret = i;634break;635case CV_CAP_PROP_GIGA_FRAME_SENS_WIDTH:636m_device->GetIntegerNodeValue ("SensorWidth", i);637d_ret = i;638break;639case CV_CAP_PROP_GIGA_FRAME_SENS_HEIGH:640m_device->GetIntegerNodeValue ("SensorHeight", i);641d_ret = i;642break;643case CV_CAP_PROP_FRAME_COUNT:644m_device->GetIntegerNodeValue ("AcquisitionFrameCount", i);645d_ret = i;646break;647case CV_CAP_PROP_EXPOSURE:648m_device->GetFloatNodeValue ("ExposureTime",d_ret);649break;650case CV_CAP_PROP_GAIN :651m_device->GetFloatNodeValue ("Gain",d_ret);652break;653case CV_CAP_PROP_TRIGGER :654bool b;655m_device->GetBooleanNodeValue ("TriggerMode",b);656d_ret = (double)b;657break;658case CV_CAP_PROP_TRIGGER_DELAY :659m_device->GetFloatNodeValue ("TriggerDelay",d_ret);660break;661default : ;662}663}664665return d_ret;666}667668/*----------------------------------------------------------------------------*/669bool670CvCaptureCAM_Giganetix::setProperty( int property_id, double value )671{672bool b_ret = wrprDeviceIsConnect(m_device);673674if(b_ret)675{676bool b_val = m_active;677678switch ( property_id )679{680case CV_CAP_PROP_FRAME_WIDTH:681stop ();682b_ret = m_device->SetIntegerNodeValue ("Width", (INT64)value);683if(b_val) start ();684break;685case CV_CAP_PROP_GIGA_FRAME_WIDTH_MAX:686stop ();687b_ret = m_device->SetIntegerNodeValue ("WidthMax", (INT64)value);688if(b_val) start ();689break;690case CV_CAP_PROP_GIGA_FRAME_SENS_WIDTH:691stop ();692b_ret = m_device->SetIntegerNodeValue ("SensorWidth", (INT64)value);693if(b_val) start ();694break;695case CV_CAP_PROP_FRAME_HEIGHT:696stop ();697b_ret = m_device->SetIntegerNodeValue ("Height", (INT64)value);698if(b_val) start ();699break;700case CV_CAP_PROP_GIGA_FRAME_HEIGH_MAX:701stop ();702b_ret = m_device->SetIntegerNodeValue ("HeightMax", (INT64)value);703if(b_val) start ();704break;705case CV_CAP_PROP_GIGA_FRAME_SENS_HEIGH:706stop ();707b_ret = m_device->SetIntegerNodeValue ("SensorHeight", (INT64)value);708if(b_val) start ();709break;710case CV_CAP_PROP_GIGA_FRAME_OFFSET_X: {711INT64 w, wmax, val = (INT64)value;712if((b_ret = m_device->GetIntegerNodeValue ("Width", w)))713if((b_ret = m_device->GetIntegerNodeValue ("WidthMax", wmax)))714b_ret = m_device->SetIntegerNodeValue ("OffsetX", (val + w) > wmax ? (wmax - w) : val);715} break;716case CV_CAP_PROP_GIGA_FRAME_OFFSET_Y: {717INT64 h, hmax, val = (INT64)value;718if((b_ret = m_device->GetIntegerNodeValue ("Height", h)))719if((b_ret = m_device->GetIntegerNodeValue ("HeightMax", hmax)))720b_ret = m_device->SetIntegerNodeValue ("OffsetY", (val + h) > hmax ? (hmax - h) : val);721b_ret = m_device->SetIntegerNodeValue ("OffsetY", (INT64)value);722}723break;724case CV_CAP_PROP_EXPOSURE:725b_ret = m_device->SetFloatNodeValue ("ExposureTime",value);726break;727case CV_CAP_PROP_GAIN :728b_ret = m_device->SetFloatNodeValue ("Gain",value);729break;730case CV_CAP_PROP_TRIGGER :731b_ret = m_device->SetBooleanNodeValue ("TriggerMode",(bool)value);732break;733case CV_CAP_PROP_TRIGGER_DELAY :734stop ();735b_ret = m_device->SetFloatNodeValue ("TriggerDelay",value);736if(b_val) start ();737break;738default:739b_ret = false;740}741}742743return b_ret;744}745746747/*----------------------------------------------------------------------------*/748/*----------------------------------------------------------------------------*/749CvCapture*750cvCreateCameraCapture_Giganetix( int index )751{752CvCaptureCAM_Giganetix* capture = new CvCaptureCAM_Giganetix;753754if (!(capture->open( index )))755{756delete capture;757capture = NULL;758}759760return ((CvCapture*)capture);761}762763/*----------------------------------------------------------------------------*/764765766