将FreeImage FIBITMAP格式转换为OpenCV Mat [英] Convert FreeImage FIBITMAP format to OpenCV Mat

查看:871
本文介绍了将FreeImage FIBITMAP格式转换为OpenCV Mat的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在搜索一个答案,但我能找到的是我需要的反向(Mat到FIBITMAP)。
我有一个短代码,作为FIBITMAP对象加载图像。我需要FreeImage,因为OpenCV不允许我加载pfm和一些其他扩展文件。
我想做的是将FIBTMAP图像转换为OpenCV Mat,以便我可以在已经有更长的代码中使用它。
我如何做?

解决方案

功能 FI2MAT 将执行从FreeImage到OpenCV Mat的转换。



我现在无法彻底测试每种类型的FreeImage格式,但它应该能正常工作。



请记住,并非所有类型都可以通过 imshow



<$ p

p> #include< FreeImage.h>
#include< opencv2\opencv.hpp>
using namespace cv;

void FI2MAT(FIBITMAP * src,Mat& dst)
{
// FIT_BITMAP //标准映像:1 - ,4 - ,8 - ,16 - ,32位
// FIT_UINT16 //无符号数组short:无符号16位
// FIT_INT16 //数组short:signed 16位
// FIT_UINT32 //数组unsigned long:unsigned 32-bit
// FIT_INT32 //数组long:signed 32位
// FIT_FLOAT //数组float:32位IEEE浮点
// FIT_DOUBLE //双double数组:64位IEEE浮点
// FIT_COMPLEX // FICOMPLEX数组:2 x 64位IEEE浮点
// FIT_RGB16 // 48位RGB图像:3 x 16位
// FIT_RGBA16 // 64位RGBA图像:4 x 16位
// FIT_RGBF // 96位RGB浮点图像:3 x 32位IEEE浮点
// FIT_RGBAF // 128位RGBA浮点图像:4 x 32位IEEE浮点

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< ushort> :: type;打破;
case FIT_INT16:cv_type = DataType< short> :: type;打破;
case FIT_UINT32:cv_type = DataType< unsigned> :: type;打破;
case FIT_INT32:cv_type = DataType< int> :: type;打破;
case FIT_FLOAT:cv_type = DataType< float> :: type;打破;
case FIT_DOUBLE:cv_type = DataType< double> :: type;打破;
case FIT_COMPLEX:cv_type = DataType< Complex< double>> :: type:打破;
case FIT_RGB16:cv_type = DataType< Vec< ushort,3>> :: type; cv_cvt = COLOR_RGB2BGR;打破;
case FIT_RGBA16:cv_type = DataType< Vec< ushort,4>> :: type; cv_cvt = COLOR_RGBA2BGRA;打破;
case FIT_RGBF:cv_type = DataType< Vec< float,3>> :: type; cv_cvt = COLOR_RGB2BGR;打破;
case FIT_RGBAF:cv_type = DataType< Vec< float,4>> :: type; cv_cvt = COLOR_RGBA2BGRA;打破;
case FIT_BITMAP:
switch(bpp){
case 8:cv_type = DataType< Vec uchar,1> :: type;打破;
case 16:cv_type = DataType< Vec< uchar,2>> :: type;打破;
case 24:cv_type = DataType< Vec< uchar,3>> :: type;打破;
case 32:cv_type = DataType< Vec< uchar,4>> :: type;打破;
默认值:
// 1,4 //不支持原生
cv_type = -1;
}
break;
默认值:
// FIT_UNKNOWN //未知类型
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 {

矢量< uchar> ;
int n = pow(2,bpp);
for(int i = 0; i {
lut.push_back(static_cast< uchar>((255 /(n-1))* );
}

FIBITMAP * palletized = FreeImage_ConvertTo8Bits(src);
BYTE * data = FreeImage_GetBits(src);
for(int r = 0; r for(int c = 0; c< width; ++ c){
dst.at& uchar>(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;
}


I've been searching on an answer but all I can find is the inverse of what I need (Mat to FIBITMAP). I have a short code that loads images as FIBITMAP objects. I need FreeImage because OpenCV doesn't allow me to load pfm and some other extension files. What I'm trying to do is convert the FIBTMAP image into an OpenCV Mat so that I can use this in a much longer code I already have. How do I do?

解决方案

The funtion FI2MAT will perform the conversion from FreeImage to OpenCV Mat.

I cannot thoroughly test each type of FreeImage format right now, but it should work as expected. Let me know if there are some issues with some formats.

Remember that not all types may be rendered correctly by imshow, so you may need to convert the image before.

Here the code with an example:

#include <FreeImage.h>
#include <opencv2\opencv.hpp>
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<ushort>::type; break;
    case FIT_INT16: cv_type = DataType<short>::type; break;
    case FIT_UINT32: cv_type = DataType<unsigned>::type; break;
    case FIT_INT32: cv_type = DataType<int>::type; break;
    case FIT_FLOAT: cv_type = DataType<float>::type; break;
    case FIT_DOUBLE: cv_type = DataType<double>::type; break;
    case FIT_COMPLEX: cv_type = DataType<Complex<double>>::type; break;
    case FIT_RGB16: cv_type = DataType<Vec<ushort, 3>>::type; cv_cvt = COLOR_RGB2BGR; break;
    case FIT_RGBA16: cv_type = DataType<Vec<ushort, 4>>::type; cv_cvt = COLOR_RGBA2BGRA; break;
    case FIT_RGBF: cv_type = DataType<Vec<float, 3>>::type; cv_cvt = COLOR_RGB2BGR; break;
    case FIT_RGBAF: cv_type = DataType<Vec<float, 4>>::type; cv_cvt = COLOR_RGBA2BGRA; break;
    case FIT_BITMAP:
        switch (bpp) {
        case 8: cv_type = DataType<Vec<uchar, 1>>::type; break;
        case 16: cv_type = DataType<Vec<uchar, 2>>::type; break;
        case 24: cv_type = DataType<Vec<uchar, 3>>::type; break;
        case 32: cv_type = DataType<Vec<uchar, 4>>::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<uchar> lut;
        int n = pow(2, bpp);
        for (int i = 0; i < n; ++i)
        {
            lut.push_back(static_cast<uchar>((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<uchar>(r, c) = saturate_cast<uchar>(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;
}

这篇关于将FreeImage FIBITMAP格式转换为OpenCV Mat的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆