2015-08-06 8 views
0

Я пытаюсь загрузить изображение, потому что я должен применить на нем алгоритм. Если я загружаю изображение с 8-битным каналом, проблем нет, но если я загружу изображение 16bpc, оно будет «разрушено». К сожалению, поскольку у меня недостаточно репутации, я не могу уладить изображения.C++ - FreeImage + OpenCV - 16-разрядное изображение искажается

Те ссылки на них:

Либо источник и результат обработки 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(); 

Что это может быть?

ответ

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 s находятся в формате 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 s.

 Смежные вопросы

  • Нет связанных вопросов^_^