c++ - FreeImage+OpenCV - 16bit image get distorted

人盡茶涼 提交于 2019-12-31 06:41:46

问题


I'm trying to load an image because I have to apply an algorithm on it. If I load an 8 bit-per-channel image there are no problems, but if I load a 16bpc image then it get "ruined". Unfortunatly, since I don't have enough reputation I can't uplad images.

Those are the links to them:

Either the source and the 8bpc processing result

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

..result if I process the same image saved as 16bpc

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

And this is the code:

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();

What could it be?


回答1:


The value of depth is not what you expected. It refers to OpenCV depths defined as:

#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

So, if you know that your FreeImage is of type FIT_RGB16, you should use as depth the value CV_16U. You should also convert from RGB to BGR, since OpenCV Mats are in BGR format.

Example here:

#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;
}

Note that you may also avoid to create an additional FreeImage image just to flip it, and let OpenCV Mat to do that:

#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;
}

You can't show this image directly with cv::imshow. You need to convert it to CV_8UC3 type to see it. You can do that for example calling convertScaleAbs(img, img); before imshow.

Or you can refer to this answer for a function to convert all types of FreeImage to OpenCV Mats.



来源:https://stackoverflow.com/questions/31866822/c-freeimageopencv-16bit-image-get-distorted

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!