1
$\begingroup$

I'm trying to use open image denoise. Here's the code:

int main() {
    int width, height, nrChannels;
    unsigned char* image = stbi_load("img_cornell_box.png", &width, &height, &nrChannels, 0);
    unsigned char* resultImage = new unsigned char[width*height*nrChannels];
    oidn::DeviceRef device = oidn::newDevice();
    device.commit();
    std::cout << nrChannels << std::endl;
    oidn::FilterRef filter = device.newFilter("RT");
    filter.setImage("color", image, oidn::Format::Float4, width, height);
    filter.setImage("output", resultImage, oidn::Format::Float4, width, height);
    filter.set("hdr", false);
    filter.set("srgb", true);
    filter.commit();
    filter.execute();

    const char* errorMessage;
    if (device.getError(errorMessage) != oidn::Error::None) {
        std::cout << "Error: " << errorMessage << std::endl;
    }
    else {
        stbi_write_png("img.png", width, height, nrChannels, resultImage, width * nrChannels);
    }
}

I'm getting an error saying that the image format is unsupported.

If I use jpg, and change Format::Float4 to Format::Float3 I get this error:

Exception thrown at 0x00007FFC5588E1F5 (OpenImageDenoise.dll) in oidntest.exe: 0xC0000005: Access violation reading location 0x0000021D9C42FA70.

Am I doing something wrong? This is the image I'm using: https://drive.google.com/open?id=1uSjsyWCRisXNFUJG6R8iL5AdVbM7_18u

$\endgroup$

2 Answers 2

0
$\begingroup$

As far as I remember, you need to input data in float array. Right now your input is unsigned char array. To quick check this, try loading any HDR image in float array & pass it on to the setImage functions, this seems to work.

In your case, you would need to read individual image channel data & cast it to float. If your image color is stored in [0-255] range, you would then need to bring it to [0-1] range (Not completely sure about this stage!) & then pass the data in float array to denoiser functions.

Hope this helps.

$\endgroup$
2
  • $\begingroup$ this worked but I had to change Float4 to Float3 and had to use a jpg instead of png. Float4 format still gives me an error saying that the image format is unsupported. $\endgroup$
    – Karthik
    Dec 15, 2019 at 17:10
  • $\begingroup$ I feel it's not supported as per official doc: openimagedenoise.github.io/documentation.html $\endgroup$
    – TheOrestes
    Dec 16, 2019 at 5:47
0
$\begingroup$

After some experimentation, I found a working code. Here we use a vector called float_data. This vector stores the colour data input as well as output. Here, pixel_data is a copy of the screen in RGBA 8-bits per channel.

vector<float> float_data(3 * px * py);

for (size_t i = 0; i < px; i++)
{
    for (size_t j = 0; j < py; j++)
    {
        size_t float_index = 3 * (j * px + i);
        size_t index = 4 * (j * px + i);

        float_data[float_index + 0] = static_cast<float>(pixel_data[index + 0]) / 255.0f;
        float_data[float_index + 1] = static_cast<float>(pixel_data[index + 1]) / 255.0f;
        float_data[float_index + 2] = static_cast<float>(pixel_data[index + 2]) / 255.0f;
    }
}


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

oidn::BufferRef colorBuf = dev.newBuffer(px * py * 3 * sizeof(float));
colorBuf.write(0, px* py * 3 * sizeof(float), &float_data[0]);

oidn::FilterRef filter = dev.newFilter("RT");

filter.setImage("color",  colorBuf, oidn::Format::Float3, px, py);
filter.setImage("output", colorBuf, oidn::Format::Float3, px, py);
filter.set("hdr", false);
filter.commit();
filter.execute();

// Check for errors
const char* errorMessage;
if (dev.getError(errorMessage) != oidn::Error::None)
    MessageBox(NULL, errorMessage, "Error", MB_OK);

colorBuf.read(0, px * py * 3 * sizeof(float), &float_data[0]);

The image can be then written to disk like:

vector <unsigned char> uc_output_data(4 * px * py, 0);

for (size_t i = 0; i < px; i++)
{
    for (size_t j = 0; j < py; j++)
    {
        size_t uc_index = 4 * (j * px + i);
        size_t data_index = 3 * (j * px + i);

        uc_output_data[uc_index + 0] = static_cast<unsigned char>(fabsf(float_data[data_index + 0]) * 255.0f);
        uc_output_data[uc_index + 1] = static_cast<unsigned char>(fabsf(float_data[data_index + 1]) * 255.0f);
        uc_output_data[uc_index + 2] = static_cast<unsigned char>(fabsf(float_data[data_index + 2]) * 255.0f);
        uc_output_data[uc_index + 3] = 255;
    }
}

int result = stbi_write_png(filename, px, py, 4, &uc_output_data[0], 0);

The result is an image -- denoised on the left, noisy on the right, for comparison purposes:

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.