facebookresearch / Replica-Dataset

The Replica Dataset v1 as published in https://arxiv.org/abs/1906.05797 .
Other
974 stars 98 forks source link

ouput 32 bit EXR images #19

Open parence opened 5 years ago

parence commented 5 years ago

Could you give me some hint on how to render and write to 32 bit exr images instead of 8 bit jpgs?

I saw that pangolin supports writing exr images so I tried by making following changes:

pangolin::GlTexture render(width, height, GL_RGB32F, true, 0, GL_RGB, GL_FLOAT, 0);
pangolin::TypedImage image(width, height, pangolin::PixelFormatFromString("RGB96F"));
render.Download(image);
pangolin::SaveImage(image, std::string(filename));

However, this gives me a somehow 'cropped' image i.e. the content seems to be fine wrt. to the y-axis but horizontally I get only a third of the content stretched to the full width with alternating rgb patterns: exr

I am able to write 16 bit pngs with a similar approach:

pangolin::GlTexture render(width, height, GL_RGB16, true, 0, GL_RGB, GL_UNSIGNED_SHORT, 0);
pangolin::TypedImage image(width, height, pangolin::PixelFormatFromString("RGB48"));

png16

simesgreen commented 5 years ago

I ran into this too -there is a bug in Pangolin::SaveEXR.

https://github.com/stevenlovegrove/Pangolin/blob/master/src/image/image_io_exr.cpp

I'll try and get this fixed, until then you can just use this fixed version of the function:

void SaveExr(const Image<unsigned char>& image_in, const pangolin::PixelFormat& fmt, const std::string& filename, bool top_line_first)
{
#ifdef HAVE_OPENEXR
    ManagedImage<unsigned char> flip_image;
    Image<unsigned char> image;

    if(top_line_first) {
        image = image_in;
    }else{
        flip_image.Reinitialise(image_in.pitch,image_in.h);
        for(size_t y=0; y<image_in.h; ++y) {
            std::memcpy(flip_image.RowPtr(y), image_in.RowPtr(y), image_in.pitch);
        }
        image = flip_image;
    }

    Imf::Header header (image.w, image.h);
    SetOpenEXRChannels(header.channels(), fmt);

    Imf::OutputFile file (filename.c_str(), header);
    Imf::FrameBuffer frameBuffer;

    size_t ch_bits = 0;
    const char* CHANNEL_NAMES[] = {"R","G","B","A"};
    for(unsigned int i=0; i<fmt.channels; i++)
    {
        const Imf::Channel *channel = header.channels().findChannel(CHANNEL_NAMES[i]);
        frameBuffer.insert(
            CHANNEL_NAMES[i],
            Imf::Slice(
                channel->type,
                (char*)image.ptr + (ch_bits/8),
                fmt.bpp/8,  // xstride
                image.pitch // ystride
            )
        );

        ch_bits += fmt.channel_bits[i];
    }

    file.setFrameBuffer(frameBuffer);
    file.writePixels(image.h);

#else
    PANGOLIN_UNUSED(image_in);
    PANGOLIN_UNUSED(fmt);
    PANGOLIN_UNUSED(filename);
    PANGOLIN_UNUSED(top_line_first);
    throw std::runtime_error("EXR Support not enabled. Please rebuild Pangolin.");
#endif // HAVE_OPENEXR
}
dkasuga commented 2 years ago

I rendered 32bit EXR images following the above ways, but sometimes output images have NaN as pixel values. Why does that happen?

Jerrypiglet commented 1 year ago

Same issue with @dkasuga here (see above .exr image from the renderer). Wondering if anyone ever figured out why. image

image

Jerrypiglet commented 1 year ago

Update: after removing gamma and saturation here (which you probably do not want for rendering hdr images), the nan values are gone.