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); }
测试结果如下: