読者です 読者をやめる 読者になる 読者になる

OpenCvSharpを使う その2 (画像の読み込み)

OpenCvSharp

今回は画像を読み込んで表示したりします。

class Program
{
    static void Main(string[] args)
    {
        IplImage img = Cv.LoadImage("lenna.png");

        Cv.NamedWindow("window");
        Cv.ShowImage("window", img);
        Cv.WaitKey();
        Cv.DestroyWindow("window");
            
        Cv.ReleaseImage(img);
    }
}

このコードの説明をかるくしつつ、最終的にはもう少し短い書き方をご紹介します。

OpenCvSharpをつかう 記事一覧

画像の読み込み

Cv.LoadImageを使います。引数には読み込む画像ファイルのパスを指定します。
http://opencv.jp/opencv-1.1.0/document/opencvref_highgui_loadsave.html#decl_cvLoadImage

IplImage img = Cv.LoadImage("lenna.png");

実行すると、このように読み込んだ画像が表示されるはずです。

読み込みフラグを指定

Cv.LoadImageには第2引数を指定することができます。例えば、以下のようにLoadMode.GrayScaleを指定すると、元の画像ファイルの色にかかわらずグレースケールで読み込まれます。

IplImage img = Cv.LoadImage("lenna.png", LoadMode.GrayScale);


LoadModeには他にもフラグがあります。最初の例のように省略した場合は LoadMode.Colorとみなされ、元の画像にかかわらず24bitカラー画像として読み込まれます。


二つのフラグの論理和LoadMode.AnyColor | LoadMode.AnyDepthを指定した場合は、元の画像がグレースケールならグレースケールで、カラー画像ならカラー画像として読み込まれます。元の画像に忠実に読み込むというフラグです。

IplImageのコンストラクタを使う

Cv.LoadImageの代わりに、IplImageのコンストラクタを使って画像を読み込むこともできます。引数の形式は同じです。内部的には同じ処理をしています。

IplImage img = new IplImage("lenna.png", LoadMode.Color);

cvLoadImageで読み込めない画像の場合

昨日遭遇した現象ですが、たまにcvLoadImageで読み込めない画像があります。ですが、同じ画像をSystem.Drawing.Bitmapとして、つまりGDI+を使って読み込むとうまくいく場合があります。そこで、cvLoadImageで読み込めない場合はGDI+を使ってくれるメソッドを定義しました。

IplImage img = IplImage.FromFile("lenna.png");

Failed to create IplImageという例外が投げられた場合は試してみましょう。

IplImageの解放

もちろんOpenCV同様にCv.ReleaseImageを使えば解放できますが、IplImageはIDisposableを実装しているので、Disposeを使った方がC#的だと思います。

IplImage img = new IplImage("lenna.png", LoadMode.Color);
img.Dispose();

さらに言えば、usingを使うのがC#的だと思います。

using(IplImage img = new IplImage("lenna.png", LoadMode.Color))
{
}

ここまでのまとめ

using (IplImage img = new IplImage("lenna.png"))
{
    Cv.NamedWindow("window");
    Cv.ShowImage("window", img);
    Cv.WaitKey();
    Cv.DestroyWindow("window");
}

ウィンドウの記述を楽に

ここからはおまけ。

Cv.NamedWindowをラップしてCvWindowというクラスが定義してあります。これもIDisposableなので、usingを使うと少しすっきりします。

using(CvWindow window = new CvWindow("window"))
{
    window.Image = img;
    Cv.WaitKey();
}

CvWindowのコンストラクタには表示させる画像を渡せるので、後から変更するつもりが無ければさらに短くできます。

using(new CvWindow("window", img))
{
    Cv.WaitKey();
}

今回のまとめ

// 画像ファイルを読み込む
using (IplImage img = new IplImage("lenna.png"))
{
    // "window"という名前のウィンドウをつくり、そこに画像imgを表示
    using (new CvWindow("window", img))
    {
        // キー入力を待つ
        Cv.WaitKey();
    }
}

特にネイティブのOpenCVの経験がある方は、慣れるまではCv.XXXを使っていた方がなじみがあってよいかもしれません。OpenCvSharpからOpenCVに入る人や、慣れてきた人は、usingな書き方をお勧めします。