wi Yu
wi Yu

Reputation: 393

C++ DLL return Mat to C#

I have a DLL build in C++, and will return Mat object. That picture info is 384*384*24 color.

C# code

Bitmap a = new Bitmap(384, 384, 3 * 384, PixelFormat.Format24bppRgb, test1());
pictureBox0.Image = a;

C++ code

uchar*  DLL_EXPORT test1(void)
{
    Mat OriginalImg = imread("c:\\20100812133.jpg", 1 );

    return OriginalImg.data;
}

upon code are ok, but I want to read the picture in gray. I will do some image process(ex:Threshod), and convert to color, and return to C# and show it!

C++ code

uchar*  DLL_EXPORT test0(void)
{
    Mat OriginalImg = imread("c:\\20100812133.jpg", 0 );
    threshold(OriginalImg,OriginalImg,0,255,THRESH_OTSU);
    cvtColor(OriginalImg,OriginalImg,CV_GRAY2BGR);
    return OriginalImg.data;
}

The c++ code fails, can you help?


updata http://ppt.cc/h2SI the picture is fail, i think the cause is memory. I fix c# code the 3st parmet 3*384 to 2*384. C# is run ok, but picture is break like this http://ppt.cc/IRfd

-- updata

Bitmap a = new Bitmap(384, 384, 1 * 384, PixelFormat.Format24bppRgb, test0());
Bitmap a = new Bitmap(384, 384, 2 * 384, PixelFormat.Format24bppRgb, test0());
Bitmap a = new Bitmap(384, 384, 3 * 384, PixelFormat.Format24bppRgb, test0());

Bitmap a = new Bitmap(384, 384, 2 * 384, PixelFormat.Format32bppRgb, test0());
Bitmap a = new Bitmap(384, 384, 3 * 384, PixelFormat.Format32bppRgb, test0());
Bitmap a = new Bitmap(384, 384, 4 * 384, PixelFormat.Format32bppRgb, test0());

i try six , run are ok, but picture are break.

Upvotes: 2

Views: 4771

Answers (2)

Ben Voigt
Ben Voigt

Reputation: 283624

You're returning a pointer to a local variable that's already been freed, that will never be reliable.

You need to arrange for the Mat object to live long enough for the Bitmap constructor to copy its contents. The simplest approach would be to use C++/CLI, then you can return a .NET Bitmap from C++:

Bitmap^ MyImageProcessor::test0(void)
{
    Mat OriginalImg = imread("c:\\20100812133.jpg", 0 );
    threshold(OriginalImg,OriginalImg,0,255,THRESH_OTSU);
    cvtColor(OriginalImg,OriginalImg,CV_GRAY2BGR);
    return gcnew Bitmap(384,
                        384,
                        3 * 384,
                        PixelFormat.Format24bppRgb,
                        IntPtr(OriginalImg.data)
                       );
}

Upvotes: 1

Sam
Sam

Reputation: 20058

Did you check the imread success?

Mat OriginalImg = imread("c:\\20100812133.jpg", 0 );
if(OriginalImg.empty())
    return NULL;

And in C# (Note that the code I wrote is not necessarily correct, but you get the idea)

char* imgData = test1;

if(imgData == Null)
{
 // do something smart
}

Bitmap a = new Bitmap(384, 384, 3 * 384, PixelFormat.Format24bppRgb, imgData);
pictureBox0.Image = a;

This is one of the most frequent mistakes you can do in programming - and one of the most annoying

Upvotes: 0

Related Questions