RenderKit / oidn

Intel® Open Image Denoise library
https://www.openimagedenoise.org/
Apache License 2.0
1.77k stars 164 forks source link

Black output #49

Closed flaviu22 closed 4 years ago

flaviu22 commented 4 years ago

I have tried the following code:

    ImageBuffer color = loadImage(_T("D:\\Temp\\memorial.pfm"));
    const int width = color.getWidth();
    const int height = color.getHeight();
    // Initialize the output image
    ImageBuffer output(width, height, 3);
    oidn::DeviceRef device = oidn::newDevice();
    oidn::FilterRef filter = device.newFilter("RT");
    filter.commit();
    filter.setImage("color", color.getData(), oidn::Format::Float3, width, height);
    filter.setImage("output", output.getData(), oidn::Format::Float3, width, height);
    filter.set("hdr", true);
    filter.commit();
    filter.execute();
    saveImage(_T("D:\\Temp\\memorial_output.pfm"), output);

but the output image are completely black ... the code seem simple and clear ... I have done something wrong ?

I attach here the input image and also the ouput result ... can you take a look ? Might be something simple, but I can't see what ... memorial.zip memorial_output.zip

jmengintel commented 4 years ago

I think the problem is that you are calling filter.commit() twice. The first call will fail because the filter isn't set up correctly at this point. Can you try removing the first call? If you set an error handler (setErrorFunction), you will get an error message (which admittedly isn't great in this particular case, we'll work on that...).

flaviu22 commented 4 years ago

Thank you for your answer. Yes, I removed the first filter.commit(), and the result is the same. I will set an error handler to get the error string and I will get back the news. See you.

flaviu22 commented 4 years ago

I tested the following code:

    ImageBuffer color = loadImage(_T("D:\\Temp\\memorial.pfm"));
    const int width = color.getWidth();
    const int height = color.getHeight();
    // Initialize the output image
    ImageBuffer output(width, height, 3);
    oidn::DeviceRef device = oidn::newDevice();
    oidn::FilterRef filter = device.newFilter(_T("RT"));
    filter.setImage(_T("color"), color.getData(), oidn::Format::Float3, width, height);
    filter.setImage("output", output.getData(), oidn::Format::Float3, width, height);
    filter.set(_T("hdr"), true);
    filter.commit();
    filter.execute();
    const char* errorMessage;
    if (device.getError(errorMessage) != oidn::Error::None)
        TRACE("Error: %s\n", errorMessage);
    saveImage(_T("D:\\Temp\\memorial_output.pfm"), output);

and the error message sound like this:

Error: changes to the device are not committed What does it mean ?

jmengintel commented 4 years ago

Oh, I should have spotted that! It means that you are not calling commit() on the device. So something like this:

oidn::DeviceRef device = oidn::newDevice();
device.commit();

You can also set parameters on the device before calling commit, as well. Our example program uses that to configure the number of threads, affinity, and verbosity.

flaviu22 commented 4 years ago

@jomeng Yes, that was the problem. Now it works.

P.S. Where can I find some code sample to improve the quality of the image just like in the presentation site ? Or should I improve the output image on and on ?

For this reason I didn't closed the post yet, but the reported issue has been solved.

jmengintel commented 4 years ago

Can you point me to the examples you want to reproduce?

flaviu22 commented 4 years ago

I take a picture from below:

tv

    ImageBuffer color = loadImage(_T("D:\\Temp\\test.pfm"));
    const int width = color.getWidth();
    const int height = color.getHeight();
    // Initialize the output image
    ImageBuffer output(width, height, 3);
    oidn::DeviceRef device = oidn::newDevice();
    device.set(_T("setAffinity"), true);
    device.set(_T("verbose"), 3);
    device.set(_T("numThreads"), 4);
    device.commit();
    oidn::FilterRef filter = device.newFilter(_T("RT"));
    filter.setImage(_T("color"), color.getData(), oidn::Format::Float3, width, height);
    filter.setImage("output", output.getData(), oidn::Format::Float3, width, height);
    filter.set(_T("hdr"), true);
    filter.commit();
    filter.execute();
    saveImage(_T("D:\\Temp\\test_ouput.pfm"), output);

and with code from above I intend to remove the noisy, but visible de-noised ... this image are just for testing purpose, but I have real images with peoples and I cannot upload here ...

And, if I don't push my luck, I don't know what if with normal/albedo images from examples (and I saw a lot on internet), all of them include "normal" image and "albedo" image example ... did they help with something ? Should I generate those images ? What are those images ? Any word from you is valuable a lot for me !!

flaviu22 commented 4 years ago

I noticed that if I repeat the code from above to every output image, the next output image are more clear. I guess this is a mode to de-noise images ...

jmengintel commented 4 years ago

Albedo and normal images help the denoiser understand which areas in the image contain real geometric detail, or texture detail, and thus should not be filtered too much. There is a lot more information on this in our documentation.

Are you using Open Image Denoise on camera images? Results may vary there because OIDN is optimized specifically for Monte Carlo rendering at this point. Also, denoising the same image multiple times will probably blur the image more and more, but the denoiser is really meant to be run just once.

atafra commented 4 years ago

Open Image Denoise works only with Monte Carlo ray traced images. It does not work with camera images at all. Also, an image should be denoised only once. There are no benefits of denoising it multiple times.

flaviu22 commented 4 years ago

In the end, I intend to use this excellent library to denoise CT DICOM images (dicom medical images) ... are they camera images ? Or Monte Carlo ray traced images ?

flaviu22 commented 4 years ago

@jomeng @atafra your informations are most valuable ... I didn't knew those things ...

flaviu22 commented 4 years ago

DICOM medical images could be counted as ray trace images or not ? Anyway, dicom images must be converted before apply this algorithm anyway ...

flaviu22 commented 4 years ago

You meant "Ray-Tracing" images ?

"Ray-Casting vs. Ray-Tracing

I would like to emphasize a pivotal difference between ‘ray-casting’ and ‘ray-tracing.’ In the case of the former, we only ‘cast’ a single ray, test for its intersection with objects, and retrieve information regarding the intersection. Ray-tracing, on the other hand, is more physically accurate, as it applies laws of physics (e.g., reflection, refraction, attenuation, etc.) to the rays to ‘trace’ (i.e., follow) that ray and its derivative rays. However, ray-casting is the natural precursor to ray-tracing, as it tells us with what part of which object the ray intersects and provides all necessary information to cast subsequent rays." Taken from here: https://blog.kitware.com/ray-casting-ray-tracing-with-vtk/

atafra commented 4 years ago

Open Image Denoise works only with computer generated images, rendered with ray tracing algorithms, so it doesn't work with medical images either.

flaviu22 commented 4 years ago

Thank you @atafra . However, this is a bad news though ... from you expertise, there is a way to denoise medical images ? Or, there is a possibility to extend your library for camera images ? I expect an answer from you in order to close this issue :)

jmengintel commented 4 years ago

There are certainly techniques for that. In fact denoising for medical imaging seems to be an active field of research, there are many current publications on this topic! So I'm sure there are specialized software packages for just this application. However, our focus remains Monte Carlo rendering.

I'll close this issue for now, but feel free to get back to us with further questions. Let me just reiterate, and @atafra already wrote this above: Open Image Denoise should not be used for medical image processing.