c ++ – FreeImage + OpenCV – Les images 16 bits sont déformées

J’essaie de charger une image parce que je dois lui appliquer un algorithme. Si je charge une image de 8 bits par canal, il n’y a pas de problèmes, mais si je charge une image de 16 bpc, elle se “ruine” Malheureusement, comme je n’ai pas assez de réputation, je ne peux pas télécharger des images.

Ce sont les liens vers eux:

Soit le résultat de traitement source et le traitement 8bpc

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

..result si je traite la même image enregistrée en 16bpc

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

Et voici le 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(); 

Qu’est ce que ça pourrait être?

La valeur de la depth n’est pas ce que vous attendiez. Il fait référence aux profondeurs OpenCV définies comme suit:

 #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 

Donc, si vous savez que votre FreeImage est de type FIT_RGB16 , vous devez utiliser comme profondeur la valeur CV_16U . Vous devez également convertir de RVB à BGR, car les fichiers OpenCV sont au format BGR.

Exemple ici:

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

Notez que vous pouvez également éviter de créer une image FreeImage supplémentaire simplement pour la retourner, puis laissez OpenCV Mat le faire:

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

Vous ne pouvez pas afficher cette image directement avec cv::imshow . Vous devez le convertir en type CV_8UC3 pour le voir. Vous pouvez le faire, par exemple, en appelant convertScaleAbs(img, img); avant imshow .

Vous pouvez également vous référer à cette réponse pour une fonction permettant de convertir tous les types de FreeImage en formats OpenCV.