The Big Bad G'MIC Thread of Silly Questions

Forgot to mention smoothelate that is added to my folder one or two weeks ago.
It’s a combination of pixelating and smoothing :

(Original dull photographs by me with Lumix TZ5 @ almost 10 years ago, somewhere in Japan,
and examples are quite random but… nwm )


No smoothing here :


Heavy smoothing & sharpening:

Low smoothing, high sharpening:

Oh that one looked funny so i’ll add it here :slight_smile:

2 Likes

Hi, me again,
and I’m trying to draw a rotated square but the size changes in the process :
gmic 800,800,1,3,255 run 'repeat 50 +polygon[0] 4,{50+$>}%,{1+$>}%,{99-$>}%,{50+$>}%,{50-$>}%,{99-$>}%,{1+$>}%,{50-$>}%,{$>*0.01},0xFFFFFFFF,0,0,0 w. done d'
Am i missing some pi stuff in there, or some other maths, to draw each point along a circle’s circumference?

I can get fun stuff that way though:

Another question: I use erode or dilate on images to increase the outline’s width, but sometimes it’s a bit tricky since it depends on the background and outline colors. If there are dark and lighter lines it may erode some and dilate others. I had the case with black to grey outlines: black lines would just disappear over a red background. Is there anything to be done about this or is it just a pit trap? Should i draw each color on a “layer” instead?

Gimp simulation with dilate (blackthinned, white thickened):

image

1 Like

It depends on how generalized you would like your solution to be. While it is a good to start small, could you share a complex image that is more representative of what you plan on working on?

Hello @afre , which question are you replying to?
The rotation or the dilate/erode problem?

Anyway :

  • for the rotation I just want to be able to draw a shape in any angle without calling rotate which i fear would force me to create a new image and paste it in the background, each time. Sounds heavy.
  • For the dilate/erode stuff, I just want to change the outline thickness regardless of color value or luminosity ( or whatever is involved). I probably need to separate colors by value I guess. There is probably a threshold value that could make this work. ( I feel like I’m having a hard time explaining what I want to do lol…)

That’s exactly where the math evaluator comes handy!

foo :
  400,400 => canvas
  repeat 90 {
    angle:=4*$>  # specified in degrees
    coords:="
      R = rot($angle°);
      C = [ w#$canvas/2, h#$canvas/2 ];
      rot_pt(x,y) = ( C + R*([ x,y ] - C) );
      [ rot_pt(100,100), rot_pt(300,100), rot_pt(300,300), rot_pt(100,300) ]"
    polygon[canvas] 4,$coords,0.5,0xFFFFFFFF,255
    w[canvas] wait 30
  }

Beware, dilate and erode are two morphological operations that have a formal definition :

and

It’s maybe not exactly what you are looking for!

You can then add some cool variations, as this one:

foo :
  400,400 => canvas
  repeat 360 {
    angle:=$>  # specified in degrees in [0,359]
    coords:="
      R = 2.3*cos(pi/3+$angle*pi/360)*rot($angle°);
      C = [ w#$canvas/2, h#$canvas/2 ];
      rot_pt(x,y) = ( C + R*([ x,y ] - C) );
      [ rot_pt(100,100), rot_pt(300,100), rot_pt(300,300), rot_pt(100,300) ]"
    +f[canvas] 0 polygon. 4,$coords,1,0xFFFFFFFF,255
    blend[canvas,-1] xor,0.25
    w[canvas] wait 30
  }
  normalize_local , smooth 50,0,1 n 0,255

foo

3 Likes

On erode and dilate:

That is why I asked. Once it is clear, it would just be a matter of implementing. This is true:

Thinking out loud, if you are processing an image with only lines, you may want to consider thinning them first and then reintroducing them and their intersections that disappear after erosion or dilation through something called geodesic erosion or dilation, or something to that effect. At first, I thought of frequency separation such as split_details. That would work for busier images, but you would end up with noise and outlines of lines and shapes rather than the lines and shapes themselves.

Thanks, that’s quite nice indeed!
But i’m a wanderer, i have to explore this a bit more.
Found out i can fix the “tilted” look with even numbers here:

   R = 2*cos(pi/4+$angle*pi/360)*rot($angle°);

Which makes this tileable:

Adding points to the polygon makes it look weird but what i want is really just draw the shape once, but in a random or chosen angle. It’s just so i can switch rectangle to polygon in the previous code i posted (the bubbly chaos stuff). rectangle is cool but i can’t (can i?) use it to draw tilted rectangles/squares.
In your example the square still grows from tiny to oversized. What mod would make it keep it’s defined/original size? Like rotate would do, but without the added borders? I don’t want it to go outside the image, it would break the seamless tiling. (at least AFAIK).


Then if erode/dilate are out, maybe i could cheat by drawing the shape a few times (warning, brainless one-liner below, i hardly ever use vars in commandline mode, it’s just for testing):

gmic 800,800,1,3,255 run 'repeat 100 polygon[0] 4,{50+$>}%,{1+$>}%,{99-$>}%,{50+$>}%,{50-$>}%,{99-$>}%,{1+$>}%,{50-$>}%,1,0xFFFFFFFF,0,0,0  polygon[0] 4,{50.05+$>}%,{1.05+$>}%,{99.05-$>}%,{50.05+$>}%,{50.05-$>}%,{99.05-$>}%,{1.05+$>}%,{50.05-$>}%,1,0xFFFFFFFF,0,0,0 polygon[0] 4,{49.95+$>}%,{0.95+$>}%,{98.95-$>}%,{49.95+$>}%,{49.95-$>}%,{98.95-$>}%,{0.95+$>}%,{49.95-$>}%,1,0xFFFFFFFF,0,0,0 w. wait 25 done d'

It’s in % so it’s a bit trickier than adding/substracting one pixel to/from coords to get some thickness. As you can see, there are some gaps in between lines:
EDIT: wrong image :frowning:
BTW it seems some lines still appear thinner than others (bottom left, top right). Don’t know what causes this.

Or go crazy and simulate everything with thickline? After all, back when i was still drawing by hand (that’s so 1950 now :P) i was only using lines, not squares…

Anyway, thank you guys :slight_smile:

2 Likes

Hi, question-man here again. :person_raising_hand:

Would this be a good right way to add an alpha channel to an existing colored outline drawing ? I don’t want to lose information in the process. The ideal would be to get a binary image to append as an alpha channel.
EDIT: But then if i use black for the outline, these lines disappear in the process…

+f 0 # <<< add a black layer at the start of the script

# ...
# A bunch of drawing stuff here
# ...

+compose_channels. add to_gray.
# cut. {ia},{iM} << seen this in a tutorial by Gary, not sure if relevant here
cut. 0,1 n. 0,255
a[-2,-1] c rv # << append channel then reverse to put new layer on top

Result :

Thanks

  1. Create a four channel canvas image: blahx,blahy,1,4,0 so that all channels are zeroed out, including the alpha channel.
  2. Then draw with polygon (or whatever else of that ilk) using a four channel color argument with alpha set. To draw the problematical black color, feed polygon with color argument 0,0,0,255
  3. Canvas is now ready to be composed on top of whatever background image you may have in mind.

Hope this helps. BTW, love the color ambience of your work-in-progress. Keep on having fun…

1 Like

You just saved my day, i was getting some headache now lol.
I didn’t add an alpha layer at the start because for some reason drawing on that image would make some lines transparent instead of the background.
So in the end :

+to_a f. 0 # << changed this
ML=$1
MR:=100-$2
MT=$3
MB:=100-$4
m "rcol : u {[${17--1}][3*int(u(8)%8),3]},255" # << added ",255" to David's subcommand
if ${"is_pattern \"$12\""} pat=$12 else pat=0xFFFFFFFF badpat=1 fi

# ...
# A bunch of drawing stuff here:
repeat $5 { rectangle. {u($ML,$MR)}%,{u($MT,$MB)}%,{u($ML,$MR)}%,{u($MT,$MB)}%,1,$pat,${-rcol} } 
# ...
rv #  << still need to reverse in the end but that's ok

Result… looks like everyone’s here! Phew!:

Thanks :slight_smile:
EDIT : This also kinda solves my dilate/erode problem since dilate over alpha also thickens black lines: :sunglasses:

That looks like a math book cover. Still though, keep it up.

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