G'MIC exercises

It was a fun exercise. Sorry, I kept on messing up my example. This one should be correct. Basically, it pairs up the layers with a choice of which odd layer to leave out; e.g.:

1,2,3,4,5,6 → [1,2],[3,4],[5,6]
1,2,3,4,5 → [1,2],[3,4],[5] or [1],[2,3],[4,5]
etc.

$1 → how many sample images to insert (edit: random; could be the same in a row)
$2 → which odd one to leave out; 1=first, 0=last

blend_test_afre: skip ${1=6},${2=1}
  repeat $1
    sp
  done
  if {$1%2==0} a="0--1" elif $2 a="1--1" else a="0--2" fi
  l[$a]
    repeat {if($!%2,$!/2-1,$!/2)}
      blend[$>,{$>+1}] average
    done
  endl

2 Likes

That’s a lot better than my attempt with my modo cli code. I did however, added a way to create blended and reversed blended while the alpha is based off top to below blending. I think that a combination of those techniques could lead to something that’s fully flexible with blending layers, but that’s going to take a while.

I tried seamcarve for the first time. This is a comparison with it and IM’s implementation. IM’s looks better to me on the left edge. Anything you could do @garagecoder?

gmic sp tiger seamcarve 75% o tiger_gmic.png

tiger_gmic

magick tiger.png -liquid-rescale 75x100%! tiger_im.png

tiger_im

Sorry probably not, it’s based on a more complex real time algorithm which sacrifices some quality for speed. David already added some clever interpolation as well. Having said that, there are some pending feature requests to look at which might help :slight_smile:

Edit: seamcarving will generally struggle with images having global “high energy”, i.e. no smooth areas.

I don’t know where to put this on github, so I’m going to leave this here and mentioned that I fixed Layer Cake. I know @Joan_Rake1 made it, but he isn’t here at all. The layer goes in the correct order when output layers are on. The preview also works as expected.

#@gui Layer Cake : fx_layer_cake, fx_layer_cake_preview(1)
#@gui : note = note("Splits image into annular or circular layers and rotates each layer. Based on <a href="https://forums.getpaint.net/topic/26566-layer-cake-plugin/">the Paint.NET plugin</a>.")
#@gui : Iterations = int(4,1,32)
#@gui : Angle at Centre = float(360,-1440,1440)
#@gui : Angle Times Iteration = bool(0)
#@gui : Size = float(75,0,200)
#@gui : Centre = point(50,50,0,1,255,255,255,175)
#@gui : Boundary = choice(3,"None","Nearest","Periodic","Mirror")
#@gui : Interpolation = choice(1,"None","Linear","Bicubic")
#@gui : Blur = float(0,0,200)
#@gui : sep = separator()
#@gui : Anti-Alias Amplitude = float(30,0,100)
#@gui : Edge Threshold (%) = float(0,0,100)
#@gui : Smoothness = float(3,0,10)
#@gui : Output Layers = choice("Off","Hollow","Filled")
#@gui : sep = separator(), Preview type = choice("Full","Forward horizontal","Forward vertical","Backward horizontal","Backward vertical","Duplicate top","Duplicate left","Duplicate bottom","Duplicate right","Duplicate horizontal","Duplicate vertical","Checkered","Checkered inverse"), Preview split = point(50,50,0,0,200,200,200,0,10,0)
fx_layer_cake :
repeat $! l[$>]
iter=$1
angle=$2
if $3 angle*=$iter fi
size=$4/2
to_rgba split_opacity to_rgb
repeat 2
part={1-$>}
l[$part]
repeat $iter
[0] rotate[-1] {$angle/$iter*($>+1)},$8,$7,$5%,$6%
100%,100%,1,1 ellipse. $5%,$6%,{$size/$iter*($iter-$>)}%,{$size/$iter*($iter-$>)}%,0,1,255
if {$13!=2} ellipse. $5%,$6%,{$size/$iter*($iter-1-$>)}%,{$size/$iter*($iter-1-$>)}%,0,1,1 fi
blur. {$9/$iter}
fx_smooth_antialias. ${10-12}
blend[-1,-2] multiply
done
if {!$13} blend[^0] add fi
if {$13!=2} 100%,100%,1,1 fc. 255,255,255 ellipse. $5%,$6%,{$size}%,{$size}%,0,1,0
blur. {$9/$iter}
fx_smooth_antialias. ${9-11}
blend[-1,0] multiply fi
if {!$13} blend add fi
if $part to_gray fi
endl
done
list={int($!/2)}
repeat {$list} a[$>,$list] c done
skip {$13==0}
if {$13} rv fi
endl
done
fx_layer_cake_preview:
if {!$13} gui_split_preview "fx_layer_cake $*",${-3--1} else fx_layer_cake ${1-12},0 fi

I followed this up with a joke but it is a real problem for me in Windows. The extreme banding occurs when I display the images and when I output to file.

Similar issue with apply_tiles. Using the example in the docs, I am not getting the nice interpolation that it should be getting.

From my output




From docs

image

I think this has to do with the numerical limits of the floating-point precision that are reached in your case.
If you don’t renormalize with n 0,1, I have stats like this (on Ubuntu, with latest gmic).

$ gmic sp tiger,barbara bug -126
[gmic]-0./ Start G'MIC interpreter.
[gmic]-1./ Input sample image 'tiger' (1 image 750x500x1x3).
[gmic]-2./ Input sample image 'barbara' (1 image 512x512x1x1).
[gmic]-2./bug/ Normalize images [0,1] in range [0,1].
[gmic]-2./bug/ Multiply images [0,1] by 1.17549e-38.
[gmic]-2./bug/ Fill images [0,1] with expression 'a = .17883277; b = .28466892; c = .559(...)i>1/12,a*log(12*i - b) + c,sqrt(3*i))'.
[gmic]-2./ Display images [0,1] = 'tiger, barbara'.
[0] = 'tiger':
  size = (750,500,1,3) [4394 Kio of floats].
  data = (0,0,0,0,0,0,0,0,0,0,0,0,(...),0,0,0,0,0,0,0,0,0,0,0,0).
  min = 0, max = 0, mean = 0, std = 0, coords_min = (0,0,0,0), coords_max = (0,0,0,0).
[1] = 'barbara':
  size = (512,512,1,1) [1024 Kio of floats].
  data = (0,0,0,0,0,0,0,0,0,0,0,0,(...),0,0,0,0,0,0,0,0,0,0,0,0).
  min = 0, max = 1.87789e-19, mean = 7.16359e-25, std = 3.66776e-22, coords_min = (0,0,0,0), coords_max = (58,312,0,0).

First image is already full of 0, while the second has values in 1e-19 and 7e-25.
I think this is too low to be handled correctly with float-valued images.

I’ve tested again on Windows, and your command results in both 0-valued images, when I use argument -126.
It’s even weird you get something different :slight_smile:

Beware, if you use bash with MSYS, there is a difference between:

$ gmic image.jpg +apply_tiles[0] "equalize 256",16,16,1,50%,50%

which gives indeed an image similar to what you show, and

$ gmic image.jpg +apply_tiles[0] \"equalize 256\",16,16,1,50%,50%

which is the correct way of invoking the example of use from apply_tiles using Bash !

That is odd. The values were different in version 2.4.1, which was also different from the version that I used to post my example originally. I wonder why it would be different for all three versions? The way G’MIC is built? Anyway, as I and you have said, the extreme values are at play. Values of v2.4.1:

[0] = 'tiger':
  size = (750,500,1,3) [4394 Kio of floats].
  data = (0,0,0,0,0,0,0,0,0,0,0,0,(...),0,0,0,0,0,0,0,0,0,0,0,0).
  min = 0, max = 1.87789e-019, mean = 5.98413e-020, std = 6.30015e-020, coords_min = (0,0,0,0), coords_max = (707,471,0,0).
[1] = 'barbara':
  size = (512,512,1,1) [1024 Kio of floats].
  data = (0,0,0,0,0,0,0,0,0,0,0,0,(...),0,0,0,0,0,0,0,0,0,0,0,0).
  min = 0, max = 1.87789e-019, mean = 6.32895e-020, std = 6.82475e-020, coords_min = (0,0,0,0), coords_max = (58,312,0,0).

Oh, I see. I did backslash once but it didn’t work. Looks like it works now. I wonder whether you should change the example to include the \, or maybe it isn’t necessary in another environment… It is a bit confusing because when I do a local custom command, like I said in a previous post, I need to double quote instead.


Last subject. I mentioned before that when I copy-paste someone else’s (e.g., @Reptorian’s) GUI-based filter it only works when I paste it into the user.gmic file. When I placed it into a linked gmic file using cli_start, it doesn’t load into the plugin. Is this a bug?

Clearly, the way the compiler optimizes math operations can be a big changer. I remember I’ve been able to switch to -Ofast recently instead of -O3 , which means -ffast-math is now enabled. I don’t remember exactly when I’ve been able to do that but maybe it happened between 2.4.1 and 2.5.0.

That’s entirely dependent on the console you are using to run gmic. Each console has its own substitution rules that must be taken into consideration to be sure gmic gets all the characters intended for it.
When the command line becomes a bit complex, with strings and spaces, it always best to put those commands in custom user commands defined in user.gmic .

No that’s not a bug. The plug-in has its own set of files to look at, and it has nothing to do with the command cli_start (which is used only by the cli tool, as its name suggests).
You should be able to add a custom file as a new source for GUI filters, by defining the command _gui_filter_sources in your user.gmic file, like this:

_gui_filter_sources : skip ${1=0}
  ({'/path/to/your/gmic/file'})

I’ve not tested this since a long time, so I’m not sure it will work, but you can tell us :slight_smile:

I placed my path as follows

cli_start:
  v - l[] m X:\_px\_in\gmic\test.gmic onfail endl v +

_gui_filter_sources: skip ${1=0}
  ({'X:\_px\_in\gmic\test.gmic'})

but it doesn’t work for me. BTW, what does $1 do?

I guess you have to ‘double’ the backslashes (or use regular slashes):

_gui_filter_sources: skip ${1=0}
  ({'X:\\_px\\_in\\gmic\\test.gmic'})

The argument $1 can be 0 or 1 depending on the fact the Internet checkbox if ticked or not.

We have gone through this before. Before I was aware of how to write cli_start properly, I had the slash problem and tried all of the suggest methods. If the following line works,

v - l[] m X:\_px\_in\gmic\test.gmic onfail endl v +

shouldn’t

({'X:\_px\_in\gmic\test.gmic'})

also work?

Question, if I already had filters used on the updatexxxx.gmic, would that override the existing filters? Now, doing this would mean I can avoid having to edit files manually on github, and just upload the file straight-away, right?

Edit: Actually, I don’t know if I am answering your question. I am talking about user.gmic and custom *.gmic files here, not update*.gmic per se.

Yes, which is why I do this. It is
1. To develop new filters and keep my custom ones private (because they aren’t useful to others).
2. Override functions to make them more suitable for my needs (but usually, I just rename them).
3. Most importantly, it allows me to organize the filters into various files.

It didn’t work with update.gmic, and I don’t believe that my reptorian.gmic file worked regardless, maybe my path is wrong.

cli_start :
_gui_filter_sources: skip ${1=0}
  ({'C:\\Users\\User\\AppData\\Roaming\\Reptorian.gmic'})

cli_start :
 v - l[] m C:\\Users\\User\\AppData\\Roaming\\Reptorian.gmic v +

_gui_filter_sources: skip ${1=0}
  ({'C:\\Users\\User\\AppData\\Roaming\\Reptorian.gmic'})

With double slashes.

I’m interested in this effect. It seem to me that it uses vectors and the vector copies the underlying colors and then delete the underlying layer. That’s my theory.


I’m having a pretty strange issue via latest g’mic version. If you copy the em or emboss_image cli command into code[local], $3 variable works just fine . Now if you look into the emboss-relief filter, $3 at 0 does the same as $3 at 1 via code[local]. I know the workaround to this issue, but my question is, why does this happen?

It is possible a deformation based in the morphology?
I think that this serious very good to caricature or stylize photographies

There are many strategies to go about seam carving, morphology being one of them. Seam carving itself has plenty of applications as well, beyond caricatures and style. Interesting topic. :slight_smile: