画像処理コンポーネントの作成 (OpenRTM-aist-1.1, CMake, Linux Ubuntu 14.04)

はじめに

このケーススタディーでは、簡単な画像処理をコンポーネント化する方法 を紹介します。既存のカメラコンポーネントと画像表示コンポーネントを 利用し、カメラからの画像をj左右(または上下)に反転させる処理部分を コンポーネントとして作成してカメラの画像を反転させ表示するシステム を作成します。

画像を反転する処理は簡単に実装することができますが、ここではさらに 簡単のためにOpenCVライブラリを利用しより汎用性の高いRTコンポーネン トを作成します。

OpenCVとは

OpenCV (オープンシーブイ) とはかつてインテル が、現在はWillow Garageが開発・公開しているオープンソースのコン ピュータビジョン向けライブラリです。

Wikipediaより抜粋。

作成するRTコンポーネント

  • Flipコンポーネント: OpenCVライブラリが提供する様々な画像処理関数のうち、cvFlip() 関数を用いて画像の反転を行うRTコンポーネント。

cvFlip関数のRTコンポーネント化

入力された画像を左右または上下に反転し出力するRTコンポーネントを、 OpenCVライブラリのcvFlip関数を利用して作成します。作成および実行環 境はWindows上のVisual C++を想定しています。対象OpenRTM-aistのバー ジョンは 1.1 です。

作成手順はおおよそ以下のようになります。

  • 動作環境・開発環境についての確認
  • OpenCVとcvFlip関数についての確認
  • コンポーネントの仕様を決める
  • RTCBuilderを用いたソースコードのひな形の作成
  • アクティビティ処理の実装
  • コンポーネントの動作確認

動作環境の確認

Linux (ここでは Ubuntu 14.04 を仮定) 上に開発環境を構築します。

OpenRTM-aist のインストール

Choreonoid を利用する場合、以下のように PPA からOpenRTM-aistをインストールしてください。一括インストールスクリプトをすでに実行している場合、/etc/apt/sources.list の下の方に追記されている openrtm.org のリポジトリをコメントアウトした上で、 apt-get update してください。

 $ sudo add-apt-repository ppa:hrg/daily
 $ sudo apt-get update
 $ sudo apt-get install openrtm-aist openrtm-aist-dev doxygen

OpenRTP のインストール

こちらのURL からLinux版のOpenRTP(コンポーネント開発ツール、システム開発ツール統合環境) をダウンロード、インストールします。OepnRTPの実行にはJavaも必要となりますので default-jre パッケージをインストールします。

 $ apt-get install default-jre
 $ wget http://openrtm.org/pub/openrtp/packages/1.1.0.rc5v20150317/eclipse381-openrtp110rc5v20150317-ja-linux-gtk-x86_64.tar.gz
 $ tar xvzf eclipse381-openrtp110rc5v20150317-ja-linux-gtk-x86_64.tar.gz
 $ cd eclipse
 $ ./openrtp

eclipse起動後、RTSystemEditorでネームサーバに接続できない場合があります。その場合、/etc/hosts の localhost の行に自ホスト名を追記してください。

 $ hostname
 ubuntu1404 ← ホスト名は ubuntu1404
 $ sudo vi /etc/hosts

 127.0.0.1       localhost
 を以下のように変更
 127.0.0.1       localhost ubuntu1404

OpenCVおよびOpenCVコンポーネントのインストール

OpenCVおよびOpenCVのコンポーネントをインストールします。

まず、Ubuntuが提供しているOpenCVのパッケージを下記のようにインストールします。

 $ sudo apt-get install libopencv-dev libcv2.4 libcvaux2.4 libhighgui2.4

OpenCV RTCのパッケージは下記URLにありますので、手動でダウンロードして、dpkgコマンドでインストールします。

 $ wget http://openrtm.org/pub/Linux/ubuntu/dists/trusty/main/binary-amd64/imageprocessing-1.1.0.deb
 $ sudo dpkg -i imageprocessing-1.1.0.deb
 $ ls /usr/share/openrtm-1.1/components/c++/opencv-rtcs/
 AffineComp                       FlipComp               RockPaperScissorsComp
 Affine.so                        Flip.so                RockPaperScissors.so
 BackGroundSubtractionSimpleComp  HistogramComp          RotateComp
 BackGroundSubtractionSimple.so   Histogram.so           Rotate.so
 BinarizationComp                 HoughComp              ScaleComp
 Binarization.so                  Hough.so               Scale.so
 CameraViewerComp                 ImageCalibrationComp   SepiaComp
 CameraViewer.so                  ImageCalibration.so    Sepia.so
 ChromakeyComp                    ImageSubstractionComp  SubStractCaptureImageComp
 Chromakey.so                     ImageSubstraction.so   SubStractCaptureImage.so
 DilationErosionComp              ObjectTrackingComp     TemplateComp
 DilationErosion.so               ObjectTracking.so      Template.so
 EdgeComp                         OpenCVCameraComp       TranslateComp
 Edge.so                          OpenCVCamera.so        Translate.so
 FindcontourComp                  PerspectiveComp
 Findcontour.so                   Perspective.so

cvFlip関数について

cvFlip 関数は、OpenCVで標準的に用いられているIplImage型の画像デー タを垂直軸 (左右反転)、水平軸 (上下反転)、または両軸 (上下左右反転) に対して反転させます。関数プロトタイプと入出力の引数の意味は以下の 通りです。

 void cvFlip(IplImage* src, IplImage* dst=NULL, int flipMode=0);
 #define cvMirror cvFlip
  
 src       入力配列
 dst       出力配列。もしdst=NULLであれば、srcが上書きされます。
 flipMode 配列の反転方法の指定内容:
  flipMode = 0: X軸周りでの反転(上下反転)
  flipMode > 0: Y軸周りでの反転(左右反転)
  flipMode < 0: 両軸周りでの反転(上下左右反転)

コンポーネントの仕様

これから作成するコンポーネントをFlipコンポーネントと呼ぶことにします。

このコンポーネントは画像データ型の入力ポート (InPort) と、反転処理 した画像を出力するための出力ポート (OutPort) を持ちます。それぞれ のポートの名前を 入力ポート(InPort)名: originalImage, 出力ポー ト(OutPort)名: flippedImage とします。

OpenRTM-aistには OpenCVを使用したビジョン関連のコンポーネントがサ ンプルとして付属しています。これらのコンポーネントのデータポートは 画像の入出力に以下のような CameraImage 型を使用しています。

   struct CameraImage
     {
         /// Time stamp.
         Time tm;
         /// Image pixel width.
         unsigned short width;
         /// Image pixel height.
         unsigned short height;
         /// Bits per pixel.
         unsigned short bpp;
         /// Image format (e.g. bitmap, jpeg, etc.).
         string format;
         /// Scale factor for images, such as disparity maps,
         /// where the integer pixel value should be divided
         /// by this factor to get the real pixel value.
         double fDiv;
         /// Raw pixel data.
         sequence<octet> pixels;
     };

このFlipコンポーネントではこれらのサンプルコンポーネントとデータの やり取りができるよう同じくCameraImage型をInPortとOutPortに使用する ことにします。 CameraImage型はInterfaceDataTypes.idlで定義されており、C++であれば、 InterfaceDataTypesSkel.hをインクルードすると使えるようになります。

また、画像を反転させる方向は、左右反転、上下反転、上下左右反転の3 通りが有ります。これを実行時に指定できるように、RTコンポーネントの コンフィギュレーション機能を使用して指定できるようにします。 パラメータ名は flipMode という名前にします。

flipModeは cvFlip 関数の仕様に合わせて、型は int 型とし 上下反転、 左右反転、上下左右反転それぞれに0, 1, -1 を割り当てることにします。

flipModeの各値での画像処理のイメージを下図に示します。

cvFlip_and_FlipRTC.png
FlipコンポーネントのflipMode指定時の画像反転パターン

以上からFlipコンポーネントの仕様をまとめます。

コンポーネント名称 Flip
InPort
ポート名 originalImage
CameraImage
意味 入力画像
OutPort
ポート名 flippedImage
CameraImage
意味 反転された画像
Configuration
パラメータ名 flipMode
int
意味 反転モード
上下反転: 0
左右反転: 1
上下左右反転: -1

動作環境・開発環境

ここで動作環境および開発環境を確認しておきます。

OpenRTM-aist-1.1以降では、コンポーネントのビルドにCMakeを使用しま す。また、RTCのひな形生成ツール RTCBuilder では、ドキュメントを入 力してこれを Doxygen に処理させることで、コンポーネントのマニュア ルも自動で生成することができるようになっており、このたCMakeで Configureを行うときにDoxygenが要求されるため予めインストールしてお く必要があります。

Flipコンポーネントの雛型の生成

Flipコンポーネントの雛型の生成は、RTCBuilderを用いて行います。

RTCBuilderの起動

Eclipseでは、各種作業を行うフォルダを「ワークスペース」(Work Space)とよ び、原則としてすべての生成物はこのフォルダの下に保存されます。ワークス ペースはアクセスできるフォルダであれば、どこに作っても構いませんが、こ のチュートリアルでは以下のワークスペースを仮定します。

  • ~/workspace (/home/<ユーザ名>/workspace を意味する。)

eclipseを起動すると、ワークスペースの場所を尋ねられます。eclipseを最初に起動したとき、または -clean オプション付きで起動した場合は、デフォルトで上記のディレクトリが指定されますので、そのままOKボタンを押しておください。以下のようなWelcomeページが表示されます。


fig1-1EclipseInit.png
Eclipseの初期起動時の画面

Welcomeページはいまは必要ないので左上の「×」ボタンを押して閉じてください。

fig2-2PerspectiveSwitch.png
パースペクティブの切り替え

右上の「Open Perspective」ボタンを押下し、プルダウンの「Other…」 ボタンを押下します。

fig2-3PerspectiveSelection.png
パースペクティブの選択

「RTC Builder」を選択することで、RTCBuilderが起動します。メニューバーに「カナヅチとRT」のRTCBuilderのアイコンが現れます。


新規プロジェクトの作成

Flipコンポーネントを作成するために、RTCBuilderで新規プロジェクトを 作成する必要が有ります。プロジェクトを作成する方法は2種類あります。

  1. 画面上部のメニューから[ファイル]-[新規]-[プロジェクト]を選択 (Eclipse共通)
    • 「新規プロジェクト」 画面において,「その他」-「RTCビルダ」を選択し、「次へ」 をクリック
  2. メニューバーの「RTCBuilder」のアイコンをクリック
    fig2-5CreateProject.png
    RTC Builder 用プロジェクトの作成 1 (「ファイル」メニューから)

fig2-6CreateProject2.png
RTC Builder 用プロジェクトの作成 2(「ファイル」メニューから)

どちらの方法でも、次ようなプロジェクト作成ウィザードが開始されます。 「プロジェクト名」欄に作成するプロジェクト名 (ここでは Flip) を入力して「終了」をクリックします。

RT-Component-BuilderProject.png
RTC Builder 用プロジェクトの作成 3

指定した名称のプロジェクトが生成され、パッケージエクスプローラ内に追加されます。

PackageExplolrer.png
RTC Builder 用プロジェクトの作成 4

生成したプロジェクト内には、デフォルト値が設定された RTC プロファ イル XML(RTC.xml) が自動的に生成されます。

RTC プロファイルエディタの起動

RTC.xmlが生成された時点で、このプロジェクトに関連付けられているワークスペースとして RTCBuilder のエディタが開くはずです。もし開かない場合は、ツールバーの「Open New RtcBuilder Editor」ボタンを押下するか、メニューバーの [file]-[Open New Builder Editor] を選択します。

Open_RTCBuilder.png
ツールバーから Open New RtcBuilder Editor

fig2-10FileMenuOpenNewBuilder.png
File メニューから Open New Builder Editor

プロファイル情報入力とコードの生成

まず、いちばん左の「基本」タブを選択し、基本情報を入力します。先ほ ど決めたFlipコンポーネントの仕様(名前)の他に、概要やバージョン等を 入力してください。ラベルが赤字の項目は必須項目です。その他はデフォ ルトで構いません。

  • モジュール名: Flip
  • モジュール概要: Flip image component
  • バージョン: 1.0.0
  • ベンダ名: AIST
  • モジュールカテゴリ: Category
  • コンポーネント型: STATIC
  • アクティビティ型: PERIODIC
  • コンポーネント種類: DataFlowComponent
  • 最大インスタンス数: 1
  • 実行型: PeriodicExecutionContext
  • 実行周期: 0.0 (下図では1.0となってますが,0.0として下さい.)


Basic.png
基本情報の入力


次に、「アクティビティ」タブを選択し、使用するアクションコールバッ クを指定します。

Flipコンポーネントでは、onActivated(),onDeactivated(),onExecute() コールバックを使用します。下図のように①のonAtivatedをクリック後に (2)のラジオボタンにて"on"にチェックを入れます。onDeactivated, onExecuteについても同様の手順を行います。


Activity.png
アクティビティコールバックの選択


さらに、「データポート」タブを選択し、データポートの情報を入力します。 先ほど決めた仕様を元に以下のように入力します。なお、変数名や表示位置はオプションで、そのままで結構です。


-InPort Profile:
    • ポート名: originalImage
    • データ型: CameraImage
    • 変数名: originalImage
    • 表示位置: left
      -OutPort Profile:
    • ポート名: flippedImage
    • データ型: CameraImage
    • 変数名: flippedImage
    • 表示位置: right


DataPort.png
データポート情報の入力


次に、「コンフィギュレーション」タブを選択し、先ほど決めた仕様を元 に、Configurationの情報を入力します。制約条件およびWidgetとは、 RTSystemEditorでコンポーネントのコンフィギュレーションパラメータを 表示する際に、スライダ、スピンボタン、ラジオボタンなど、GUIで値の 変更を行うためのものです。

ここでは、flipModeが取りうる値は先ほど仕様を決めたときに、-1,0,1の 3つの値のみ取ることにしたので、ラジオボタンを使用することにします。


-flipMode
    • 名称: flipMode
    • データ型: int
    • デフォルト値: 1
    • 変数名: flipMode
    • 制約条件: (-1, 0, 1) ※ (-1: 上下左右反転, 0: 上下反転, 1: 左右反転)
    • Widget: radio


Configuration.png
コンフィグレーション情報の入力


次に、「言語・環境」タブを選択し、プログラミング言語を選択します。 ここでは、C++(言語)を選択します。なお、言語・環境はデフォルト等が 設定されておらず、指定子忘れるとコード生成時にエラーになりますので、 必ず言語の指定を行うようにしてください。

また、C++の場合デフォルトではCMakeを利用してビルドすることになって いますが、旧式のVCのプロジェクトやソリューションを直接RTCBuilderが 生成する方法を利用したい場合は Use old build environment を チェックしてください。

Language.png
プログラミング言語の選択


最後に、「基本」タブにある"コード生成"ボタンをクリックし、コンポー ネントの雛型を生成します。


Generate.png
雛型の生成(Generate)


※ 生成されるコード群は、eclipse起動時に指定したワークスペースフォルダの中に生成されます。現在のワークスペースは、「ファイル(F)」 > 「ワークスペースの切り替え(W)...」で確認することができます。

仮ビルド

さて、ここまででFlipコンポーネントのソースコードが生成されました。 処理の中身は実装されていないので、InPortに画像を入力しても何も出力 されませんが、生成直後のソースコードだけでもコンパイルおよび実行は できます。

※サービスポートとプロバイダを持つコンポーネントの場合、実装を行わないとビルドが通らないものもあります。

では、まずCMakeを利用してビルド環境のConfigureを行います。Linuxで あれば、Flipコンポーネントのソースが生成されたディレクトリで

 $ cd workspace/Flip
 $ mkdir build
 $ cd build
 $ cmake ..
 $ make

とすれば、Configureおよびビルドが完了するはずです。ビルド終了後、からのFlipCompを起動してみましょう。

 $ cd src
 $ ./FlipComp

起動後、RTSystemEditorなどでアクセスしてみてください。Flipというコンポーネントが表示されているはずです。カメラコンポーネント (OpenCVCameraComp) や表示コンポーネント (CameraViewerComp) などとも接続できますが、中で何も処理を行っていないでの、表示コンポーネントには何も表示されません。

次からは、コンポーネントのソースコードを作成し、中身を実装していきます。

ヘッダ、ソースの編集

ヘッダ (include/Flip/Flip.h) およびソースコード (src/Flip.cpp) をそれぞれ編集します。 Eclipse画面左のパッケージエクスプローラでそれぞれのファイルをダブルクリックすると、通常はVisual C++の編集画面が開きますので、そこで編集します。Eclipseの中央のエディタにドラッグアンドドロップしても編集できます。

アクティビティ処理の実装

Flipコンポーネントでは、InPortから受け取った画像を画像保存用バッファ に保存し、その保存した画像をOpenCVのcvFlip()関数にて変換します。そ の後、変換された画像をOutPortから送信します。


onActivated(),onExecute(),onDeactivated()での処理内容を下図に示します。

FlipRTC_State.png
アクティビティ処理の概要


onExecute()での処理を下図に示します。


FlipRTC.png
onExucete()での処理内容


ヘッダファイル (Flip.h) の編集

OpenCVのライブラリを使用するため、OpenCVのインクルードファイルをイ ンクルードします。

 //OpenCV用インクルードファイルのインクルード
 #include<cv.h>
 #include<cxcore.h>
 #include<highgui.h>

このcvFlipコンポーネントでは、画像領域の確保、Flip処理、確保した画 像領域の解放のそれぞれの処理を行います。これらの処理は、それぞれ onActivated(),onDeactivated(),onExecute() のコールバック関数にて行 います。

   /***
    *
    * The activated action (Active state entry action)
    * former rtc_active_entry()
    *
    * @param ec_id target ExecutionContext Id
    *
    * @return RTC::ReturnCode_t
    * 
    * 
    */
   virtual RTC::ReturnCode_t onActivated(RTC::UniqueId ec_id);
 
   /***
    *
    * The deactivated action (Active state exit action)
    * former rtc_active_exit()
    *
    * @param ec_id target ExecutionContext Id
    *
    * @return RTC::ReturnCode_t
    * 
    * 
    */
   virtual RTC::ReturnCode_t onDeactivated(RTC::UniqueId ec_id);
 
   /***
    *
    * The execution action that is invoked periodically
    * former rtc_active_do()
    *
    * @param ec_id target ExecutionContext Id
    *
    * @return RTC::ReturnCode_t
    * 
    * 
    */
   virtual RTC::ReturnCode_t onExecute(RTC::UniqueId ec_id);

反転した画像の保存用にメンバー変数を追加します。

   IplImage* m_imageBuff;
   IplImage* m_flipImageBuff;

ソースファイル (Flip.cpp) の編集

下記のように、onActivated(),onDeactivated(),onExecute()を実装します。

 RTC::ReturnCode_t Flip::onActivated(RTC::UniqueId ec_id)
 {
   // イメージ用メモリの初期化
   m_imageBuff = NULL;
   m_flipImageBuff = NULL;
 
   // OutPortの画面サイズの初期化
   m_flippedImage.width = 0;
   m_flippedImage.height = 0;
  
   return RTC::RTC_OK;
 }
 
 
 RTC::ReturnCode_t Flip::onDeactivated(RTC::UniqueId ec_id)
 {
   if(m_imageBuff != NULL)
   {
     // イメージ用メモリの解放
     cvReleaseImage(&m_imageBuff);
     cvReleaseImage(&m_flipImageBuff);
   }
 
   return RTC::RTC_OK;
 }
 
 
 RTC::ReturnCode_t Flip::onExecute(RTC::UniqueId ec_id)
 {
   // 新しいデータのチェック
   if (m_originalImageIn.isNew()) {
     // InPortデータの読み込み
     m_originalImageIn.read();
 
     // InPortとOutPortの画面サイズ処理およびイメージ用メモリの確保
     if( m_originalImage.width != m_flippedImage.width || m_originalImage.height != m_flippedImage.height)
       {
     m_flippedImage.width = m_originalImage.width;
     m_flippedImage.height = m_originalImage.height;
 
     // InPortのイメージサイズが変更された場合
     if(m_imageBuff != NULL)
       {
         cvReleaseImage(&m_imageBuff);
         cvReleaseImage(&m_flipImageBuff);
       }
 
     // イメージ用メモリの確保
     m_imageBuff = cvCreateImage(cvSize(m_originalImage.width, m_originalImage.height), IPL_DEPTH_8U, 3);
     m_flipImageBuff = cvCreateImage(cvSize(m_originalImage.width, m_originalImage.height), IPL_DEPTH_8U, 3);
       }
 
     // InPortの画像データをIplImageのimageDataにコピー
     memcpy(m_imageBuff->imageData,(void *)&(m_originalImage.pixels[0]),m_originalImage.pixels.length());
 
     // InPortからの画像データを反転する。 m_flipMode 0: X軸周り, 1: Y軸周り, -1: 両方の軸周り
     cvFlip(m_imageBuff, m_flipImageBuff, m_flipMode);
 
     // 画像データのサイズ取得
     int len = m_flipImageBuff->nChannels * m_flipImageBuff->width * m_flipImageBuff->height;
     m_flippedImage.pixels.length(len);
 
     // 反転した画像データをOutPortにコピー
     memcpy((void *)&(m_flippedImage.pixels[0]),m_flipImageBuff->imageData,len);
 
     // 反転した画像データをOutPortから出力する。
     m_flippedImageOut.write();
   }
 
   return RTC::RTC_OK;
 }

CMakeによるビルドに必要なファイルの生成

CMakeList.txt の編集

Eclipse画面左のパッケージエクスプローラでsrc/CMakeLists.txtをダブルクリックorエディタへドラッグアンドドロップして編集します。

EditCmakeLists.png
CMakeLists.txtの編集

このコンポーネントではOpenCVを利用していますので、OpenCVのヘッダの インクルードパス、ライブラリやライブラリサーチパスを与えてやる必要 が有ります。幸いOpenCVはCMakeに対応しており、以下の2行を追加・変更するだ けでOpenCVのライブラリがリンクされ使えるようになります。

  • src/CMakeLists.txt を修正する
    • Eclipseのパッケージエクスプローラで src/CMakeLists.txt をダブルクリック
  • find_package(OpenCV REQUIRED)を追加
  • 最初のtarget_link_libraries に ${OpenCV_LIBS} を追加
    • target_link_libraries は2ヶ所あり、上がDLL、下が実行ファイルのライブラリ指定です

 set(comp_srcs Flip.cpp )
 set(standalone_srcs FlipComp.cpp)
 
 find_package(OpenCV REQUIRED) ←この行を追加
   :中略
 add_dependencies(${PROJECT_NAME} ALL_IDL_TGT)
 target_link_libraries(${PROJECT_NAME} ${OPENRTM_LIBRARIES} ${OpenCV_LIBS}) ← OepnCV_LIBSを追加
   :中略
 add_executable(${PROJECT_NAME}Comp ${standalone_srcs}
   ${comp_srcs} ${comp_headers} ${ALL_IDL_SRCS})
 target_link_libraries(${PROJECT_NAME}Comp ${OPENRTM_LIBRARIES} ${OpenCV_LIBS}) ← OepnCV_LIBSを追加

ビルド

ビルドの実行

CMakeList.txtを編集したので、再度CMakeでConfigureおよびGenerateを行います。

 $ cd workspace/Flip (eclipseワークスペース下のFlipディレクトリへ移動)
 $ rm -rf build (念のため仮ビルドで作成したディレクトリは削除)
 $ mkdir build (再度buildディレクトリを作成)
 $ cd build
 $ cmake ..
 $ make
 
CMakeのGenerateが正常に終了した事を確認し、makeします。Configureで問題 がある場合、先ほど編集した Flip/src/CMakeList.txt の編集にミスがある可 能性があります。makeでエラーが出た場合は、ソースコードやヘッダの編集に 間違いがある可能性があります。エラーメッセージをよく見て、修正してくだ さい。

Flipコンポーネントの動作確認

ここでは、OpenRTM-aist-1.1以降で同梱されるようになったカメラコンポーネント (OpenCVCameraComp, またはDirectShowCamComp)とビューアコンポーネント (CameraViewerComp)を接続し動作確認を行います。

NameServiceの起動

コンポーネントの参照を登録するためのネームサービスを起動します。


 $ rtm-naming

rtc.confの作成

RTコンポーネントでは、ネームサーバーのアドレスやネームサーバーへの 登録フォーマットなどの情報をrtc.confというファイルで指定する必要が あります。

下記の内容をrtc.confというファイル名で保存し、 workspace/Flip/build/src/ ディレクトリに置いて下さい。

 corba.nameservers: localhost
 naming.formats: %n.rtc

Flipコンポーネントの起動

Flipコンポーネントを起動します。

先程rtc.confファイルを置いたフォルダにある、FlipComp.exeファイルを実行して下さい。

 $ cd workspace/Flip/build/src (もし現在 build/src 以外にいる場合)
 $ ./FlipComp
 

カメラコンポーネントとビューアコンポーネントの起動

USBカメラのキャプチャ画像をOutPortから出力するOpenCVCameraComp, InPortで受け取った画像を画面に表示するCameraViewerCompを起動します。

 $ /usr/share/openrtm-1.1/components/c++/opencv-rtcs/OpenCVCameraComp
 $ /usr/share/openrtm-1.1/components/c++/opencv-rtcs/CameraViewerComp
 

コンポーネントの接続

下図のように、RTSystemEditorにて OpenCVCameraComp (またはDirectShowcomp) と Flip、CameraviewerComp コンポーネントを接続します。

RTSE_Connect.png
コンポーネントの接続

eclipse起動後、RTSystemEditorでネームサーバに接続できない場合があります。その場合、/etc/hosts の localhost の行に自ホスト名を追記してください。

 $ hostname
 ubuntu1404 ← ホスト名は ubuntu1404
 $ sudo vi /etc/hosts

 127.0.0.1       localhost
 を以下のように変更
 127.0.0.1       localhost ubuntu1404

コンポーネントのActivate

RTSystemEditorの上部にあります「ALL」というアイコンをクリックし、 全てのコンポーネントをアクティブ化します。正常にアクティベートされ た場合、下図のように黄緑色でコンポーネントが表示されます。


RTSE_Activate.png
コンポーネントのアクティブ化


動作確認

下図のようにコンフィギュレーションビューにてコンフィギュレーションを変更することができます。

Flipコンポーネントのコンフィギュレーションパラメータ「flipMode」を「0」や「-1」などに変更し、画像の反転が行われるかを確認して下さい。


RTSE_Configuration.png
コンフィギュレーションパラメータの変更


Flipコンポーネントの全ソース

Flipコンポーネントソースファイル (Flip.cpp)

 // -*- C++ -*-
 /*!
  * @file  Flip.cpp
  * @brief Flip image component
  * @date $Date$
  *
  * $Id$
  */
 
 #include "Flip.h"
 
 // Module specification
 static const char* flip_spec[] =
   {
     "implementation_id", "Flip",
     "type_name",         "Flip",
     "description",       "Flip image component",
     "version",           "1.0.0",
     "vendor",            "AIST",
     "category",          "Category",
     "activity_type",     "PERIODIC",
     "kind",              "DataFlowComponent",
     "max_instance",      "1",
     "language",          "C++",
     "lang_type",         "compile",
     // Configuration variables
     "conf.default.flipMode", "1",
     // Widget
     "conf.__widget__.flipMode", "radio",
     // Constraints
     "conf.__constraints__.flip_mode", "(-1,0,1)",
     ""
   };
 
 /*!
  * @brief constructor
  * @param manager Maneger Object
  */
 Flip::Flip(RTC::Manager* manager)
   : RTC::DataFlowComponentBase(manager),
     m_originalImageIn("originalImage", m_originalImage),
     m_flippedImageOut("flippedImage", m_flippedImage)
 {
 }
 
 /*!
  * @brief destructor
  */
 Flip::~Flip()
 {
 }
 
 
 RTC::ReturnCode_t Flip::onInitialize()
 {
   // Registration: InPort/OutPort/Service
   // Set InPort buffers
   addInPort("originalImage", m_originalImageIn);
   
   // Set OutPort buffer
   addOutPort("flippedImage", m_flippedImageOut);
   
   // Bind variables and configuration variable
   bindParameter("flipMode", m_flipMode, "1");
 
   return RTC::RTC_OK;
 }
 
 
 RTC::ReturnCode_t Flip::onActivated(RTC::UniqueId ec_id)
 {
   // イメージ用メモリの初期化
   m_imageBuff = NULL;
   m_flipImageBuff = NULL;
 
   // OutPortの画面サイズの初期化
   m_flippedImage.width = 0;
   m_flippedImage.height = 0;
  
   return RTC::RTC_OK;
 }
 
 
 RTC::ReturnCode_t Flip::onDeactivated(RTC::UniqueId ec_id)
 {
   if(m_imageBuff != NULL)
   {
     // イメージ用メモリの解放
     cvReleaseImage(&m_imageBuff);
     cvReleaseImage(&m_flipImageBuff);
   }
 
   return RTC::RTC_OK;
 }
 
 
 RTC::ReturnCode_t Flip::onExecute(RTC::UniqueId ec_id)
 {
   // 新しいデータのチェック
   if (m_originalImageIn.isNew()) {
     // InPortデータの読み込み
     m_originalImageIn.read();
 
     // InPortとOutPortの画面サイズ処理およびイメージ用メモリの確保
     if( m_originalImage.width != m_flippedImage.width || m_originalImage.height != m_flippedImage.height)
       {
     m_flippedImage.width = m_originalImage.width;
     m_flippedImage.height = m_originalImage.height;
 
     // InPortのイメージサイズが変更された場合
     if(m_imageBuff != NULL)
       {
         cvReleaseImage(&m_imageBuff);
         cvReleaseImage(&m_flipImageBuff);
       }
 
     // イメージ用メモリの確保
     m_imageBuff = cvCreateImage(cvSize(m_originalImage.width, m_originalImage.height), IPL_DEPTH_8U, 3);
     m_flipImageBuff = cvCreateImage(cvSize(m_originalImage.width, m_originalImage.height), IPL_DEPTH_8U, 3);
       }
 
     // InPortの画像データをIplImageのimageDataにコピー
     memcpy(m_imageBuff->imageData,(void *)&(m_originalImage.pixels[0]),m_originalImage.pixels.length());
 
     // InPortからの画像データを反転する。 m_flipMode 0: X軸周り, 1: Y軸周り, -1: 両方の軸周り
     cvFlip(m_imageBuff, m_flipImageBuff, m_flipMode);
 
     // 画像データのサイズ取得
     int len = m_flipImageBuff->nChannels * m_flipImageBuff->width * m_flipImageBuff->height;
     m_flippedImage.pixels.length(len);
 
     // 反転した画像データをOutPortにコピー
     memcpy((void *)&(m_flippedImage.pixels[0]),m_flipImageBuff->imageData,len);
 
     // 反転した画像データをOutPortから出力する。
     m_flippedImageOut.write();
   }
 
   return RTC::RTC_OK;
 }
 
 
 extern "C"
 {
  
   void FlipInit(RTC::Manager* manager)
   {
     coil::Properties profile(flip_spec);
     manager->registerFactory(profile,
                              RTC::Create<Flip>,
                              RTC::Delete<Flip>);
   }
   
 };

Flipコンポーネントのヘッダファイル (Flip.h)

 // -*- C++ -*-
 /*!
  * @file  Flip.h
  * @brief Flip image component
  * @date  $Date$
  *
  * $Id$
  */
 
 #ifndef FLIP_H
 #define FLIP_H
 
 #include <rtm/Manager.h>
 #include <rtm/DataFlowComponentBase.h>
 #include <rtm/CorbaPort.h>
 #include <rtm/DataInPort.h>
 #include <rtm/DataOutPort.h>
 #include <rtm/idl/BasicDataTypeSkel.h>
 #include <rtm/idl/ExtendedDataTypesSkel.h>
 #include <rtm/idl/InterfaceDataTypesSkel.h>
 
 //OpenCV用インクルードファイルのインクルード
 #include<cv.h>
 #include<cxcore.h>
 #include<highgui.h>
 
 using namespace RTC;
 
 /*!
  * @class Flip
  * @brief Flip image component
  *
  */
 class Flip
   : public RTC::DataFlowComponentBase
 {
  public:
   /*!
    * @brief constructor
    * @param manager Maneger Object
    */
   Flip(RTC::Manager* manager);
 
   /*!
    * @brief destructor
    */
   ~Flip();
 
   /***
    *
    * The initialize action (on CREATED->ALIVE transition)
    * formaer rtc_init_entry() 
    *
    * @return RTC::ReturnCode_t
    * 
    * 
    */
    virtual RTC::ReturnCode_t onInitialize();
 
   /***
    *
    * The activated action (Active state entry action)
    * former rtc_active_entry()
    *
    * @param ec_id target ExecutionContext Id
    *
    * @return RTC::ReturnCode_t
    * 
    * 
    */
    virtual RTC::ReturnCode_t onActivated(RTC::UniqueId ec_id);
 
   /***
    *
    * The deactivated action (Active state exit action)
    * former rtc_active_exit()
    *
    * @param ec_id target ExecutionContext Id
    *
    * @return RTC::ReturnCode_t
    * 
    * 
    */
    virtual RTC::ReturnCode_t onDeactivated(RTC::UniqueId ec_id);
 
   /***
    *
    * The execution action that is invoked periodically
    * former rtc_active_do()
    *
    * @param ec_id target ExecutionContext Id
    *
    * @return RTC::ReturnCode_t
    * 
    * 
    */
    virtual RTC::ReturnCode_t onExecute(RTC::UniqueId ec_id);
 
  protected:
   // Configuration variable declaration
   /*!
    * 
    * - Name:  flipMode
    * - DefaultValue: 1
    */
   int m_flipMode;
 
   // DataInPort declaration
   CameraImage m_originalImage;
 
   /*!
    */
   InPort<CameraImage> m_originalImageIn;
   
   // DataOutPort declaration
   CameraImage m_flippedImage;
 
   /*!
    */
   OutPort<CameraImage> m_flippedImageOut;
 
  private:
   // 処理画像用バッファ
   IplImage* m_imageBuff;
   IplImage* m_flipImageBuff;
 };
 
 
 extern "C"
 {
   DLL_EXPORT void FlipInit(RTC::Manager* manager);
 };
 
 #endif // FLIP_H

Flipコンポーネントの全ソースコード

Flipコンポーネントの全ソースコードを以下に添付します。

Flip.zip

最新バージョン

初めての方へ

Windows msi(インストーラ) パッケージ (サンプルの実行ができます。)

C++,Python,Java,
Toolsを含む
1.1.2-RELEASE

RTコンポーネントを開発するためには開発環境のインストールが必要です。詳細はダウンロードページ

統計

Webサイト統計
ユーザ数:1618
プロジェクト統計
RTコンポーネント286
RTミドルウエア21
ツール20
文書・仕様書1

OpenHRP3

動力学シミュレータ

Choreonoid

モーションエディタ/シミュレータ

OpenHRI

対話制御コンポーネント群

OpenRTP

統合開発プラットフォーム

産総研RTC集

産総研が提供するRTC集

TORK

東京オープンソースロボティクス協会

DAQ-Middleware

ネットワーク分散環境でデータ収集用ソフトウェアを容易に構築するためのソフトウェア・フレームワーク

VirCA

遠隔空間同士を接続し、実験を行うことが可能な仮想空間プラットホーム

Join our slack

Enter email address for slack invite.