Преобразование формата FreeImage FIBITMAP в Matrix OpenCV

Я искал ответ, но все, что я могу найти, это инверсия того, что мне нужно (Mat to FIBITMAP). У меня есть короткий код, который загружает изображения как объекты FIBITMAP. Мне нужен FreeImage, потому что OpenCV не позволяет мне загружать pfm и некоторые другие файлы расширений. То, что я пытаюсь сделать, – это преобразовать изображение FIBTMAP в макет OpenCV, чтобы я мог использовать его в гораздо более длинном коде, который у меня уже есть. Как мне это сделать?

Функция funtion FI2MAT выполнит преобразование из FreeImage в OpenCV Mat.

Я не могу полностью протестировать каждый тип формата FreeImage прямо сейчас, но он должен работать так, как ожидалось. Дайте мне знать, есть ли какие-то проблемы с некоторыми форматами.

Помните, что не все типы могут быть правильно imshow , поэтому вам может понадобиться преобразовать изображение раньше.

Вот код с примером:

 #include  #include  using namespace cv; void FI2MAT(FIBITMAP* src, Mat& dst) { //FIT_BITMAP //standard image : 1 - , 4 - , 8 - , 16 - , 24 - , 32 - bit //FIT_UINT16 //array of unsigned short : unsigned 16 - bit //FIT_INT16 //array of short : signed 16 - bit //FIT_UINT32 //array of unsigned long : unsigned 32 - bit //FIT_INT32 //array of long : signed 32 - bit //FIT_FLOAT //array of float : 32 - bit IEEE floating point //FIT_DOUBLE //array of double : 64 - bit IEEE floating point //FIT_COMPLEX //array of FICOMPLEX : 2 x 64 - bit IEEE floating point //FIT_RGB16 //48 - bit RGB image : 3 x 16 - bit //FIT_RGBA16 //64 - bit RGBA image : 4 x 16 - bit //FIT_RGBF //96 - bit RGB float image : 3 x 32 - bit IEEE floating point //FIT_RGBAF //128 - bit RGBA float image : 4 x 32 - bit IEEE floating point int bpp = FreeImage_GetBPP(src); FREE_IMAGE_TYPE fit = FreeImage_GetImageType(src); int cv_type = -1; int cv_cvt = -1; switch (fit) { case FIT_UINT16: cv_type = DataType::type; break; case FIT_INT16: cv_type = DataType::type; break; case FIT_UINT32: cv_type = DataType::type; break; case FIT_INT32: cv_type = DataType::type; break; case FIT_FLOAT: cv_type = DataType::type; break; case FIT_DOUBLE: cv_type = DataType::type; break; case FIT_COMPLEX: cv_type = DataType>::type; break; case FIT_RGB16: cv_type = DataType>::type; cv_cvt = COLOR_RGB2BGR; break; case FIT_RGBA16: cv_type = DataType>::type; cv_cvt = COLOR_RGBA2BGRA; break; case FIT_RGBF: cv_type = DataType>::type; cv_cvt = COLOR_RGB2BGR; break; case FIT_RGBAF: cv_type = DataType>::type; cv_cvt = COLOR_RGBA2BGRA; break; case FIT_BITMAP: switch (bpp) { case 8: cv_type = DataType>::type; break; case 16: cv_type = DataType>::type; break; case 24: cv_type = DataType>::type; break; case 32: cv_type = DataType>::type; break; default: // 1, 4 // Unsupported natively cv_type = -1; } break; default: // FIT_UNKNOWN // unknown type dst = Mat(); // return empty Mat return; } int width = FreeImage_GetWidth(src); int height = FreeImage_GetHeight(src); int step = FreeImage_GetPitch(src); if (cv_type >= 0) { dst = Mat(height, width, cv_type, FreeImage_GetBits(src), step); if (cv_cvt > 0) { cvtColor(dst, dst, cv_cvt); } } else { vector lut; int n = pow(2, bpp); for (int i = 0; i < n; ++i) { lut.push_back(static_cast((255 / (n - 1))*i)); } FIBITMAP* palletized = FreeImage_ConvertTo8Bits(src); BYTE* data = FreeImage_GetBits(src); for (int r = 0; r < height; ++r) { for (int c = 0; c < width; ++c) { dst.at(r, c) = saturate_cast(lut[data[r*step + c]]); } } } flip(dst, dst, 0); } int main() { FreeImage_Initialise(); FREE_IMAGE_FORMAT format = FreeImage_GetFileType("path_to_image", 0); FIBITMAP* fi_image = FreeImage_Load(format, "path_to_image"); Mat cv_img; FI2MAT(fi_image, cv_img); return 0; }