如何将受管理的Bitmap从C#传递到包装的非托管OpenCV的Mat

时间:2015-03-26 23:02:41

标签: c# c++ opencv bitmap mat

我有一个包含3个部分的项目:

  1. 带有回调的托管C#项目,它给了我一个位图(它应该有PixelFormat = Format24bppRgb)。我已经尝试了几种方法将Bitmap转换为我可以传递给第2部分的内容,这是我尝试过的最后一件事:

    public int BufferCB(IntPtr pBuffer, int BufferLen)
    {
        byte[] aux = new byte[BufferLen];
        Marshal.Copy(pBuffer, aux, 0, BufferLen);
        String s_aux = System.Text.Encoding.Default.GetString(aux);
        wrappedClassInstance.GetBitmap(s_aux);
    }
    
  2. 托管C ++ / CLI以包装第3项:

    int WrappedClass::GetBitmap(array<System::Byte>^ s_in) {
        pin_ptr<unsigned char> pin = &s_in[0];
        unsigned char* p = pin;
        return privateImplementation->GetBitmap(p);
    }
    
  3. 使用OpenCV的非托管C ++应用程序。我想将这些数据加载到Mat:

    Mat myMat;
    int NativeClass::GetBitmap(unsigned char *s_in) {
    
        // If there's no input:
        if (!s_in) {
            return -1;
        }
        /* h and w are defined elsewhere */
        myMat = Mat(h, w, CV_8UC3, (void *)s_in, Mat::AUTO_STEP));
        imwrite("test.bmp", myMat);
        return 0;
    }
    
  4. 当达到imwrite函数时,抛出异常:&#34;&#34; System.Runtime.InteropServices.SEHException(0x80004005)&#34;。它并没有说太多,但是当我编组它时,我猜测传入Mat的数据已经损坏了。

    之前,我试图在没有包装器的情况下传递数据:

    [DllImport("mydll.dll", ...)]
    static extern void GetBitmap(IntPtr pBuffer, int h, int w);
    
    void TestMethod(IntPtr pBuffer, int BufferLen)
    {
        // h and w defined elsewhere
        // GetBitmap is essentially the same as in item 3.
        GetBitmap(pBuffer, BufferLen, h, w);
    }
    

    并且有效(它将Bitmap保存到文件中),但因为DLL一直保持连接,直到我杀死了解决方案对我来说不够好的过程。我也不想&#34;镜像&#34; Mat类进入我的项目,因为我知道Mat应该接受来自某些char *的数据。

    请帮忙,我该怎么做?我做错了类型转换吗?

    谢谢。

1 个答案:

答案 0 :(得分:0)

我已将第2部分更改为memcpy非托管内存到本机内存,只是为了确定。但我的代码真正的问题是每次我想要一个新的Mat,我都会调用Mat构造函数:

Mat myMat;
int MyClass::GetBitmap(unsigned char* s_in) {
    myMat = Mat(...)
}

相反,我做了:

Mat myMat;
int MyClass::GetBitmap(unsigned char* s_in) {
    Mat aux;
    aux = Mat(...)
    aux.copyTo(myMat);
    aux.release();
}

...现在我的代码工作正常。

修改 删除了一些使用new Mat(...)的部分,这是一个错字,它不会编译,因为我使用的是Mat,而不是Mat *。