Как конвертировать CBitmap в cv :: Mat? Может быть, есть некоторые библиотеки или что-то еще …
лайк…
CBitmap bitmap;
bitmap.CreateBitmap(128, 128, 1, 24, someData);
cv::Mat outBitmap(128,128,someData,1,24);
но этот код неверен.
Спасибо!
Есть и другой способ, вы можете конвертировать ваши CBitmap
в HBitmap
, а затем конвертировать HBitmap
в GdiPlus::Bitmap
, а затем преобразовать его в cv::Mat
,
Вот что ты можешь сделать, но будьте осторожны, это решение работает только для формата пикселей RGB24 :
Шаг 1: CBitmap
в HBITMAP
HBITMAP hBmp = (HBITMAP)yourCBitmap.GetSafeHandle();
Шаг 2: HBITMAP
в Gdiplus::Bitmap
(скопировано с этот вопрос)
#include <GdiPlus.h>
#include <memory>
Gdiplus::Status HBitmapToBitmap( HBITMAP source, Gdiplus::PixelFormat pixel_format, Gdiplus::Bitmap** result_out )
{
BITMAP source_info = { 0 };
if( !::GetObject( source, sizeof( source_info ), &source_info ) )
return Gdiplus::GenericError;
Gdiplus::Status s;
std::auto_ptr< Gdiplus::Bitmap > target( new Gdiplus::Bitmap( source_info.bmWidth, source_info.bmHeight, pixel_format ) );
if( !target.get() )
return Gdiplus::OutOfMemory;
if( ( s = target->GetLastStatus() ) != Gdiplus::Ok )
return s;
Gdiplus::BitmapData target_info;
Gdiplus::Rect rect( 0, 0, source_info.bmWidth, source_info.bmHeight );
s = target->LockBits( &rect, Gdiplus::ImageLockModeWrite, pixel_format, &target_info );
if( s != Gdiplus::Ok )
return s;
if( target_info.Stride != source_info.bmWidthBytes )
return Gdiplus::InvalidParameter; // pixel_format is wrong!
CopyMemory( target_info.Scan0, source_info.bmBits, source_info.bmWidthBytes * source_info.bmHeight );
s = target->UnlockBits( &target_info );
if( s != Gdiplus::Ok )
return s;
*result_out = target.release();
return Gdiplus::Ok;
}
Вызовите эту функцию и передайте HBITMAP
к этому.
Шаг 3: Gdiplus::Bitmap
в cv::Mat
cv::Mat GdiPlusBitmapToCvMat(Gdiplus::Bitmap* bmp)
{
auto format = bmp->GetPixelFormat();
if (format != PixelFormat24bppRGB)
return cv::Mat();
int width = bmp->GetWidth();
int height = bmp->GetHeight();
Gdiplus::Rect rcLock(0, 0, width, height);
Gdiplus::BitmapData bmpData;
if (!bmp->LockBits(&rcLock, Gdiplus::ImageLockModeRead, format, &bmpData) == Gdiplus::Ok)
return cv::Mat();
cv::Mat mat = cv::Mat(height, width, CV_8UC3, static_cast<unsigned char*>(bmpData.Scan0), bmpData.Stride).clone();
bmp->UnlockBits(&bmpData);
return mat;
}
Пройти Gdiplus::Bitmap
что вы создали в последнем шаге к этой функции, и вы получите свой cv:Mat
, Как я уже говорил, эта функция работает только с пиксельным форматом RGB24.
Других решений пока нет …