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

OpenCV2.0でcvの関数がおかしい?

C#からOpenCV2,0をDllImportで呼び出してみたところ、AccessViolationExceptionが発生しました。

static class Program
{
    [DllImport("libcxcore200")]
    extern static CvSize cvGetSize(IntPtr arr);
    [DllImport("libcxcore200")]
    extern static IntPtr cvCreateImage(CvSize size, int depth, int channels);
    [DllImport("libcv200")]
    extern static void cvCvtColor(IntPtr src, IntPtr dst, int code);
    [DllImport("libhighgui200")]
    extern static IntPtr cvLoadImage(string filename, int flags);        
    [DllImport("libhighgui200")]
    extern static int cvSaveImage(string filename, IntPtr image);

    static void Main()
    {
        const int CV_LOAD_IMAGE_COLOR = 1;
        const int CV_BGR2GRAY = 6;

        IntPtr src = cvLoadImage("lenna.png", CV_LOAD_IMAGE_COLOR);
        IntPtr dst = cvCreateImage(cvGetSize(src), 8, 1);

        cvCvtColor(src, dst, CV_BGR2GRAY);

        cvSaveImage("dst.png", dst);
    }
}

この画像ではcvSaveImageのところでエラーが発生しているように見えますが、実際に悪さをしているのはcvCvtColorのほうです。

個人的に、AccessViolationExceptionというのは、ものにもよりますがぬるぽなんかの比ではない凶悪な例外だと思っています。何せ全く原因がわかりません。OpenCvSharp内部でも、未だに原因が分からずtry-catchで無かったことにしているAccessViolationExceptionが結構あります。


試してみたところ、cvCvtColorの他にもcvFindContours, cvWarpAffine, cvFiletr2Dといった関数でも例外が起きることを確認しました。cvの関数に多い模様です。
しかし厄介なのは、何事もなく実行できる関数も多いということです。ですからDllImport自体がうまくいっていないという線は考えにくいです。



OpenCVのbinディレクトリにある「cvtest.exe」を実行してみると、cvWarpAffineのところで落ちます。

よってやはり原因はOpenCVの側にあるような気がします。試しに、標準で添付されているlibcv200.dllといったDLLではなく、自分でCMakeでコンパイルしたcv200.dllをDllImportで使うようにすると、例外はピタリと止みました。結局DLLを添付しなければならないのでしょうか・・・?

追記

どうもlibcxcore200.dllといった標準添付のDLLはMinGWでコンパイルしたDLLっぽい?呼び出しがうまくいっていないのはそのあたりが理由なのかもしれません。

いずれにしろ、OpenCV2.0を使う際にはCMakeを用いたビルドが必須ということのようですね。