On FOSS side, I think nind-denoise (created by Benoit Brummer) is the only practical AI denoise available that I tested. I’ve been using it personally and professionally, totally happy with its performance, ISO up to 10,000 can look clean as ISO200 (even with artifacts, reduction of false colors from noise is a huge plus). Search for dt-nind-denoise to see samples.
It works on RAW images that have not been denoised, and it’s slow (about 9 seconds on RTX3060, or 63 seconds on Ryzen 5 7640HS, for a 24MP image). Thus, it should not be part of darktable interactive darkroom, but applied only at export.
Injecting nind-denoise into darktable export process
In DT, an image’s history stack is saved to the XMP file. darktable-cli can process the image with a specified XMP. The idea is to copy the original XMP into two XMPs:
- 1st-stage has only RAW-related operations (demosaic, hotpixel, highlight reconstruction …)
- 2nd-stage has the remaining operations of the history stack
We apply nind-denoise in between the two stages.
The flow would be:
(darktable-cli) apply 1st-stage XMP and export to TIFF32
==> (nind-denoise) output to a denoised TIFF32
==> (darktable-cli) apply 2nd-stage XMP and export to JPG (optionally apply RL-deblur)
I’ve been working on a Python script to streamline the process. It’s still a WIP, tailored to my needs, but I think it’s stable enough. Here’s an attempt to document the tool, hopefully to get some feedback/testing on making the tool more accessible. I’ll keep this top post updated.
Installing nind-denoise
nind-denoise is the main component, so you’ll need to get that working first. Try to follow the instructions on the repo, basically:
-
install dependencies (using pip3, package manager, …)
-
clone and checkout my darktable-cli branch to run locally.
NOTE: check out the branch darktable-cli directly to avoid problem with models’ folder name having invalid char (for Windows)
git clone https://github.com/hqhoang/nind-denoise --branch darktable-cli -
download the available models ( I found this one to be the best).
If you modify the folder name of the model, note whether it hasunetorutnet, and specify--network UNetor--network UtNetlater when using the command. -
optional: install CUDA for faster denoise on nVidia GPUs (look up tutorials/guides for your distro/OS)
Once you get nind-denoise working, you can test it manually by feeding it a JPG exported from darktable (without any operation that affect the noise patterns such as profiled denoise, sharpen, lens correction, …).
Example command on mine, with DSC0123.jpg being the JPG exported from RAW in DT, nind-denoise will output to DSC0123_denoised.jpg (testing manually with JPG to avoid complication with TIFF).
/home/noname/python_envs/nind_denoise/bin/python3 /home/noname/tinker/git/nind-denoise/src/nind_denoise/denoise_image.py --network UtNet --model_path "/home/noname/tinker/git/nind-denoise/models/2021-06-14/generator_650.pt" --input "DSC0123.jpg" --output "DSC0123_denoised.jpg"
Streamlining the workflow
I wrote a Python script for the above workflow.
In the src/darktable folder of the checked out github repo:
- copy the file
dt_nind_denoise.example.iniintodt_nind_denoise.ini - update the
dt_nind_denoise.inifile according to your local paths (using the same paths that have been tested manually above). - run
dt_nind_denoise.pyon your RAW images. You can put those two files (together) anywhere, they don’t have to stay in that folder.
You might need to install a few required packages for the script (e.g. pip3 install exiv2 beautifulsoup4 lxml)
Example usage: dt_nind_denoise.py DSCF0123.RAF DSC0234.NEF
or, for all RAW files in a folder: dt_nind_denoise.py *
or, for only images rated 3- or 4-star: dt_nind_denoise.py -r34 *
or, use bash range: dt_nind_denoise.py DSC0{121..129}.*
(run dt_nind_denoise.py -h to list all parameters)
When run in debug mode (with -d flag), the script will print more details, and keep the intermediate TIFF32 files for inspection.
My workflow: edit RAW files normally in darktable, but don’t apply denoise (and no sharpening, since I use RL-deblur instead). Once I’m done editing, instead of exporting from darktable, I’d drop to the terminal, and run the dt_nind_denoise.py script on the whole album/folder.
IMPORTANT: the dt_nind_denoise.py script doesn’t handle multiple instances of a module (e.g. if you adjust exposure mutltiple times in between other operations). To avoid unpredictable behavior, always compress history in darktable before running the script.
GMIC RL-deblur
Richardson-Lucy deconvolution is a reconstruction process (unlike sharpening), really great to make the most of your lenses, bringing back details without halo. Its only downside (beside being slow): noise is also accentuated. But that’s why nind-denoise is its perfect companion.
The script optionally uses GMIC’s RL-deblur on the exported JPG (I don’t use sharpening in DT). If you don’t have gmic installed, just comment it out in the dt_nind_denoise.ini file.
Other notes
Demosaic makes huge difference to nind-denoise, as each algorithms alter the noise pattern slightly. I’m not sure which demosaic algo was used for the training data, but I found RCD is best for Bayer, and Markesteijn 3-pass is best for X-Trans. color smoothing and match greens should be disabled.
I’m not familiar with C++ and darktable’s code structure, only use Python once in a while, so this is just a really dirty hack, while waiting for a proper solution from the darktable team. All feedback and help are very welcomed and appreciated.