简体   繁体   English

EMGU(openCV)在C#和C ++之间来回传递图像

[英]EMGU (openCV) Passing a image back and forth between C# & C++

What I am trying to do seems simple in concept. 我正在尝试做的事情在概念上似乎很简单。 But, I am having a hard time with it (error message at the bottom). 但是,我很难过(底部的错误消息)。 I figured out most of it using EMGU documentation and prior questions here. 我使用EMGU文档和此处的先前问题弄清了大部分内容。

I have a windows form with an Imagebox control and a button. 我有一个带有Imagebox控件和一个按钮的Windows窗体。 On button click, I want to load a image (from file) and pass it to a C++ dll that can take the imagefile and pass the same file back to the C# program which can be displayed on the Imagebox control 在单击按钮时,我要加载图像(从文件)并将其传递到可以获取图像文件的C ++ dll,并将相同的文件传递回可以在Imagebox控件上显示的C#程序

C# C#

    private void rbtnLoadImage_Click(object sender, EventArgs e)
    {
        Image<Bgr, Int32> img1 = new Image<Bgr, Int32>("abc_color.jpg");
        IntPtr pnt = CvInvoke.cvCreateImageHeader(new Size(img1.Width, img1.Height), IPL_DEPTH.IPL_DEPTH_32S , img1.NumberOfChannels);

        Marshal.StructureToPtr(img1.MIplImage, pnt, false);
        MIplImage mptr = (MIplImage)Marshal.PtrToStructure(testIplImagePass(pnt), typeof(MIplImage));
        Image<Bgr, Int32> img2 = Image<Bgr, Int32>.FromIplImagePtr(mptr.imageData);
        imgbox.Image = img2;
    }

    [DllImport("xyz.dll", CallingConvention = CallingConvention.Cdecl)]
    public static extern IntPtr testIplImagePass(IntPtr imagevar);

C++ C ++

    extern "C" { __declspec(dllexport) IplImage* testIplImagePass(IplImage* imagevar); }

    IplImage* testIplImagePass(IplImage* imagevar)
    {
        return imagevar;
    }

The error message I got is "An unhandled exception of type 'System.NotImplementedException' occurred in Emgu.CV.dll. Additional information: Loading of 239, 249 channel image is not implemented." 我收到的错误消息是“在Emgu.CV.dll中发生了'System.NotImplementedException类型的未处理的异常。附加信息:239,249通道图像的加载未实现。”

It occurred on the line 它发生在网上

    Image<Bgr, Int32> img2 = Image<Bgr, Int32>.FromIplImagePtr(mptr.imageData);

What am I doing wrong here? 我在这里做错了什么? Any advice is appreciated. 任何建议表示赞赏。

This method is light, minimally requiring only one copy of the image data (in C# from managed to unmanaged memory). 此方法比较轻巧,只需最少的一个图像数据副本(在C#中从托管内存到非托管内存)。

Additionaly it is safe code (no C# pointers or fixing). 另外,它是安全代码(无C#指针或固定代码)。

The code is tailored for the <Bgr, Byte> . 该代码是针对<Bgr, Byte>量身定制的。 For a general version you also need to pass the element size and number of channels between C# and C++. 对于常规版本,还需要在C#和C ++之间传递元素大小和通道数。

C# Part: C#部分:

Image<Bgr, Byte> img = ImageSource();
int colWidth = img.Cols * 3;
int img_size = img.Rows * colWidth;
IntPtr unmanaged = Marshal.AllocHGlobal(img_size);
//Copy img data into unmanaged memory
for (int i = 0; i < img.Rows; i++)
    Marshal.Copy(img.Bytes, i * img.MIplImage.WidthStep, img_unmanaged + i * colWidth, 
                 colWidth);

//Call c++ function with
//void FooCpp(IntPtr unmanaged, int rows, int cols);
FooCpp(unmanaged, rows, cols);

//If the values for cols and rows have changed you need to pass them back to c# 
int newColWidth = newCols*3;

//Get back the data: outImg constructor DOES NOT COPY the data
//You can directly use outImg as long as unmanaged lives.
Image<Bgr, Byte> outImg = new Image<Bgr, Byte>(newCols, newRows, newColWidth, unmanaged);
img = outImg.Clone();
Marshal.FreeHGlobal(unmanaged);
unmanaged = IntPtr.Zero;

//continue to use img here

C++ Part: C ++部分:

void FooCpp(unsigned char* imgPtr, int rows, int cols){
    //Optionally: create a cv::Mat image or just use the image data         
    cv::Mat img(rows, cols, CV_8UC3, imgPtr);

    //use and modify img here. 
    //Can also use imgPtr directly as long as you know what you're doing

    //Passback: you can relax row and cols limits as long as the size is smaller
    int newRows = std::min(rows, img.rows);
    int newCols = std::min(cols, img.cols);
    if (img.elemSize() == 3)
        for (int i = 0; i < newRows; i++)
            memcpy(imgPtr + i*newCols*img.elemSize(), img.data + i*img.step, 
                   newCols*img.elemSize());
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM