このサンプルプラグインではカメラの映像に対して、OpenCVのチュートリアルにあるhull_demoを適用します。

カメラが複数の場合、一番多くの輪郭線を検出したカメラに自動的に切り替わります。

IwaCamを一度起動すると、IwaCamが置いてあるフォルダにplugins-3.0というフォルダが出来ます。

plugins-3.0フォルダにダウンロードしたOpenCV2Sample-1.0.0.dllを置いてください。

IwaCamを起動すると、プラグインが読み込まれます。

アプリケーションのインストール

プラグインの開発には以下のソフトウェアが必要です。

  • Visual Studio 2012
  • OpenCV 2.4.6

下記の手順でインストールしてください。

Visual Studioのインストール

Visual Studio Express 2012 for Windows Desktopをインストールします。

Info ライセンスをお持ちであれば、Visual Studio Professional 2012などの上位エディションでもかまいません。


OpenCVのインストール

OpenCV 2.4.6をダウンロードします。

Info バージョン2.4.6をダウンロードしてください。


「C:\opencv2.4.6」に展開してください。

ソースコードのビルド

ダウンロードしたサンプルプラグインのソースコードの「plugin\OpenCV2Sample.sln」を開いてください。


Visual Studioが立ち上がりますので、Releaseビルドに変更します。


メニューから、「ビルド > ソリューションのビルド」を選択します。 プラグインのビルドが行われます。


ビルドが終了すると、OpenCV2Sample.slnと同じフォルダに「Release」というフォルダが作成されます。


Releaseフォルダの下にOpenCV2Sample.dllがあります。

これがプラグインになりますので、IwaCamのplugins-3.0フォルダに移動してください。

Info plugins-3.0にあるOpenCV2Sample-1.0.0.dllは削除してください。

OpenCVの処理の変更

Visual StudioでOpenCV2Sample.cppを開きます。


カメラの映像に対する処理はVFrameCallback関数で行っていますので、この中身を変更することでプラグインの動作を変更します。

VFrameCallback関数へは映像の各フレームが順番に送られてきます。
引数として渡されるデータはDIBになっていますので、cv::Mat形式に変換してから処理を行っています。

プラグインの動作を変更する場合は、上記の画像でテキスト選択されている部分を変更してください。


VFrameCallbackのコード:
PLUGIN_API int VFrameCallback(int camera,
  const BITMAPINFOHEADER* bitmapinfoheader,
  BYTE* buffer,
  long len)
{
  if (! appInfo_) return 0;
  if (! bitmapinfoheader) return 0;
  if (! buffer) return 0;

  // ------------------------------------------------------------
  // OpenCV用にcv::Matを用意。
  auto bpp = bitmapinfoheader->biBitCount / 8;
  assert(bpp == 3 || bpp == 4); // 24bitか32bitのみ対応
  auto mat = cv::Mat(bitmapinfoheader->biHeight, bitmapinfoheader->biWidth, CV_MAKETYPE(CV_8U, bpp), buffer);
  // bitmapは上下逆になっているので反転する。
  cv::flip(mat, mat, 0);

↓ここの処理を変更することでプラグインの動作が変化します。

  // ------------------------------------------------------------
  // 以後、matを変更することでエフェクトがかかる。

  // hull_demoを適用
  auto contours_size = hull_demo_.apply(mat);

#if 1
  // カメラ切り替え処理
  int max_priority_camera = camera_chooser_demo_.get_max_priority_camera(camera, contours_size);
  appInfo_->SelectCamera(max_priority_camera);
#endif

#if 1
  // デバッグ用に各カメラ画像を表示
  const std::string winname = "OpenCV2Sample camera" + std::to_string(camera);
  cv::putText(mat, "priority: " + std::to_string(contours_size),
              cv::Point(10, 50), cv::FONT_HERSHEY_SIMPLEX,
              1.0, cv::Scalar(0, 0, 200), 2, CV_AA);
  cv::namedWindow(winname);
  cv::imshow(winname, mat);
  cv::waitKey(1);
#endif
  // ------------------------------------------------------------
  // 反転を戻す。
  cv::flip(mat, mat, 0);

  return 0;
}

カメラの切り替え

カメラが複数ある場合、プラグインには全てのカメラの映像が送られてきます。
ですが、相手に送られる映像は現在選択されているカメラ一つだけですので、状況に応じてカメラを切り替えてください。

カメラの切り替えはVFrameCallback関数の中で、appInfo_->SelectCameraを使います。
引数としてカメラ番号(0から連番)を渡します。

  appInfo_->SelectCamera(max_priority_camera);

このサンプルプラグインではhull_demoで検出した輪郭の数を優先度としてcamera_chooser_demo_に渡し、最優先のカメラ番号を得て、SelectCameraを呼んでいます。

#if 1
  // カメラ切り替え処理
  int max_priority_camera = camera_chooser_demo_.get_max_priority_camera(camera, contours_size);
  appInfo_->SelectCamera(max_priority_camera);
#endif

camera_chooser_demo_はそのまま使えますので、優先度としてcontours_size(輪郭の数)以外の値を使うことで望みの条件でカメラを選択できます。

効率的な開発の仕方について

プラグインは変更をするたびにIwaCamの再起動を行わなければならず、動作確認に時間がかかります。
また、デバッガを使うことも難しいです。

そのため、直接プラグインを開発するのではなく、基本的なOpenCVの処理は通常のアプリケーションとして開発をしたほうが効率的です。

サンプルプラグインでも、「app\OpenCV2App\OpenCV2App.sln」で通常のアプリケーションを用意しています。

アプリについて

app\OpenCV2App\OpenCV2App.slnを開きます。

Visual Studioが立ち上がりますので、実行します。

ファイルから読み込んだ動画へhull_demoが適用されます。