【问题标题】:c++ - FreeImage+OpenCV - 16bit image get distortedc++ - FreeImage+OpenCV - 16bit 图像失真
【发布时间】:2015-08-07 23:13:37
【问题描述】:

我正在尝试加载图像,因为我必须对其应用算法。 如果我加载一个每通道 8 位的图像,则没有问题,但如果我加载一个 16bpc 的图像,那么它就会被“破坏”。不幸的是,由于我没有足够的声誉,我无法上传图片。

这些是它们的链接:

来源和8bpc处理结果

http://postimg.org/image/gc0zf2lp5/

..result 如果我处理保存为 16bpc 的相同图像

http://postimg.org/image/5nnwee7df/

这是代码:

FreeImage_Initialise();
FREE_IMAGE_FORMAT formato = FreeImage_GetFileType(argv[1], 0);
FIBITMAP* imagetmp = FreeImage_Load(format, argv[1]);
FIBITMAP* image = FreeImage_Rotate(imagetmp, 180);
FreeImage_FlipHorizontal(image);
int depth = FreeImage_GetBPP(image);
printf("depth = %d\n", FreeImage_GetPitch(image));
cv::Mat img(FreeImage_GetHeight(image), FreeImage_GetWidth(image), CV_MAKETYPE(depth/3, 3), FreeImage_GetBits(image), FreeImage_GetPitch(image));
FreeImage_DeInitialise();

会是什么?

【问题讨论】:

    标签: c++ opencv depth freeimage


    【解决方案1】:

    depth 的值不是您所期望的。它指的是 OpenCV 深度定义为:

    #define CV_8U   0
    #define CV_8S   1
    #define CV_16U  2
    #define CV_16S  3
    #define CV_32S  4
    #define CV_32F  5
    #define CV_64F  6
    

    因此,如果您知道 FreeImage 的类型为 FIT_RGB16,则应使用值 CV_16U 作为深度。您还应该将 RGB 转换为 BGR,因为 OpenCV Mats 是 BGR 格式。

    这里的例子:

    #include <FreeImage.h>
    #include <opencv2\opencv.hpp>
    using namespace cv;
    
    int main()
    {
        FreeImage_Initialise();
        FREE_IMAGE_FORMAT format = FreeImage_GetFileType("path_to_image", 0);
        FIBITMAP* imagetmp = FreeImage_Load(format, "path_to_image");
        FIBITMAP* image = FreeImage_Rotate(imagetmp, 180);
        FreeImage_FlipHorizontal(image);
        int depth = FreeImage_GetBPP(image);
        printf("depth = %d\n", FreeImage_GetPitch(image));
    
        // FreeImage to Mat conversion
        cv::Mat img(FreeImage_GetHeight(image), FreeImage_GetWidth(image), CV_MAKETYPE(CV_16U, 3), FreeImage_GetBits(image), FreeImage_GetPitch(image));
        cvtColor(img, img, CV_BGR2RGB);
    
        FreeImage_DeInitialise();
    
        return 0;
    }
    

    请注意,您也可以避免创建额外的 FreeImage 图像来翻转它,并让 OpenCV Mat 来做:

    #include <FreeImage.h>
    #include <opencv2\opencv.hpp>
    using namespace cv;
    
    int main()
    {       
        FreeImage_Initialise();
        FREE_IMAGE_FORMAT format = FreeImage_GetFileType("path_to_image", 0);
        FIBITMAP* image = FreeImage_Load(format, "path_to_image");
    
        // FreeImage to Mat conversion
        cv::Mat img(FreeImage_GetHeight(image), FreeImage_GetWidth(image), CV_MAKETYPE(CV_16U, 3), FreeImage_GetBits(image), FreeImage_GetPitch(image));
        cvtColor(img, img, CV_BGR2RGB);
        flip(img,img,0);
    
        FreeImage_DeInitialise();
    
        return 0;
    }
    

    您无法使用cv::imshow 直接显示此图片。您需要将其转换为CV_8UC3 类型才能看到它。您可以这样做,例如在imshow 之前调用convertScaleAbs(img, img);

    或者你可以参考this的答案,获取将所有类型的FreeImage转换为OpenCV的函数Mats。

    【讨论】:

      猜你喜欢
      • 2022-01-09
      • 1970-01-01
      • 2013-12-29
      • 1970-01-01
      • 2017-11-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多