c ++ - FreeImage + OpenCV - 16位图像失真

时间:2015-08-06 22:28:35

标签: c++ opencv depth freeimage

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

这些是他们的链接:

源和8bpc处理结果

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

..如果我处理保存为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();

它可能是什么?

1 个答案:

答案 0 :(得分: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 Mat是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类型才能看到它。您可以执行此操作,例如在convertScaleAbs(img, img);之前调用imshow

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