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?
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 Mat
s 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 Mat
s.
来源:https://stackoverflow.com/questions/31866822/c-freeimageopencv-16bit-image-get-distorted