代码之家  ›  专栏  ›  技术社区  ›  user3178756

加载OpenEXR单通道深度图图像

  •  0
  • user3178756  · 技术社区  · 6 年前

    我正在尝试用一个通道加载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 回复  |  直到 6 年前
        1
  •  2
  •   Mark Setchell    6 年前

    我想我看到两个问题,都在同一个函数调用中:

    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) 因为你的元素是浮动的。