OpenCvSharpをつかう その6 (PictureBoxIpl)

ずいぶんと前回から間が空いてしまいました。今回は、フォームに張り付けてIplImageをすぐに表示できるPictureBoxIplコントロールの紹介です。

即席で作ったものなのであまり作りこんでいないのですが、表示させる際にIplImageからBitmapに変換するコードを書く手間は省くことができます。

プロジェクトの作成

Windows フォーム アプリケーション」としてプロジェクトを新規作成します。

参照の追加

PictureBoxIplを利用するためには、OpenCvSharp.dllのほかに、OpenCvSharp.UserInterface.dllを参照に加える必要があります。「参照設定」から、DLLを追加します。


ツールボックスに追加

Form1.csのデザイナ画面上で、ツールボックスを右クリックし、「アイテムの選択」を選ぶと以下のようなダイアログが出ます。ここで「参照」をクリックし、二度手間になりますがもう一度先ほど同様に OpenCvSharp.UserInterface.dll を追加します。するとPictureBoxIplという項目が現れるはずです。そのままOKします。

これで、ButtonやTextBoxなどの標準コントロールと同様にPictureBoxIplをフォームにドラッグするだけで貼り付けることができます。

コードの記述

PictureBoxIplはPictureBoxを継承しており、それにImageIplというプロパティが追加されています。このプロパティにIplImageを渡せば、それが表示されます。

private void button1_Click(object sender, EventArgs e)
{
    pictureBoxIpl1.ImageIpl = new IplImage(@"C:\Users\Public\Pictures\Sample Pictures\Waterfall.jpg");
}


画像の更新

IplImageのピクセルデータが画像処理等によって書き変わっても、PictureBoxIplに表示された画像は更新されません。更新する方法は、今のところImageIplプロパティに再代入する方法のみです。

// 画像を表示
pictureBoxIpl1.ImageIpl = img;
// 画像処理を行う(ネガポジ反転)
Cv.Not(img, img);
// 反映するには、再度代入が必要
pictureBoxIpl1.ImageIpl = img;

再代入のたびにPictureBoxIpl内部ではBitmapのインスタンスの再生成が行われるため、リアルタイムの更新はあまり向かないかもしれません(最近のPCならば全く問題ないですが)。現状で対策としては、普通のPictureBoxを使い自分でビットマップへの変換処理を書くことになります。

void timer1_Tick(object sender, EventArgs e)
{
    IplImage img = capture.QueryFrame();
    OpenCvSharp.Extensions.BitmapConverter.ToBitmap(img, pictureBox1.Image);
}

上記のようにすれば、Bitmapのインスタンスは再生成されず、ピクセルデータのみを書き換えてくれます。


追記:PictureBoxIplのRefreshIplImageというメソッドを使うと、初回以外はインスタンスを作らずにピクセルデータをコピーするようになります。

void timer1_Tick(object sender, EventArgs e)
{
    IplImage img = capture.QueryFrame();
    pictureBoxIpl1.RefreshIplImage(img);
}