Qt + OpenCV。 CvCaptureのような新しいGigEネットワークカメラアクセスインターフェイスデバイス

ヘンリー8世が次の妻に言ったように、「私は長い間あなたを抱きしめません...」

この投稿は、以前の記事「Qt + OpenCV」の小さな拡張です CvCapture(ビデオキャプチャデバイス)のランタイムとウィジェット。

親愛なる読者がビデオカメラを購入し、そのサポートがOpenCVライブラリによって提供されていない場合、および必要に応じてそれを操作する方法が動揺しないようにしてください。

最初に、彼らが提示したもの、または彼ら自身が無知で購入したものを調査します。

  1. GigEインターフェースはSDKでサポートされており、SDKは無料で入手できるか、製品とともに提供されます。 最初のプラス!
  2. ドキュメントは多かれ少なかれ意味があります。 またラッキー!
  3. 例があります! うわー...プラス!


だから、Smartek Giganetix GC1921Mカメラを手に入れて、このリストのプラスに「幸運」になった

SDKメソッドは機能しますが、どういうわけか...コードは部分的に閉じられています。 プログラマのレベルはコードスニペットから明らかになりました
... if (m_selectedDevice->IsConnected()){ m_disconnectAct->setEnabled(true); m_fwUpdateAct->setEnabled(true); } ...
      
      





「何が悪いの?」という質問があった場合、タイムマシンでソビエト大学に送ることはできません。 :)

はい、大丈夫です。 接続し、ストリームを受け入れ、切断するだけです。 幸いなことに、例が用意されています。



独自のビデオキャプチャデバイスの実装オプション。



BSDライセンスの下で配布されたコードの OpenCVライブラリの開発者に感謝します。

バージョン2.4.2について話します。

modules / highgui / srcディレクトリのソースコードの一部を学習します。 ご覧のとおり、すべてがシンプルです。 同様のモジュール(cap_pvapi.cppなど)を単純にコピーしてcap_giganetix.cppを自分のデバイスにし、適切な変更を加え、precomp.hppコードとcmakeの対応するディレクティブファイルに変更(新しいメソッドと列挙列挙要素)を加えて、ビルドを実行できます。

これが最初の方法です。 主な欠点は、バージョンごとにすべてが変更され、新しいリリースの再構築が避けられないことです。

OpenCVの構造と互換性のある新しいデバイス用の独自のCvCaptuteの実装という、より安定したオプションもあります。 プラスは、開発者がこのカヌーすべてをすべての収益を別のライブラリに配置し、依存関係の要件に従って、SDKを新しいデバイスとOpenCVの両方にダウンロードすることです。

マイナス面は、いつものように、「Pig in a poke」の存在です。これは、CvCaptureの隠された構造のOpenCV開発者側の実装です。

最後のオプションを考えてみましょう。



CvCaptureタイプの外部ビデオキャプチャデバイスライブラリ。


当初、この単語は 、OpenCVファイルのソースおよびヘッダーの列挙値であるマクロと互換性ありました。

macros.hpp
 #ifndef MACROS_HPP #define MACROS_HPP #define QTGIG_HEARTBEAT_TIME (12000.0) #define QTGIG_MAX_WAIT_TIME (2.0) #define QTGIG_IMG_WAIT_TIME (3.0) #define CV_CAP_GIGANETIX 1300 // GigE additional for highgui_c.h //enum { #define CV_CAP_PROP_GIGA_FRAME_SENS_WIDTH 40 #define CV_CAP_PROP_GIGA_FRAME_SENS_HEIGH 41 #define CV_CAP_PROP_GIGA_FRAME_WIDTH_MAX 42 #define CV_CAP_PROP_GIGA_FRAME_HEIGH_MAX 43 #define CV_CAP_PROP_GIGA_FRAME_OFFSET_X 44 #define CV_CAP_PROP_GIGA_FRAME_OFFSET_Y 45 //}; //precomp.hpp double #define __BEGIN__ __CV_BEGIN__ #define __END__ __CV_END__ #define EXIT __CV_EXIT__ #endif // MACROS_HPP
      
      







プロット
 //precomp.hpp double #define __BEGIN__ __CV_BEGIN__ #define __END__ __CV_END__ #define EXIT __CV_EXIT__
      
      



OpenCV モジュールを開発するための規則にコードを導きます 。 チャーターで奇妙な修道院に入らないでください!

そして、デバイスにいくつかのプロパティを追加しました。

カメラのSDK関数のラッパーメソッドを作成します。 これにより、開発者が独自のSDKを編集できるため、コードの変更が最小限に抑えられます。 これは良いスタイルだと思います。



gige_wrapper.h
 #ifndef GIGE_WRAPPER_H #define GIGE_WRAPPER_H /** \module GIGA_WRAPPER \brief Smartek Giganetix Cameras wrapper */ #include <GigEVisionSDK.h> namespace gigew { /*----------------------------------------------------------------------------*/ /** \internal \fn bool gigew::wrprInitGigEVisionAPI(); \brief Wrapper to GigEVisionAPI function gige::InitGigEVisionAPI () \return true - success See \a gigew::wrprExitGigEVisionAPI */ bool wrprInitGigEVisionAPI(); /*----------------------------------------------------------------------------*/ /** \internal \fn void gigew::wrprExitGigEVisionAPI() \brief Wrapper to GigEVisionAPI function gige::ExitGigEVisionAPI () \return true -- success See \a gigew::wrprInitGigEVisionAPI */ bool wrprExitGigEVisionAPI(); //   ... } //namespace gigew #endif // GIGE_WRAPPER_H
      
      









そして、実際には、デバイス自体(cap_giganetix.h)
 #ifndef CAP_GIGANENIX_H #define CAP_GIGANENIX_H #include <opencv2/highgui/highgui_c.h> #include "GigEVisionSDK.h" #include "../../common/macros.hpp" #include <QObject> #ifdef HAVE_GIGE_API #if !defined WIN32 && !defined _WIN32 && !defined _LINUX #define _LINUX #endif #if defined(_x64) || defined (__x86_64) || defined (_M_X64) #define _x64 1 #elif defined(_x86) || defined(__i386) || defined (_M_IX86) #define _x86 1 #endif /*----------------------------------------------------------------------------*/ /** \internal \struct CvCapture \brief Copy OpenCV CvCapture internal release. */ struct CvCapture { virtual ~CvCapture() {} virtual double getProperty(int) { return 0; } virtual bool setProperty(int, double) { return 0; } virtual bool grabFrame() { return true; } virtual IplImage* retrieveFrame(int) { return 0; } virtual int getCaptureDomain() { return CV_CAP_ANY; } // Return the type of the capture object: CV_CAP_VFW, etc... }; /*----------------------------------------------------------------------------*/ /** \internal \class CvCaptureCAM_Giganetix \brief Capturing video from camera via Smartec Giganetix GigEVisualSDK */ class Q_DECL_EXPORT CvCaptureCAM_Giganetix : public CvCapture { public: CvCaptureCAM_Giganetix(); virtual ~CvCaptureCAM_Giganetix(); virtual bool open( int index ); virtual void close(); virtual double getProperty(int); virtual bool setProperty(int, double); virtual bool grabFrame(); virtual IplImage* retrieveFrame(int); virtual int getCaptureDomain() { return CV_CAP_GIGANETIX; } bool start (); bool stop (); protected: void init (); void grabImage (); gige::IGigEVisionAPI m_api; bool m_api_on; gige::IDevice m_device; bool m_active; IplImage* m_raw_image; UINT32 m_rawImagePixelType; bool m_monocrome; }; /*----------------------------------------------------------------------------*/ Q_DECL_EXPORT CvCapture* cvCreateCameraCapture_Giganetix( int index ); /*----------------------------------------------------------------------------*/ #endif #endif // CQTGIGEVISIONCAPTURE_H
      
      







struct CvCapture



は、OpenCVソースコード(ディレクトリモジュール/ highgui / src 、ファイルprecomp.hpp )から取得されることに注意してください。 ここに、ライブラリのボトルネックがあります!



クラスとメソッドcvCreateCameraCapture_Giganetix



の実装を記述します。

プロジェクトのアーカイブはリンクを取る

open



メソッドのコードのみを提供します。

 ... /*----------------------------------------------------------------------------*/ bool CvCaptureCAM_Giganetix::open( int index ) { bool b_ret = m_api_on; CV_FUNCNAME("CvCaptureCAM_Giganetix::open"); __BEGIN__; if(b_ret) b_ret = m_api.IsValid (); if(b_ret ) { m_api->FindAllDevices (QTGIG_MAX_WAIT_TIME); //TODO - serch device as DevicesList member gige::DevicesList DevicesList = m_api->GetAllDevices (); m_device = 0; b_ret = false; for (int i = 0; i < (int) DevicesList.size() && !b_ret; i++) { if((b_ret = i == index)) { m_device = DevicesList[i]; b_ret = m_device->Connect (); if(b_ret) { b_ret = m_device->SetStringNodeValue("AcquisitionStatusSelector", "AcquisitionActive") && m_device->SetStringNodeValue ("TriggerMode", "Off") && m_device->SetStringNodeValue ("AcquisitionMode", "Continuous") && m_device->SetIntegerNodeValue ("AcquisitionFrameCount", 20) ; } } } // for } if(!b_ret) { CV_ERROR(CV_StsError, "Giganetix: Error cannot find camera\n"); close (); } else { start (); } __END__; return b_ret; } ...
      
      





OpenCVのプログラミングスタイルに従ってマクロを使用する方法を示します。



プロジェクトファイルは、SDKとOpenCVにアクセスできる動的に接続されたライブラリとして設計します。
 #----------------------------------------------------------- TARGET = QtGigEVisionCapture TEMPLATE = lib #CONFIG += release #----------------------------------------------------------- DEFINES += QTGIGEVISION_LIBRARY \ HAVE_GIGE_API #----------------------------------------------------------- SOURCES += \ ../../common/QtGigEVision_global.cpp \ cap_giganetix.cpp \ gige_wrapper.cpp HEADERS +=\ ../../common/QtGigEvision_global.h \ ../../common/macros.hpp \ cap_giganetix.h \ gige_wrapper.h #----------------------------------------------------------- unix:!symbian: target.path = /usr/lib INSTALLS += target #----------------------------------------------------------- unix:!macx:!symbian: LIBS += -L/usr/local/lib/ -lGigEVisionSDK INCLUDEPATH += /usr/local/include/GigEVisionSDK/gige_cpp \ /usr/local/include/GigEVisionSDK/gige_c DEPENDPATH += /usr/local/include/GigEVisionSDK/gige_cpp \ /usr/local/include/GigEVisionSDK/gige_c #----------------------------------------------------------- unix: LIBS += -L/usr/lib/ -lopencv_core -lopencv_highgui INCLUDEPATH += /usr/include/opencv2/core \ /usr/include/opencv2/highgui DEPENDPATH += /usr/include/opencv2/core \ /usr/include/opencv2/highgui
      
      









スーパーユーザー権限で、ディレクトリ/ usr / libに新しいライブラリへのリンクを配置し、テストに進みます。



テストケース。



コード
 #include <QtGui/QApplication> #include "../../common/macros.hpp" #include <stdio.h> #include "cap_giganetix.h" void print_properties (CvCaptureCAM_Giganetix* cap) { if(cap) { printf("Device found.\n"); printf("Sensor Width = %d.\n", (int)cap->getProperty (CV_CAP_PROP_GIGA_FRAME_SENS_WIDTH)); printf("Sensor Height = %d.\n", (int)cap->getProperty (CV_CAP_PROP_GIGA_FRAME_SENS_HEIGH)); printf("Offset X = %d.\n", (int)cap->getProperty (CV_CAP_PROP_GIGA_FRAME_OFFSET_X)); printf("Offset Y = %d.\n", (int)cap->getProperty (CV_CAP_PROP_GIGA_FRAME_OFFSET_Y)); printf("Width = %d.\n", (int)cap->getProperty (CV_CAP_PROP_FRAME_WIDTH)); printf("Height = %d.\n", (int)cap->getProperty (CV_CAP_PROP_FRAME_HEIGHT)); printf("Frame Count = %d.\n", (int)cap->getProperty (CV_CAP_PROP_FRAME_COUNT)); printf("Gain = %d.\n", (int)cap->getProperty (CV_CAP_PROP_GAIN)); } } int main(int argc, char *argv[]) { QApplication a(argc, argv); CvCapture* capture = cvCreateCameraCapture_Giganetix(0); CvCaptureCAM_Giganetix* cap = (CvCaptureCAM_Giganetix*)capture; int i_width, i_height, i_offX, i_offY; if(cap) { i_width = (int)capture->getProperty (CV_CAP_PROP_FRAME_WIDTH); i_height = (int)capture->getProperty (CV_CAP_PROP_FRAME_HEIGHT); i_offX = (int)capture->getProperty (CV_CAP_PROP_GIGA_FRAME_OFFSET_X); i_offY = (int)capture->getProperty (CV_CAP_PROP_GIGA_FRAME_OFFSET_Y); printf("-------------------------\n"); print_properties (cap); printf("-------------------------\n"); ... INT64 i = 0; cvNamedWindow("Frame",0); while(1) { if(i == 1000) { printf("------ Reset to original -------\n"); (void)capture->setProperty (CV_CAP_PROP_FRAME_WIDTH, i_width); (void)cap->setProperty (CV_CAP_PROP_FRAME_HEIGHT, i_height); (void)capture->setProperty (CV_CAP_PROP_GIGA_FRAME_OFFSET_X, i_offX); (void)cap->setProperty (CV_CAP_PROP_GIGA_FRAME_OFFSET_Y, i_offY); print_properties (cap); } i++; IplImage* frame = cvQueryFrame (capture); if(frame) cvShowImage ("Frame",frame); if((cvWaitKey (3) == 27)) break; } cvDestroyWindow("Frame"); cvReleaseCapture(&capture); } return 0;//a.exec(); }
      
      









よろしく

頑張って!




All Articles