I'm trying to develop a small C++/CLI wrapper around OpenCV for use in a C# application. I can't use Emgu since it's for a commercial application.
I'm facing a problem when I'm trying to convert from System.Drawing.Bitmap
to OpenCV Mat
.
I have the following code:
cv::Mat BitmapToMat(System::Drawing::Bitmap^ bitmap)
{
System::Drawing::Rectangle blank = System::Drawing::Rectangle(0, 0, bitmap->Width, bitmap->Height);
System::Drawing::Imaging::BitmapData^ bmpdata = bitmap->LockBits(blank, System::Drawing::Imaging::ImageLockMode::ReadWrite, System::Drawing::Imaging::PixelFormat::Format24bppRgb);
cv::Mat cv_img(cv::Size(bitmap->Width, bitmap->Height), CV_8UC3, bmpdata->Scan0.ToPointer(), cv::Mat::AUTO_STEP);
bitmap->UnlockBits(bmpdata);
return cv_img;
}
I'm using it in cpp file to test out the generated Mat like this:
Mat image = BitmapToMat(templateImage);
cv::imwrite("some2.jpg", image);
But the image produced is completely distorted (see images)
INPUT BITMAP IMAGE
RESULT MAT IMAGE SAVED TO FILE
Windows bitmaps are padded. You want to calculate "width in bytes" of the bitmap row, and supply that instead of cv::Mat::AUTO_STEP
:
int wb = ((bitmap->Width * 24 + 31) / 32) * 4;
cv::Mat cv_img(cv::Size(bitmap->Width, bitmap->Height),
CV_8UC3, bmpdata->Scan0.ToPointer(), wb);