Wiredchop
Wiredchop

Reputation: 145

System::Drawing::Bitmap to cv::Mat (OpenCV c++/cli)

I'm trying to convert a System::Drawing::Bitmap into a cv::Mat for what will eventually be a wrapper for c# (can't use EMGU in this case). I've seen lots of examples of how to construct a cv::Mat using a pointer to the Bitmap's data but my cv image is junk (a few pixels of junk and then nothing).

My code is:

System::Drawing::Rectangle blank = System::Drawing::Rectangle(0, 0, _image->Width, _image->Height);
System::Drawing::Imaging::BitmapData^ bmpdata = image.LockBits(blank,System::Drawing::Imaging::ImageLockMode::ReadWrite,System::Drawing::Imaging::PixelFormat::Format24bppRgb);
cv::Mat thisimage(cv::Size(image.Width, image.Height), CV_8UC3,bmpdata->Scan0.ToPointer(),cv::Mat::AUTO_STEP);
image.UnlockBits(bmpdata);

I've tried all sorts of things and attempted to copy the bytes directly but can't seem to get the syntax correctly. However, no matter what I do the image never seems to be converted correctly. I'm using visual studio's image watch add-on to check my images and if I load a cv::Mat directly from file it's all fine.

Upvotes: 3

Views: 3287

Answers (1)

Wiredchop
Wiredchop

Reputation: 145

I found the problem. Earlier on in my code I was cloning the bitmap without creating a pointer to the clone. I.e.

 ::Bitmap myclone

rather than

::Bitmap ^myclone

I had done this to try and avoid memory errors I was getting. Since then I've set up the project so I can debug the native code and see what's going on. I seem to have got rid of the memory error and used my original Bitmap object rather than the clone. It seems to be working now. To make a deep copy of my cv::Mat I have also cloned that. I did this so that it wasn't pointing to my original bitmap on the managed heap. I have no idea whether this is necessary or not but it seems to be working for now.

Upvotes: 1

Related Questions