Загрузка OpenEXR одноканальной карты глубины - PullRequest
0 голосов
/ 15 ноября 2018

Я пытаюсь загрузить изображение глубины в формате OpenEXR с одним каналом, однако я не могу определить формат, который мне нужно использовать, основываясь на этой документации: http://www.openexr.com/documentation/ReadingAndWritingImageFiles.pdf

РЕДАКТИРОВАТЬ: мне удалось прочитать файл, но когда я пытаюсь проверить значения, они округляются до ближайшего целого числа, но я не понимаю, почему это происходит.

    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: файл exr доступен здесь: https://drive.google.com/file/d/1q_AmJgzJjs3bOCCpmcC-X-iAH88PY9dG/view?usp=sharing

1 Ответ

0 голосов
/ 16 ноября 2018

Я думаю, что вижу две проблемы, обе в одном и том же вызове функции:

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

Во-первых, ваш OpenCV Mat имеет размер, точно соответствующий ширине и высоте изображения OpenEXR, что означает, что у вас будут проблемыесли вы поместите его в любое другое место, кроме самого начала буфера Mat.Итак, измените эту строку:

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

на

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

Во-вторых, вы используете sizeof(CV_32F).Дело в том, что CV_32F не является типом, это элемент в перечислении типов, поэтому я думаю, что вы должны предпочесть sizeof(float), поскольку ваши элементы являются числами с плавающей точкой.

...