Exporting/importing photos in full 32-bit representation (to train a neural network for image denoising)

I’d assume you’d want to use the same profile in your output that you’re using as your working space.

1 Like

Thank you, that makes a lot more sense!
I set everything (raw: working profile, output color profile; tif/exr/pfm: input profile, working profile, output profile) to use the same “linear Rec2020 RGB” profile since that’s darktable’s default working profile.
I also simplified the example processing to nothing to minimize histogram inaccuracies.
It looks like I am able to get values beyond [0,1], however the histogram is still not quite the same and I don’t know what to make of it.
raw image with no processing whatsoever:


raw image with exposure setting:

tiff import with no processing whatsoever (looks about the same as the raw one. also no visible difference w/ openexr and pfm):

tiff import with exposure setting (no visible difference w/ openexr and pfm):

1 Like

You shouldn’t change your input profile.

I only change the input profile of the exported-reimported image to make sure it matches. It makes no difference in tiff, pfm doesn’t seem to embed a color profile so it defaults to sRGB, and EXR embeds something slightly different which I suspect is not right (though I don’t know).

I tried saving the histogram-compressed raw, and upon reimporting it in one of those 3 formats I get exactly the same histogram as in the last screenshot (where I compress the histogram after import), so it looks like there is no loss associated with histogram clipping which is great.

I think that means my next step is to reprocess the whole dataset with minimally processed images (white balance - demosaic - exposure matching - alignment) using the “linear Rec2020 RGB” output color profile. I guess that what the network gets as input and outputs should then be identical to the raw data that goes in and out of darktable’s denoise module (please correct me if I’m wrong).

The most straightforward way should then be to overwrite the dataset directly on Wikimedia Commons. (All the versions are kept and the download script I made can fetch the version from a specific date, ie when the paper was released to replicate the exact results shown).

I will post back once that’s done, it should be a while.

Actually I feel like this could be wrong, wouldn’t the output color profile apply a conversion to the pixel values?

The raw image’s “input profile” is “standard color matrix”, and I have to pick a different output color profile (ie linear Rec2020 RGB) which has to match when I reimport the exported image (or it’s stored with the image and used as default in containers such as tiff).

Reimporting with a different color profile or with the “standard color matrix” as input color profile yields different results. This seems to indicate that the pixel values have changed, but I would ideally get the pixel values exactly the way they transit internally (there is no reason to do any conversion since the few modules used operate in RGB space).

I guess outputting the exact pixel values that transit in memory is not something that’s currently implemented, or I’m overthinking it/wrong because there is no actual loss involved in outputting with a different color profile? (I’m not yet too familiar with how these work.)

I wrote this a while ago, after I’d sorted through the ins and outs of the profile chain.

Most of the rest of color management literature goes hard into the theory and minutia, I just wanted something that rounded up the basic mechanics.

2 Likes

This is probably something very easy, but I get syntax error when trying the following:

python3 denoise_image.py --cs 256 --ucs 192 --model_path "models/2019-02-18T20:10_run_nn.py_--time_limit_259200_--batch_size_94_--test_reserve_ursulines-red_stefantiek_ursulines-building_MuseeL-Bobo_CourtineDeVillersDebris_MuseeL-Bobo-C500D_--skip_sizecheck_--lr_3e-4" -i <in/3200.jpg> [-o out/3200.tiff]

bild

I don’t know why the syntax error shows there, but maybe it’s related to the brackets ? They just mean mandatory / optional argument. The command should then be:
python3 denoise_image.py --cs 256 --ucs 192 --model_path "models/2019-02-18T20:10_run_nn.py_--time_limit_259200_--batch_size_94_--test_reserve_ursulines-red_stefantiek_ursulines-building_MuseeL-Bobo_CourtineDeVillersDebris_MuseeL-Bobo-C500D_--skip_sizecheck_--lr_3e-4" -i in/3200.jpg -o out/3200.tiff
Let me know if that works, unfortunately I can’t test right now because of Build fails with torch 1.8.1 and cuda 11.3 · Issue #3695 · pytorch/vision · GitHub , and/or if you need this without CUDA (on CPU).

Sadly no difference. I also get syntax error when trying this
bild

Edit: I should run it outside Python environment, shouldn’t I?

bild

It seems you are running the python command inside of python. Try running the command from the bash prompt (right after $)

I had to specify the name of the model, model_257.pth
I did get some error messages, but it worked.

bild

5.9 seconds to clean the jpeg from 500D. Impressive result.

1 Like

Great :slight_smile: Glad you got it to work!

I updated the doc and I will test the bits that are supposed to find the right model soon.

I have a few changes in the pipeline; CPU denoising (painfully slow but sometimes needed), whole image denoising (if there is an insane amount of RAM then it can yield slightly better results than stitching crops together), and 16-bit loading using opencv (PIL only supports 8-bits) are done, I want to improve the training pipeline and I will test and push it all together.

Sounds great!
I tried the 500D model on my 6D raw file. Not suited for that so I will need to train it myself.

Were the images sharpened ? The current training pipeline was fed unsharpened images (because that amplifies noise) which are meant to be sharpened after denoising. That might affect the result. Otherwise it’s possible that it doesn’t generalize to very different sensors (I didn’t have access to a full-frame camera at the time).

If you end up making (a) test set(s) with your camera, could I add them to the training set on Natural Image Noise Dataset - Wikimedia Commons ?

No sharpened. The issue was colour space.

How many series of test sets will be enough? And 1 file for each ISO?

This is from my 7D. The software removed CA also.

bild
bild

2 Likes

I have no answer for how many test sets will have enough influence unfortunately.

My initial experiments were satisfying with a total of about 35 sets but you should need much less than that to fine-tune with the existing data. Maybe 5? (I’ve also recently added 3 full-frame images with a Z6 that haven’t been part of a training yet, they would probably be helpful too.)

1 file per ISO indeed. You don’t need every ISO for every set, maybe >= 5 different values. Different low-ISO values are important too so that the network learns that it should leave clean parts mostly intact.

Is this a noisy-denoised pair or different ISO settings?

Noisey-denoised pair. ISO 800.

  1. Noisy picture
  2. NR in darktable (the best I could)
  3. Neural network
    bild
    bild
    bild

9 seconds with RTX 2080 8GB at 85% activity and half memory. My second card, GTX 1060 3GB was not used.

3 Likes