freeimage数据转opencv数据

freeimage存储格式为FIBITMAP;

opencv存储格式为cv::Mat;

freeimage善于读取和保存各种格式的图片;

opencv具备各种图像处理算法;

真实项目中经常会将两者结合,发挥各自最大优势。

本贴将实现FIBITMAP数据转换为Mat格式,以供程序后续处理。

话不多说,直接上代码:

转换功能实现如下:

bool FImageToMat(FIBITMAP* bitmap, cv::Mat& mat)
{
    FREE_IMAGE_TYPE fit = FreeImage_GetImageType(bitmap);
    int wid = FreeImage_GetWidth(bitmap);
    int hei = FreeImage_GetHeight(bitmap);
    int dstr = 0;
    switch(fit){
    case FIT_BITMAP:
    {
        int bpp = FreeImage_GetBPP(bitmap);
        switch(bpp){
        case 1:{
            mat = cv::Mat(hei, wid, CV_8UC1, cv::Scalar(0));
            BYTE byindex = 0;
            for(int r = 0; r < hei; r++)
            {
                dstr = hei - r - 1;
                for(int c = 0; c < wid; c++)
                {
                    FreeImage_GetPixelIndex(bitmap, c, r, &byindex);
                    if(1 == byindex){
                        mat.at<uchar>(dstr, c) = 255;
                    }else{
                        mat.at<uchar>(dstr, c) = 0;
                    }
                }
            }
        }
            break;
        case 8:{
            mat = cv::Mat(hei, wid, CV_8UC1, cv::Scalar(0));
            BYTE byindex = 0;
            for(int r = 0; r < hei; r++)
            {
                dstr = hei - r - 1;
                for(int c = 0; c < wid; c++)
                {
                    FreeImage_GetPixelIndex(bitmap, c, r, &byindex);
                    mat.at<uchar>(dstr, c) = byindex;
                }
            }
        }
            break;
        case 24:
        case 32:{
            mat = cv::Mat(hei, wid, CV_8UC3, cv::Scalar(0));
            RGBQUAD clr = {0};
            for(int r = 0; r < hei; r++)
            {
                dstr = hei - r - 1;
                for(int c = 0; c < wid; c++)
                {
                    FreeImage_GetPixelColor(bitmap, c, r, &clr);
                    mat.at<cv::Vec3b>(dstr, c)[0] = clr.rgbBlue;
                    mat.at<cv::Vec3b>(dstr, c)[1] = clr.rgbGreen;
                    mat.at<cv::Vec3b>(dstr, c)[2] = clr.rgbRed;
                }
            }
        }
            break;
        default:
            qWarning() << "unknown bpp:" << bpp;
            return false;
        }
    }
        break;
    case FIT_UINT16:{
        mat = cv::Mat(hei, wid, CV_16UC1, cv::Scalar(0));
        BYTE *psrc = nullptr;
        uint usize = mat.cols*mat.depth();
        for(int r = 0; r < hei; r++)
        {
            dstr = hei - r - 1;
            psrc = FreeImage_GetScanLine(bitmap, r);
            memcpy(mat.ptr(dstr), psrc, usize);
        }
    }
        break;
    default:
        qWarning() << "unknown free image type:" << fit;
        return false;
    }
    if(!mat.empty()){
        return true;
    }
    return false;
}

 

调用如下:

std::string str = qstr2str(filename);
qDebug() << filename  << str.size();
    FREE_IMAGE_FORMAT fif = FreeImage_GetFIFFromFilename(str.c_str());
    FIBITMAP* fbm = FreeImage_Load(fif, str.c_str());
    cv::Mat mat;
    FImageToMat(fbm, mat);
    qDebug() << mat.rows << mat.cols << mat.depth();
    if(!mat.empty()){
        showMat(filename.toStdString(), mat);
    }

 

测试结果如下:

 

posted @ 2022-12-02 17:48  larkin-cn  阅读(120)  评论(0编辑  收藏  举报