Ask Your Question
0

FreeImage Lib: convert raw image to cv::Mat

asked 2015-03-25 16:59:42 -0600

JohannesZ gravatar image

updated 2015-03-30 15:19:59 -0600

Hi there,

are there any FreeImage users in this cmmunity? I am posting here because the FreeImage users were sadly not able to help me yet... I am trying to convert a FreeImage RAW image (Sony ARW File) data structure with the following specs:

type: FIT_RGB16 bits per pixel: 48

to a cv::Mat data structure. Besides a lot of tests, I tried the following:

//image dimensions
int cols = FreeImage_GetWidth(rawImage);
int rows = FreeImage_GetHeight(rawImage);

FIRGB16* bits = (FIRGB16* )FreeImage_GetScanLine(rawImage, 0);

cv::Mat preview(rows, cols, CV_16UC3, bits, cols * 3);

There is always a segmentation fault. Can you tell me what I am doing wrong? Since a 48bit image is not so special I really don't understand what I am doing wrong.

Any tips are really appreciated! JohannesZ

edit retag flag offensive close merge delete

Comments

2

when does the segfault happen ?

this Mat constructor works with a 'borrowed' pointer to the pixel data. if FIRGB16* bits goes out of scope, your Mat will be invalid.

try to work with a clone(), to achieve a 'deep' copy:

cv::Mat img = preview.clone();
berak gravatar imageberak ( 2015-03-26 04:25:31 -0600 )edit

Hi Berak, thanks for your comment! The seg fault happens right after the execution of the statement, this means I have no chance to execute your suggesion.

A "normal" 8 bit image, eg. 24 bit for RGB, works without any problems:

BYTE *bits = (BYTE *)FreeImage_GetScanLine(rawImage, 0);
cv::Mat image(height, width, CV_8UC3, bits, FreeImage_GetWidth(rawImage)*3);
JohannesZ gravatar imageJohannesZ ( 2015-03-26 07:45:34 -0600 )edit
1

do you have to give a row-stride ?

try either to omit that, else, imho, the stride is cols*channels*elemSize (so yours is too short in the 16bit case.)

berak gravatar imageberak ( 2015-03-26 07:49:52 -0600 )edit

sorry, I don't understand what you mean exactly with "row stride". Is this some kind of step parameter?

JohannesZ gravatar imageJohannesZ ( 2015-03-26 07:58:54 -0600 )edit
1

ah, step, ofc. couldn't remember the correct word.

berak gravatar imageberak ( 2015-03-26 09:41:07 -0600 )edit
3

I've never used FreeImage, but I think you can use the FreeImage.GetBits method to get the data pointer and the FreeImage.GetPitch method for the step calculation.

So maybe something like:

FIRGB16* bits = (FIRGB16*)FreeImage_GetBits(rawImage);
size_t step = FreeImage_GetPitch(rawImage);
cv::Mat preview(rows, cols, CV_16UC3, (void*)bits, step);
boaz001 gravatar imageboaz001 ( 2015-03-26 12:10:45 -0600 )edit

1 answer

Sort by ยป oldest newest most voted
2

answered 2015-03-30 15:13:06 -0600

JohannesZ gravatar image

updated 2015-03-30 15:18:46 -0600

Hi berak and boaz, you both gave me the right hint, thank you very much!

This code is working now:

FIRGB16* bits = (FIRGB16*)FreeImage_GetBits(rawImage);
size_t step = FreeImage_GetPitch(rawImage);
cv::Mat preview(rows, cols, CV_16UC3, (void*)bits, step);
edit flag offensive delete link more

Comments

Since the ToneMapping operator "Reinhard" in openCV 3.0 beta only accepts an image of type "32S" I have made the following conversion:

    //preview32 must be a matrix of data type 32S:
    cv::Mat preview32;
    preview.convertTo(preview32, 21);

    //ToneMap
    cv::Ptr<cv::TonemapReinhard> reinhard = cv::createTonemapReinhard();
    cv::Mat result;
    reinhard->process(preview32, result);
    result.convertTo(result, CV_8UC3, 255);

    cv::Mat resultC;
cv::cvtColor(result, resultC, cv::COLOR_BGR2RGB)

Dou you think this is an elegant way of converting these matrices or can be there a better/faster way to achieve this?

JohannesZ gravatar imageJohannesZ ( 2015-03-30 15:18:33 -0600 )edit
1

I think it is. Only thing I would change is the 'magic number' 21. You can just use CV_<bit-depth>{U|S|F}C(<number_of_channels>) - format.

boaz001 gravatar imageboaz001 ( 2015-03-30 17:15:37 -0600 )edit

Thanks for your answer! Do you mean the make-type macro? CV_MAKETYPE(depth, 3)?

JohannesZ gravatar imageJohannesZ ( 2015-03-31 05:35:25 -0600 )edit

Yes that one, or if the depth is known (say 32 bits signed): CV_32SC3

boaz001 gravatar imageboaz001 ( 2015-03-31 05:39:27 -0600 )edit

Question Tools

1 follower

Stats

Asked: 2015-03-25 16:59:42 -0600

Seen: 3,096 times

Last updated: Mar 30 '15