Loading OpenEXR single channel depth map image

1.1k views Asked by At

I am trying to load a depth image in OpenEXR format with one channel, however, I couldn't figure out the format that I need to use based on this documentation: http://www.openexr.com/documentation/ReadingAndWritingImageFiles.pdf

EDIT: I managed to read the file, but when I try to check the values, they are rounded to the closest integer but I don't understand why that happens.

    Imf::InputFile file (filename.c_str());
    Imath::Box2i dw = file.header().dataWindow();
    int width = dw.max.x - dw.min.x + 1;
    int height = dw.max.y - dw.min.y + 1;

    cv::Mat inputImage = cv::Mat::zeros(cv::Size(width,height), CV_32F );

    Imf::FrameBuffer frameBuffer;
    frameBuffer.insert ("Z", // name
    Imf::Slice (Imf::FLOAT, // type
        (char *) (inputImage.data), // base pointer
        sizeof(CV_32F)*1,         // xStride
        sizeof(CV_32F) * width, // yStride
        1, 1,      // x/y sampling
        0.0));     // fillValue

    file.setFrameBuffer (frameBuffer);
    file.readPixels (dw.min.y, dw.max.y);
    cout << inputImage.at<float>(285,562) << endl;

EDIT2: The exr file can be accessed from here: https://drive.google.com/file/d/1q_AmJgzJjs3bOCCpmcC-X-iAH88PY9dG/view?usp=sharing

1

There are 1 answers

0
Mark Setchell On BEST ANSWER

I think I see two issues, both in the same function call:

Imf::FrameBuffer frameBuffer;
frameBuffer.insert ("Z", // name
Imf::Slice (Imf::FLOAT, // type
    (char *) (inputImage.data  -  dw.min.x - dw.min.y * width), // base pointer
    sizeof(CV_32F)*1,         // xStride
    sizeof(CV_32F) * width, // yStride
    1, 1,      // x/y sampling
    0.0));     // fillValue

Firstly, you OpenCV Mat is sized to the exact width and height of the OpenEXR image, which means you will have problems if you put it at any other place than at the very start of the Mat buffer. So, change this line:

(char *) (inputImage.data  -  dw.min.x - dw.min.y * width), // base pointer

to

(char *) (inputImage.data), // base pointer

Secondly, you use sizeof(CV_32F). The thing is though, that CV_32F is not a type, it is an element in an enumeration of types, so I think you should prefer sizeof(float) since your elements are floats.