The Big Bad G'MIC Thread of Silly Questions

I can’t tell, i’ve never seen one :open_mouth:

BTW, is there any case where dilate 1 does something?

i had to +1 so that it always do something for my case:
if $11 dilate. {$11+1} fi

I don’t know, let’s make a test:

foo_test_dilate:
+dilate 1 
+neq 
echo[0] Does\ dilate\ 1\ do\ something\?\ ${arg\ iM+1,No,Yes}

Output:


C:\Windows\System32>gmic (0,1,0;0,1,1;1,1,1) foo_test_dilate
[gmic]./ Start G'MIC interpreter (v.3.3.4).
[gmic]./ Input image at position 0, with values (0,1,0;0,1,1;1,1,1) (1 image 3x3x1x1).
[gmic]./ Does dilate 1 do something? No
[gmic]./ Display images [0,1,2] = '(0,1,0;0,1,1;1,1,1), (0,1,0;0,1,1;1,1,1)_c1, (0,1,0;0,1,1;1,1,1)_c1'.
[0] = '(0,1,0;0,1,1;1,1,1)':
  size = (3,3,1,1) [36 b of float32].
  data = (0,1,0;0,1,1;1,1,1).
  min = 0, max = 1, mean = 0.666667, std = 0.5, coords_min = (0,0,0,0), coords_max = (1,0,0,0).
[1] = '(0,1,0;0,1,1;1,1,1)_c1':
  size = (3,3,1,1) [36 b of float32].
  data = (0,1,0;0,1,1;1,1,1).
  min = 0, max = 1, mean = 0.666667, std = 0.5, coords_min = (0,0,0,0), coords_max = (1,0,0,0).
[2] = '(0,1,0;0,1,1;1,1,1)_c1':
  size = (3,3,1,1) [36 b of float32].
  data = (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).
[gmic]./ End G'MIC interpreter.
1 Like

No, the dilate operator replaces each pixel by the max value in a neighborhood of size N\times N centered on this pixel. If N==1, this max is the same as the current pixel value.

2 Likes

Just uploaded that thing in git:

Had to change the way it works since dilate would make some ugly stitches where lines of a different color would cross. So i decided to draw shapes and lines with the same color on separated layers. It’s less chaotic but i guess that’s ok.
I’m still not sure if it’ll be useful to someone, but who knows lol.

2 Likes

Indeed, with dilate, the max in a neighborhood is computed independently for each channel, meaning, which means the locations of the max can be at different places for different channels, resulting in color mixing in some way.

If you have a predefined colormap, it can be useful to work only with a scalar image all the way long, where values are just indices in the colormap, then at the end you use map to map the desired palette.
Doing that will ensure that the dilate operation won’t mix colors. It will just locally favor the highest index but that’s OK.

Nice filter, BTW!

Seconded.
Been here for a little over a year now. Pretty good progress for a ‘math amputee’.

Yes, with so many lines it was rather messy, almost looking like i used outline patterns when i didn’t. And TBH, i actually considered using palette mapping over a grayscale image at the beginning, but then went the “random” way again. This particular filter didn’t really need it. Next one will probably need it, but may not need dilate. Or maybe it will need it, since it can give a nice calligraphic look to splines and circles when using different x,y size values. Well, i’ll see.

(interlude: i wonder if it still has the parallax effect with the layers…)
(EDIT: it seems it does, but the use random of random dilate values won’t please epilectics… one more thing i didn’t think about)

BTW, is there any reason why spline can’t be drawn with a pattern like line or polygon?

Thanks! shift saved me a lot of time, at the start i was already thinking about how i should split the image in 4 parts, and append everything together in another way, etc… shift made things so much easier to make the seamless effect, even with so much chaos going on. You and @grosgood were a great help too, as usual :slight_smile:

Thanks for the help, too! That alpha trick was getting on my nerve… You can’t even imagine how long i struggle with some parts of my scripts (not just the maths) before asking a question here lol. I just don’t know all the g’mic commands. Having a bad memory doesn’t help either since i forget parameters or commands. Well, even if i know the commands most of the time i don’t see which can be combined effectively, so it’s a lot of trial and error.
Still, i don’t think there’s a lot of maths in my scripts. The only “advanced” stuff i did on my own was converting this in g’mic language to calculate color distance for Sick Painter. I still don’t know how i managed to do it but it worked, even though David gave me a shorter version (as usual xD). I still have to fix the alpha in this thing btw.

Anyway, next “filter” will probably take me a thousands years to complete, even if most of it should already be in SCP, which was a training, in a way.

whatis may be of some help. Let’s say you half-remember some G’MIC command that has “sharp” in it:

gosgood@lydia ~ $ gmic whatis sharp
[gmic]./ Start G'MIC interpreter (v.3.3.4).
afre_sharpenfft
blend_sharpness
gcd_reverse_unsharp
hessian_sharpen
rep_tr_pixel_sharpener
sharpen
sharpen_alpha
unsharp
unsharp_octave
[gmic]./ End G'MIC interpreter.
gosgood@lydia ~ $

It finds all the commands (with written #@cli headers) that have sharp in their names and lists them. Perhaps an item in that listing jogs your memory enough to invoke gmic help on it.

whatis is not available in a just-installed standard distribution, but it is very easy to add. In fact I use it to introduce G’MIC neophytes to the fine art of writing their own custom commands. It is just two lines. See: I want to run the — you know! — the — the — whatchamacallit command. The apply something command. You know. That command. in the introduction to tutorials.

1 Like

Thanks for the tip! I’m used to use autocompletion to find commands starting with “[whatever]” but this is so much better. I’m tempted to put it in my prawnsushi.gmic file instead of the local .gmic. Or you should put it in yours!
Or i’ll just try to remember only one command : parse_cli print,[whatchamacallit - that command]. Actually print is not needed since it’s the default, so it’s just parse_cli ,[whatwasitagain].

And i’ll try not to take long g’mic breaks like i just did haha.

I may be asking for the impossible, but is there any way to make
r=10 R:=w/$r X,Y:=-$R work when written like this :

r,R,X,Y:=10,w/$r,-$R,-$R

Obviously the latter doesn’t work since $r is not defined, and then $R fails, and so on.

If you want a one liner:

r,R,X,Y:=r=10;[r,vector3(w/r)*[1,-1,-1]]

Other solutions:

r=10
R,X,Y:=vector3(w/$r)*[1,-1,-1]
r,R,X,Y={"
 r=10;
 R=w#-1/r;
 [r,w#-1/r,-R,-R];
 "}

You can also break them into lines. Like this:

r=10 
R:=w/$r
X,Y=-$R

Haha, that looks even more confusing :sweat_smile:

Yes, i do this a lot for more readability, then i rewrite what i can to save vertical space.

I understand your examples but… still hard to read. Maybe i’ll switch to this style when the script is finished?

Here is something else that i’m trying to figure out. The script below insists on creating a new layer in Gimp :sweat_smile:
I wonder what causes this?

m "circpat : 
  r=10 R:=w/$r X,Y:=-$R 
  repeat {(h/$R)+2} { 
    repeat {(w/$R)+2} { 
      circle $X,$Y,$R,1,$7,0,0,0,255  
      X+=$R 
    }  
  X=-$R Y+=$R  
  }"
${-circpat}
um *


Hi, who are you? Where are you from?

Made a mistake on the one liner solution. Remove the $ from $r.

Anyway, glancing from the code, I think it’s a G’MIC plugin configuration problem.

Thanks, noted.

I also made a mistake in my code. Changed *2 to +2

EDIT : actually i looks like this now:


m "circpat : 
W,H:=w,h r:=$_Size+1 R:=w/$r X,Y:=-$R 
expand_xy. 1 
repeat {(h/$R)+2} { 
  repeat {(w/$R)+2} { 
    circle {$X},{$Y},$R,1,$7,0,0,0,255 X+=$R 
  } 
  X=-$R Y+=$R 
} 
r. $W,$H,100%,100%,1"

Had to expand then resize the canvas otherwise the last circles would be out of bounds by 1 px, which breaks the seamless look.
Is there a trick to know about?

David, does um * do anything? Could I use this to uncommand all internal commands?

From gmic h um:


    Set argument to '*' for discarding all existing custom commands.
    (equivalent to shortcut command 'um').

Not sure if just um would do the job, that last sentence seem to imply this.

I tested this:

$ m foo:5 um * sample cat rep_fragment_blur 5

And it caused a error. I think it has application for GUI filters and interactive filters, but for most CLI filters, that can trigger a error.

Workaround is to collect all of your potential internal commands and append that next to um. Use $0_circpat instead.

If you put in $ debug um *, you get this:

<gmic>./ Item[2]: 'debug', selection [].
<gmic>./ Item[3]: 'um', selection [].
<gmic>./ Command 'um': arguments = '*'.
[gmic]./ Discard definitions of all custom commands (4818 commands).
<gmic>./ Exit scope './'.

But um seem to work here:

gmic run 'm foo:5 e um *  sample cat ${-foo}'
[gmic]./ Start G'MIC interpreter (v.3.3.4).
[gmic]./run/__run/ Import custom commands from expression 'foo:5' (1 new, total: 4733).
um
[gmic]./run/__run/ Multiply image [].
[gmic]./run/__run/ Input sample image 'cat' (1 image 600x550x1x3).
[gmic]./run/__run/*substitute/ *** Error *** Item substitution '${"-foo"}': Expression incorrectly changes the number of images (from 1 to 2).

What does $0_circpat mean?

um * seem to remove all commands then?

Hmm, it appears under run, it multiplies rather than removing all commands.

$0 means the name of your command.

foo: echo $0 would print out foo. If you do m $0_circpat inside foo, the name of the custom internal command is equal to foo_circpat. This helps avoid potential conflicts with existing command or even future commands.

1 Like

Thanks for the tip!

It seems i keep running into problems today.

Some circles don’t “connect”:

Looks like this is the effect of resize when the circle radius is w/$r where $r is an odd number. Should i start checking about even/odd numbers and always make it “even”?