はつねの日記

Kinect, Windows 10 UWP, Windows Azure, IoT, 電子工作

OpenCVをVB.NET/C#で使うためのラッパーを試してみよう

Open CVインテル製のコンピュータビジョン向けオープンソースライブラリです。

C/C++JavaPython用のライブラリで、OpenCV自体はVB.NETC#から直接使うことができないのですがラッパーを使うことでVB.NET/C#からも使えるようになります。きっとOpen CV自体が対応してくれるようになると思うのですが、いまのところはまだラッパーにお世話にならないといけません。

.NET用ラッパーとしては、

  Open CV Emgu CV OpenCVDotNet OpenCvSharp
ライセンス BSD GPL v3 GPL v2 LGPL
2013/10/01時点の
最終日付
2013/07/03
Ver 2.4.6
2013/09/26
Ver 2.9.0(beta)
2007/03
Ver 0.7
2013/07/10
Ver 2.4.5

などがあります。

Emgu CV

Emgu CVには対応するOpen CVのDLLが入っています。通常、このDLLの入った「C:\Emgu\emgucv-windows-universal-cuda 2.9.0.1922\bin\x86」などに環境変数でPathを通すことになりますが、いろいろ面倒なのでビルド前イベントでdllを出力ディレクトリにコピーするように設定します。

image

Emgu CVで顔認識させるコードは以下のようになります。非常に簡単ですが、ライセンスがGPL v3ですので使いづらいです。

VB.NET
Dim filename As String = dialog.FileName
Dim cvImg As New Emgu.CV.Image(Of Emgu.CV.Structure.Bgr, Byte)(filename)
'Load the object detector
Dim faceDetector As New Emgu.CV.CascadeClassifier("haarcascade_frontalface_default.xml")
Dim imgGray As Emgu.CV.Image(Of Emgu.CV.Structure.Gray, Byte) =
    cvImg.Convert(Of Emgu.CV.Structure.Gray, Byte)()
For Each face As Rectangle In faceDetector.DetectMultiScale( _
                                   imgGray, _
                                   1.1, _
                                   10, _
                                   New Size(20, 20), _
                                   Size.Empty)
    cvImg.Draw(face, New Emgu.CV.Structure.Bgr(Color.Red), 2)
Next
'
Me.Emgu_PictureBox.Image = cvImg.ToBitmap
C#
var filename = dialog.FileName;
var cvImg = new Emgu.CV.Image<emgu.cv.structure.bgr, Byte>(filename);
///Load the object detector
var faceDetector = new Emgu.CV.CascadeClassifier("haarcascade_frontalface_default.xml");
var imgGray = cvImg.Convert<emgu.cv.structure.gray, Byte>();
foreach (Rectangle face in faceDetector.DetectMultiScale(imgGray,1.1,10, new Size(20, 20), Size.Empty))
{
    cvImg.Draw(face, new Emgu.CV.Structure.Bgr(Color.Red), 2);
}
///
this.Emgu_PictureBox.Image = cvImg.ToBitmap();

Open CVのコードを見たことのある人は初期化やreleaseなどがなくかなりシンプルになっていることに戸惑うかも知れません。

内部的にはOpen CVを使いつつ、独自の世界観を醸し出しているのが特徴ですが、同時にOpen CVの新バージョンの対応の速さも特筆すべきものがあります。

OpenCvSharp

OpenCvSharpの特徴はOpen CVに近い構造をとりつつIDispatchインターフェースをもっているためUsingブロックが使える点でしょう。

VB.NET
Using cvImg = New OpenCvSharp.IplImage(filename, OpenCvSharp.LoadMode.Color)
    Using faceDetector As OpenCvSharp.CvHaarClassifierCascade =
        OpenCvSharp.Cv.Load(Of OpenCvSharp.CvHaarClassifierCascade)("haarcascade_frontalface_default.xml")
        Using cvMem As New OpenCvSharp.CvMemStorage
            Using imgGray As New OpenCvSharp.IplImage(cvImg.Size, OpenCvSharp.BitDepth.U8, 1)
                OpenCvSharp.Cv.CvtColor(cvImg, imgGray, OpenCvSharp.ColorConversion.BgrToGray)
                OpenCvSharp.Cv.EqualizeHist(imgGray, imgGray)
                cvMem.Clear()
                For Each face In OpenCvSharp.Cv.HaarDetectObjects( _
                                        cvImg,
                                        faceDetector,
                                        cvMem,
                                        1.1,
                                        10,
                                        0,
                                        New OpenCvSharp.CvSize(30, 30))
                    cvImg.DrawRect(face, New OpenCvSharp.CvColor(255, 0, 0), 2)
                Next
            End Using
        End Using
    End Using
    Me.Emgu_PictureBox.Image = cvImg.ToBitmap
End Using
C#
using (var cvImg = new OpenCvSharp.IplImage(filename, OpenCvSharp.LoadMode.Color))
{
    using (OpenCvSharp.CvHaarClassifierCascade faceDetector =
        OpenCvSharp.Cv.Load<OpenCvSharp.CvHaarClassifierCascade>("haarcascade_frontalface_default.xml"))
    {
        using (var cvMem = new OpenCvSharp.CvMemStorage())
        {
            using (var imgGray = new OpenCvSharp.IplImage(cvImg.Size, OpenCvSharp.BitDepth.U8, 1))
            {
                OpenCvSharp.Cv.CvtColor(cvImg, imgGray, OpenCvSharp.ColorConversion.BgrToGray);
                OpenCvSharp.Cv.EqualizeHist(imgGray, imgGray);
                cvMem.Clear();
                foreach (var face in  OpenCvSharp.Cv.HaarDetectObjects(
                                            cvImg,
                                            faceDetector,
                                            cvMem,
                                            1.1,
                                            10,
                                            0,
                                            new OpenCvSharp.CvSize(30, 30)))
                {
                    cvImg.DrawRect(face, new OpenCvSharp.CvColor(255, 0, 0), 2);
                }
            }
        }
    }
    this.Emgu_PictureBox.Image = cvImg.ToBitmap();
}

OpenCVSharpにはもっとOpen CVと1対1に対応した記述方法もあります。

まとめ

Emug CVとOpenCVSharpのどちらがいいのか、最終的には好みの問題もあるでしょうが、Emgu CVがGPL v3である事を考えると、OpenCVSharpの方がよいのではないかと思います。

ただし、Open CVのバージョンに対する追随など決定打にかける気もしますので、やはり、ここはOpen CV自体の.NET Framework化、しいてはWindowsストアアプリ対応が望まれるところです。このあたりはOpen CVを提供しているのがIntelさんだということもあり、期待しております。そのときにはPerCライブラリもついてに対応してくれると色々広がりますので合わせてIntelさんには検討してもらえたらと思います。