Attempt for a x2 image upscaler, using CNN

The other command line style yields the same artifacts:

gmic IMG_20251017_132427.edited.v2.jpg -scale2x_cnn 1.25 -o IMG_20251017_132427.edited.v4.jpg

With the new 3.6.3 version (not yet in the stable repos), the output is clean again.

1 Like

I am trying to upscale some very bad old photos, some oversharpened and some unsharp.

I have written a bash-script using gmic to create different upscaling automatically, but it looks like I can do what I want and there is no big difference depending on the options.

Maybe this is because of the quality of these photos.

I hope you can suggest options which I should try.

I don’t expect miracles, but I think it could be made better with AI.

After upscaling I would like to use darktable with light editing. I think editing with darktable first is not so good. The result should be exactly 3840x2160. So at the end there is a little bit downsizing needed with ImageMagick probably.

Here are example images, original and upscaled:

LAGOS 5MP with broken distance and therefore very unsharp
https://drive.google.com/drive/folders/1sYgptFeKkcTgPvxwGjwLfGHiLIpXkDXW?usp=sharing

Tenerife 4MP, oversharped by the camera
https://drive.google.com/drive/folders/1OxaV43m9dkh4uELY8GvjidETvavC8adu?usp=sharing

The folders contain directories containing “upscale” where you can see what I tried.

I use gmic: GREYC’s Magic for Image Computing: Command-Line Interface
Version 3.7.0 (pre-release #26012712)
with Ubuntu 24.04

The filenames give you an idea what I tried. The upscale-dir contains a copy of the original file too for better comparison, the filename doesn’t contain upscaling-options then.

lagos/upscale-lagos$ ls -1
lagos1_cnn_1.7-0.jpg
lagos1_cnn_1.7-0+richardsonlucy_1.5-9-1-1.jpg
lagos1_cnn_2.1-0.jpg
lagos1.jpg
lagos1_patch2x_0-0+richardsonlucy_1.3-4-1-1.jpg
lagos1_patch2x_0-0+richardsonlucy_1.4-8-1-1.jpg
lagos2_cnn_1.7-0.jpg
lagos2_cnn_1.7-0+richardsonlucy_1.5-9-1-1.jpg
lagos2_cnn_2.1-0.jpg
lagos2.jpg
lagos2_patch2x_0-0+richardsonlucy_1.3-4-1-1.jpg
lagos2_patch2x_0-0+richardsonlucy_1.4-8-1-1.jpg

upscale-tenerife$ ls -1
tenerife1_cnn_1.25-0.jpg
tenerife1_cnn_1.7-0.jpg
tenerife1_cnn_1.7-0+richardsonlucy_1.2-2-1-1.jpg
tenerife1.jpg
tenerife1_patch2x_0-0.jpg
tenerife1_patch2x_2-0.jpg
tenerife1_patch2x_2-0+richardsonlucy_1.2-2-1-1.jpg
tenerife1_patch2x_2-0+richardsonlucy_1.3-3-1-1.jpg
tenerife2_cnn_1.25-0.jpg
tenerife2_cnn_1.7-0.jpg
tenerife2_cnn_1.7-0+richardsonlucy_1.2-2-1-1.jpg
tenerife2.jpg
tenerife2_patch2x_0-0.jpg
tenerife2_patch2x_2-0.jpg
tenerife2_patch2x_2-0+richardsonlucy_1.2-2-1-1.jpg
tenerife2_patch2x_2-0+richardsonlucy_1.3-3-1-1.jpg
tenerife3_cnn_1.25-0.jpg
tenerife3_cnn_1.7-0.jpg
tenerife3_cnn_1.7-0+richardsonlucy_1.2-2-1-1.jpg
tenerife3.jpg
tenerife3_patch2x_0-0.jpg
tenerife3_patch2x_2-0.jpg
tenerife3_patch2x_2-0+richardsonlucy_1.2-2-1-1.jpg
tenerife3_patch2x_2-0+richardsonlucy_1.3-3-1-1.jpg

I append my bash-script as text-file, so you can see what I am doing.
It is very simple, you define an album-directory and define options from 1-9, commented options (#) are not computed. Depending on the album, options can be changed easily in the text.

upscale-script.sh.txt (13.3 KB)

I see you are using fx_ versions of the commands, which are usually meant to be used by the GUI (if i’m not mistaken).
@David_Tschumperle has issued a warning about this :

Them being GUI filters means you will (sometimes) have to use some extra parameters which may be relevant in the GUI but may not be useful in your script.
If you wish, you can hunt for the CLI versions of the commands here ,or here if it’s a community command.
I see at least 4 CLI commands:
scale2x scale2x_cnn scale3x scale_dcci2x
BUT in the case of fx_scale2x_cnn there is the option to update the neural network that doesn’t exist in the CLI version, so the fx_ version might be useful.
Maybe it could be added in the CLI version too?

Anyway, sorry if this doesn’t help you solving your problem in any way!

1 Like

Thanks, I have no idea, what to use. I started gimp and copied the command to the clipboard.

option7="fx_scale2x_cnn 1.7,0"

So maybe someone can write the command here and I will add it to my script. I am with 9 options to compare, it is no problem to create more.

I downloaded https://gmic.eu/get_file.php?file=prerelease/gmic_ubuntu24-04_noble_amd64.deb I hope this is the correct one for cli.

Yes, gmic is the CLI version and gmic_qt the GUI version ( like the Gimp plugin version).

What i meant is that, for example, fx_scale2x_cnn is meant to be called by the GUI, and it then calls the CLI command scale2x_cnn with your 1st parameter.

fx_scale2x_cnn :
  scale2x_cnn $1

The second param is only meant for the fx_scale2x_cnn_preview command, to update the .gmz from the GUI. So in the end, you’re calling a command that just calls another one, sending one extra param that isn’t used.

Here’s the full code for fx_scale2x_cnn:

#@gui Upscale [CNN2x] : fx_scale2x_cnn, fx_scale2x_cnn_preview(0)
#@gui : Description = note{"<span color="#EE5500"><b>Description:</b></span> \
# Doubles image size using a Convolutional Neural Network.
#@gui : "}, sep = separator()
#@gui : Sharpness = float(1.25,0,5)
#@gui : sep = separator()
#@gui : Update Neural Network = button()
#@gui : sep = separator()
#@gui : note = note{"<small>
#@gui : <b><span color="#EE5500">Note:</span></b> This filter uses a convolutional neural network (CNN)
#@gui : to upscale images. This filter does not take advantage of GPU computing, so expect it to be quite slow
#@gui : if you don't have many CPU cores available.
#@gui : </small>"}
#@gui : sep = separator()
#@gui : note = note("<small>Author: <i>David Tschumperlé</i>.      Latest Update: <i>2025/10/13</i>.</small>")
fx_scale2x_cnn :
  scale2x_cnn $1

fx_scale2x_cnn_preview :
  if $2 l[] {
    delete ${-path_cache}gmic_scale2x_cnn.gmz
    input_cached gmic_scale2x_cnn.gmz,2 rm
  } fi
  rs 128,128,0
  foreach {
    gui_split_preview "scale2x_cnn $1",9,50,50
  }

You could even actually use :
gui_split_preview "scale2x_cnn 1.7",9,50,50
…and it would work, but the extra params 9,50,50 are just meant for gmic_qt’s preview window, you don’t need them for a script.
In the end, the real command is just: scale2x_cnn 1.7

Using the copy command in the GUI is useful though, to see the command used by gmic_qt and then look for the full code on github. I wish it would just give us the CLI command though (and sometimes it’s the same).

Thanks a lot. I am unable to understand what is important at the end.

Unofrutanelty it was not so easy with richardsonlucy and upscale_patch2x from @garagecoder Removing “fx_” worked, but I got errors when I used options, which I did not get with fx_

On the other hand I see no difference with CNN, when I remove fx_ See files at Google Drive.

I changed the options in my script very agressive. At the end there is a big visibale change only with richardsonlucy

THe question is, if it makes sense to increase the sharping a lot more with cnn or is a combination with richardsonlucy better?

upscale-lagos$ ls -1

lagos1_fx_gcd_upscale_patch2x_0-0+fx_unsharp_richardsonlucy_3-15-1-1.jpg
lagos1_fx_gcd_upscale_patch2x_0-0+fx_unsharp_richardsonlucy_4-20-1-1.jpg
lagos1_fx_gcd_upscale_patch2x_0-0.jpg
lagos1_fx_gcd_upscale_patch2x_0-1.jpg
lagos1_fx_scale2x_cnn_5.3-0+fx_unsharp_richardsonlucy_4-20-1-1.jpg
lagos1_fx_scale2x_cnn_5.3-0.jpg
lagos1_gcd_upscale_patch2x.jpg
lagos1.jpg
lagos1_scale2x_cnn_3.1-0.jpg
lagos1_scale2x_cnn_5.3-0.jpg
lagos2_fx_gcd_upscale_patch2x_0-0+fx_unsharp_richardsonlucy_3-15-1-1.jpg
lagos2_fx_gcd_upscale_patch2x_0-0+fx_unsharp_richardsonlucy_4-20-1-1.jpg
lagos2_fx_gcd_upscale_patch2x_0-0.jpg
lagos2_fx_gcd_upscale_patch2x_0-1.jpg
lagos2_fx_scale2x_cnn_5.3-0+fx_unsharp_richardsonlucy_4-20-1-1.jpg
lagos2_fx_scale2x_cnn_5.3-0.jpg
lagos2_gcd_upscale_patch2x.jpg
lagos2.jpg
lagos2_scale2x_cnn_3.1-0.jpg
lagos2_scale2x_cnn_5.3-0.jpg

and

upscale-tenerife$ ls -1

tenerife1_fx_gcd_upscale_patch2x_0-0+fx_unsharp_richardsonlucy_1.2-2-1-1.jpg
tenerife1_fx_gcd_upscale_patch2x_0-0+fx_unsharp_richardsonlucy_1.2-5-1-1.jpg
tenerife1_fx_gcd_upscale_patch2x_0-0.jpg
tenerife1_fx_gcd_upscale_patch2x_0-1.jpg
tenerife1_fx_scale2x_cnn_3-0.jpg
tenerife1_fx_scale2x_cnn_5.3-0+fx_unsharp_richardsonlucy_1.2-2-1-1.jpg
tenerife1_gcd_upscale_patch2x.jpg
tenerife1.jpg
tenerife1_scale2x_cnn_2-0.jpg
tenerife1_scale2x_cnn_3-0.jpg
tenerife2_fx_gcd_upscale_patch2x_0-0+fx_unsharp_richardsonlucy_1.2-2-1-1.jpg
tenerife2_fx_gcd_upscale_patch2x_0-0+fx_unsharp_richardsonlucy_1.2-5-1-1.jpg
tenerife2_fx_gcd_upscale_patch2x_0-0.jpg
tenerife2_fx_gcd_upscale_patch2x_0-1.jpg
tenerife2_fx_scale2x_cnn_3-0.jpg
tenerife2_fx_scale2x_cnn_5.3-0+fx_unsharp_richardsonlucy_1.2-2-1-1.jpg
tenerife2_gcd_upscale_patch2x.jpg
tenerife2.jpg
tenerife2_scale2x_cnn_2-0.jpg
tenerife2_scale2x_cnn_3-0.jpg
tenerife3_fx_gcd_upscale_patch2x_0-0+fx_unsharp_richardsonlucy_1.2-2-1-1.jpg
tenerife3_fx_gcd_upscale_patch2x_0-0+fx_unsharp_richardsonlucy_1.2-5-1-1.jpg
tenerife3_fx_gcd_upscale_patch2x_0-0.jpg
tenerife3_fx_gcd_upscale_patch2x_0-1.jpg
tenerife3_fx_scale2x_cnn_3-0.jpg
tenerife3_fx_scale2x_cnn_5.3-0+fx_unsharp_richardsonlucy_1.2-2-1-1.jpg
tenerife3_gcd_upscale_patch2x.jpg
tenerife3.jpg
tenerife3_scale2x_cnn_2-0.jpg
tenerife3_scale2x_cnn_3-0.jpg

You can see the files at Google Drive too. Again, the options are very agressive to see a difference (or not).

I append the new script with the changed options, but I think you can guess from the filenames what I did.

Goal is, too define different options, so there are different results of 1 image and the best is chosen.

upscale-script_v2.sh.txt (12.5 KB)

That’s because removing “fx_” doesn’t necessarily give you the called command, the name could be totally different. fx_unsharp_richardsonlucy actually calls deblur_richardsonlucy with all your parameters ($*), and then applies a cut or a normalization, depending what you set as param 4 (0 or 1):

fx_unsharp_richardsonlucy :
  deblur_richardsonlucy $*
  if $4 c 0,255 else n 0,255 fi

This one is a bit more tricky since it uses a menu and calls different commands based on what you choose (and multiple times too). The called commands gcd_upscale_patch2x or gcd_upscale_tile2x take no parameters. If you select patch4x or tile4x they are just called twice.

I tried running Upscayl on your images and i can get nice results as well as bad ones. Lagos2 .jpg is a bit of a nightmare even though it cleans the noise in the sky quite a bit; i get a weird sharpened patch on the rocks and a blurred one next to it.

I think i would just use selections/masks to denoise the sky and see and sharpen the rocks, but you can only trust your own eyes on this.

1 Like

Thanks a lot. You are very helpful!

I agree, I think it is the worst. Lagos1 is average bad. These examples are not important, important are the photos with persons, which I cannot publish. I am searching for a general solution to upscale a lot photos.

Do you think there is AI for denoising? At the moment I don’t care a lot of denoising. The 1st step is acceptable sharperning. After different sharpening I am chosing manually the best.

I know this is a big challenge and the goal is not to get a perfect picture, getting it better than the original is my challenge.

I want to use my script with different options and then choose the best and if the result is bad, it is bad. For now all look similar and not better.

If you have a suggestions for a terminal-command let me know please.

Can I use Upscayl with a terminal-command somehow? I have to do hundreds of pictures and I think it will take forever. 1 upscale für 1 photo takes 5-7min. So variations will take 1/2hr for 1 photo. I see no chance to do this manually. I have to accept limitations.

Do you think cnn alone is able to sharpen the lagos photos?

Would you recommend to use fx_unsharp_richardsonlucy too? If so, after or before upscaling with cnn. As already written, until now, I don’t see sharpening with cnn, but of course, the lagos photos are extreme bad.

I think a command for the tenefife-photos is easier.

Surprise, there is a bug with green artifacts and cli/deblur_richardsonlucy, while fx_unsharp_richardsonlucy works. For commands see the attached changed script.

New versions:
lagos1_fx_gcd_upscale_patch2x_0-0+fx_unsharp_richardsonlucy_4-10-1-1.jpg
lagos1_fx_scale2x_cnn_10.3-0+fx_unsharp_richardsonlucy_4-20-1-1.jpg
lagos1_fx_scale2x_cnn_20.3-0.jpg
lagos1_gcd_upscale_patch2x+deblur_richardsonlucy_4-20-1-1.jpg
lagos1_gcd_upscale_patch2x.jpg
lagos1_gcd_upscale_tile2x.jpg
lagos1.jpg
lagos1_scale2x_cnn_10.3-0+deblur_richardsonlucy_4-20-1-1.jpg
lagos1_scale2x_cnn_10.3-0.jpg
lagos1_scale2x_cnn_5.1-0.jpg
lagos2_fx_gcd_upscale_patch2x_0-0+fx_unsharp_richardsonlucy_4-10-1-1.jpg
lagos2_fx_scale2x_cnn_10.3-0+fx_unsharp_richardsonlucy_4-20-1-1.jpg
lagos2_fx_scale2x_cnn_20.3-0.jpg
lagos2_gcd_upscale_patch2x+deblur_richardsonlucy_4-20-1-1.jpg
lagos2_gcd_upscale_patch2x.jpg
lagos2_gcd_upscale_tile2x.jpg
lagos2.jpg
lagos2_scale2x_cnn_10.3-0+deblur_richardsonlucy_4-20-1-1.jpg
lagos2_scale2x_cnn_10.3-0.jpg
lagos2_scale2x_cnn_5.1-0.jpg

These have artifacts:
lagos1_gcd_upscale_patch2x+deblur_richardsonlucy_4-20-1-1.jpg
lagos1_scale2x_cnn_10.3-0+deblur_richardsonlucy_4-20-1-1.jpg
lagos2_gcd_upscale_patch2x+deblur_richardsonlucy_4-20-1-1.jpg
lagos2_scale2x_cnn_10.3-0+deblur_richardsonlucy_4-20-1-1.jpg

So it seems it doesn’t depend on the upscaler and is probably offtopic here.

Please let me know, if there is a richardsonlucy thread, or if I should create a new one? Where?

upscale-script_v3.sh.txt (12.5 KB)

@linuxuser Yes, keep this thread on-topic. I suggest you create a separate thread for learning how to use G’MIC and related filter and commands. No need for it to be specifically about the richardson-lucy command. Call it something like “G’MIC fun with linuxuser”.

PS. As for processing, follow snibgo’s implicit advice and deal with the JPEG/camera-baked-in artifacts first before doing anything else. Otherwise, you are making the base image worse by enlarging and sharpening it further.

Quick answer : you need to add normalization n 0,255 or cutting c 0,255 after the deblur command. Tested it. It is what the fx_ version does anyway.