Tips and curiosities - GreycLab/gmic-community GitHub Wiki
Preface
This page will hopefully become a collection of useful tips for beginner to intermediate level G'MIC script writers. Many have been kindly submitted by people learning how to create filters for the Gimp plugin. G'MIC was never intended to be easy to learn, so figuring out what something means or how to perform a particular task is often tricky - at least if you don't happen to be an image processing scientist!
Now, on to the tips...
- About the reference manual images
This one is not really a tip but an important warning. Keep in mind that all images on the Handbook are normalized to the range 0->255 before being displayed, so do not rely on getting the same results when trying to apply the code examples unless you at the end of your trial code enter the additional command -normalize 0,255 As a rough explanation: normalize in this case means the lowest values are forced to be 0 and the highest 255, so the values in between are either stretched or compressed to fit as necessary.
- How to try out G'MIC commands in the Gimp plugin
You can experiment with commands following these steps:
- Open gimp
- Open an image (no matter, even new one empty)
- Go to filters
- Select gmic
- When gmic opens select "various"
- Then select "custom code (local)"
- You may remove whatever you find in there
- Then put your command(s)
- Select "update" to see result in preview window or
- Select "apply" / "OK" to have it executed
- Creating an image from scratch
How do I add a new blank image filled with the color I want? The short answer is like this:
800,600,1,3 # Add a new image 800x600 with 3 channels (i.e. for RGB)
-fc[-1] 255,0,0 # fill it with red
# -or-
100%,100%,1,3 # Add a new image the same size as the last on the image list, 3 channels
-fc[-1] 0,255,0 # fill it with green
But don't forget: An "image" can represent anything you want, it could be HSV/YcBcR/CMYK etc. or might not contain an image at all! So it's wrong to think of a G'MIC image as always being red green blue
- Creating an image filled with values
How do I get a non-blank new RGB image with a single command?
- I want white: enter 100,100,1,3,255
- I want some nuance of grey: enter 100,100,1,3,128 or any other number between 1 and 254
- I'm curious and I enter: 100,100,1,3,128,64,32: wow!
I get a fantastic chess-board with any single pixel colored in triplets like this: 1°pixel (and 4°...and 7°...) colored with Red128+Green64+Blu32 2°pixel (and 5°...and 8°...) colored with Red64+Green32+Blu128 3°pixel (and 6°...and 9°...) colored with Red32+Green128+Blu64
Any use of this curiosity? Well, if you need chess-boards tri-colored you can create one with the initial numbers of how many squares you like (BUT ATTENTION! NONE OF THE TWO NUMBERS REPRESENTING WIDTH AND HEIGHT HAS TO BE A MULTIPLE OF 3 !!!) then enter the command -resize to get the image size you want.
What about an initial value multiple of 3? Well, try: you will get a b/w image with the three numbers (128,64,32) used as nuances of grey. If the number representing the width is multiple of 3, the image results "striped" because - as in the previous example - the image is considered like a uni-dimensional series of pixels, so that after the last one of the first row the first one of the second row continues the series... If the width is not multiple of 3, you get a chess-board in 3 different grey nuances.
Any use of this second curiosity? If you need a striped image, do as above, but in this case width must be a multiple of 3.
- Blending images
In image manipulation the capability to blend layers is very much common, so this tip is related to the command -blend. Using G'MIC console under GIMP (as indicated on a previous post) do the following:
- Open a new image in GIMP (no matter, make it transparent, we use it only for the dimensions)
- Start G'MIC -> various -> custom code (local)
- Enter the following:
100%,100%,1,3 # Create a new image(layer) same dimension, black by default
-fill_color[1] 255,0,0 # Fill the new layer with red
100%,100%,1,3 # Create a new image(layer) same dimension, black by default
-fill_color[2] 0,255,0 # Fill the new layer with green
--blend[1,2] add,0.50 # This will create a new layer with both colours blended
# Note: using positive numbers for referencing images,
# [0] is the original, [1]...[n] are the additional ones created by yourself
How are they blended?
- The mode is "add"
- The opacity is 50% of one layer over 100% of the other one. Please note: it is clearly stated in the Handbook, the opacity should be entered as a value 0...1. Do not make the easy mistake of entering 50 instead of 0.5; you wouldn't get any error, but simply the 50 is taken as 1.
- Which layer (which colour) is taken at 50%? Green, so that you get an orange with red at 255 value and green at 127 value, but
- NOT BECAUSE YOU ENTERED -blend[1,2], what you put is irrelevant, even if you put -blend[2,1] you get the same result, so remember:
- The order in which images(layers) are considered is fixed UNLESS YOU EXPLICITLY CHANGE THE ORDER, so the command always take the younger as the one to which apply the indicated opacity.
- To change the order you may use an additional parameter in the -blend command, but to be more explicit (for a novice the clarity is always important) you may...
- Enter -reverse[1,2] before blending, by this way you get a yellow-green with green at 255 value and red at 127 value.
Try some experiments yourself in a command window!
- The threshold command
Let's talk about a command not immediately understandable in its behaviour: -threshold You may use it with two different options in the first parameter (the threshold value) and with two different options in the second parameter (hard or soft).
1° parameter:
- Entering an absolute value (let's assume: 100) In this case all values in the image (in a RGB image the single values of R, G, B in each pixel) are reduced of that value (negative results become zeroes). For example an area of pixels with values R250+G150+B50 becomes an area of values R150+G50+B0.
- Entering a percentage (let's assume 40%) In this case the command performs a search for the highest value actually present in the image, then to this maximum the percentage is applied and the result becomes the absolute threshold value; assuming there is at least one value of 255, the threshold of 40% is calculated as 102 (40% of 255) then the previous algorithm is applied, so the mentioned area will become an area of values R148+G48+B0. This clarifies that the percentage is not applied to the single values as one could have expected.
2° parameter:
- 0=hard (default) In this case all values which ended up in the previous algorithm to a positive number >0 are converted to 1; thus the image will have only 0 and 1 values in each colour of an RGB pixel.
- 1=soft (you must enter it to replace default) In this case all values previously calculated remain as calculated.
In both cases it is recommended to enter afterwards the command -normalize 0,255 Well, in case you selected a small value and soft-mode, you may also look at the transformed image without normalizing it (maybe you like it). If you opted for the default hard-mode the -normalize command is mandatory, otherwise you get only a black screen.
Uses:
- Using soft-mode + normalize you get colours somehow "stretched" and "contrasted", you may experiment on images lacking of vivacity. For example: -threshold 25%,1 -normalize 0,255
- Using hard-mode + normalize you get a nice kind of "cartoonized" image, having 8 colours: black, white, red, green, blue, cyan, yellow and magenta You may understand this by thinking about the fact that each hard value is either 1 or 0 and there are 3 values R/G/B. So 2 to the power of 3 is 8: RGB hard=000 or 001 or 010 or 011 or 100 or 101 or 110 or 111 Which after normalization become: 0 0 0 / 0 0 255 / 0 255 0 / 0 255 255 / 255 0 0 / 255 0 255 / 255 255 0 / 255 255 255 Alias: black blue green cyan red magenta yellow white Normally a good result is obtained using 50% as first parameter, thus: -threshold 50%,0 -normalize 0,255 Experiment on G'MIC console.
- Using the max command with a formula
- Forward Note: in the examples here we use the "^" (caret) symbol, if you encounter any strange behavior be sure to check it's being entered correctly - it's been known to cause issues especially when copy/pasting from a document.
Let's talk about the command -max You can find its description on page 61-62 of the Handbook. It's very generic and can be used for many purposes, I refer explicitly to example 76 which is able to "fade" an open image. So, open an image in Gimp, start G'MIC->Various->Custom code (local). Enter the command of the example: -max 'R=((x/w-0.5)^2+(y/h-0.5)^2)^0.5;255*R'
As you can see, the image is faded out from the centre towards the corners. In fact, the formula create like a b/w fading mask starting from black at the centre, then for each pixel the command chooses between the values in the image and the values in the mask defined by the formula. So you see grey pixels overriding the image pixels around the centre (none close to the centre, a lot close to the corners).
Assume you have an image where the centre of attention is NOT the centre of the image. In this case you may change the formula on the first and second "0.5" you find in it:
- Reducing the first 0.5 moves the centre of the attention to the left
- Increasing the first 0.5 moves the centre of attention to the right
- Reducing the second 0.5 moves the centre of the attention to the top
- Increasing the second 0.5 moves the centre of attention to the bottom
So, if you enter the command modified as such: -max 'R=((x/w-0.25)^2+(y/h-0.25)^2)^0.5;255*R' you get an image with the centre of the attention on the top-left quadrant.
If you enter the command modified as such: -max 'R=((x/w-0.75)^2+(y/h-0.75)^2)^0.5;255*R' you get an image with the centre of the attention on the bottom-right quadrant.
Now, assume you want a centre of attention smaller or larger. In this case you have to play with the last 0.5 in the formula:
- Reducing that value you reduce the centre of attention area
- Increasing that value you enlarge the centre of attention area
Let's experiment with: -max 'R=((x/w-0.50)^2+(y/h-0.50)^2)^0.25;255*R' -max 'R=((x/w-0.50)^2+(y/h-0.50)^2)^0.75;255*R' and you will see the effects.
- About the resize command
Part 1. Creating a pattern then applying -resize
- Open gimp
- Create an image 30*30, black
- Select G'MIC -> various -> custom code (local)
- Remove what you find in there
- Enter the following:
#Let's create a new image 3*3 with colours R G B ; B R G ; G B R
(1,0,0;0,1,0;0,0,1^0,1,0;0,0,1;1,0,0^0,0,1;1,0,0;0,1,0)
-normalize 0,255 #bring the values to {0,255} range
-resize[1] [0],3 #this is the command under examination
-keep[1] #just to see only the newly created image
- Set output mode: new image
- Set OK
In this case we resized the newly created pattern to the base image dimensions using linear interpolation. Now, we will test other resizing options, just replacing the command -resize[1] [0],3 with different formats.
-resize[1] [0],0,0 #we get the "canvas" (let me call it this way) resized but the pattern is not rescaled, left 3*3 at the top-left corner. Here the first 0 means no interpolation, the second 0 means boundary black.
-resize[1] [0],0,1 #we get the canvas resized but the pattern is not rescaled, left 3*3 at the top-left corner. Here the first 0 means no interpolation, second parameter=1 means boundary extended with the colours of the last pixel (we see a lot of red because the bottom right pixel is red).
-resize[1] [0],0,2 #we get the canvas resized and filled completely by the pattern 3*3. And this time the first 0 means no interpolation, second parameter=2 means boundary extended with replications.
-resize[1] [0],1,0 #we get the 3*3 pattern rescaled 30*30 -resize[1] [0],2,0 #same as with 1 -resize[1] [0],3,0 #we get the 3*3 pattern rescaled 30*30 and colours nicely interpolated -resize[1] [0],3,1 #same as above, with a different interpolation of the boundaries
You can put 5 or 6 in the previous 2 examples and you will get almost same results as with 3; the difference is in the interpolation (linear, bicubic, lanczos). -resize[1] [0],4,0 #we get a black grid interpolating the 3*3 pattern In this case, due to the big resizing (10 to 1), the grid is big and occupies 9/10 of the image.
Part 2. Applying -resize to an existing image
- Open gimp
- Open your image
- Experiment with:
--resize 300%,200%,1,3,0,2 #you get your image replicated six times (3*2)
#or
--resize 110%,110%,1,3,4,0 #you get a grid interpolated (10% only)
#you may also apply again interpolation 4 on the already interpolated image
-resize 150%,150%,1,3,4,0 #you get a nice kind of double grid
#also try
--resize 110%,110%,1,3,0,1 #you get a kind of frame with the boundary
#extended (having added 0.5,0.5 the image is centered)
OK, now continue as you like (if you like...)
Note: interpolation 3, 5, 6 (linear, bicubic, lanczos) are the usual resizing interpolation types found in almost all image processing software.
- Some handy photo manipulation commands
Many (if not all) of the following effects are available in "ready-to-go" filters, but I prefer discuss here of "native" commands you can insert in your G'MIC experiments.
-vignette
This command is shown in the handbook without indication of the default parameters: strength, minimum radius, maximum radius. By experimenting it seems the defaults are: 100,70,90.
So, you can increase or reduce the "black" of the mask by increasing/reducing the first value the radius parameters are referring to the "untouched" area of the image, and must be values in the range 0-100. You can shrink or enlarge the untouched area by reducing/increasing delta radius, that is: the difference between the two values.
Note: even if the first radius is said to be "minimum" and the second one "maximum", what really matters is the difference between the two; so you get the same result with 100,40,80 as with 100,80,40.
If the two radius have equal values, no vignette occurs; if you have a photo with a well centred point of interest (well, it should be the case, otherwise vignetting is not appropriate), I found a nice result with -vignette 200,50,100.
-texturize_paper
This command has no parameter, but a very nice effect, as if the photo was printed on a paper with a rough surface.
-texturize_canvas
This command has three parameters: amplitude, fibrousness, emboss-level; also the defaults are specified: 20, 3, 0.6. The defaults produce very nice effect, as if the photo was printed on a canvas like a painting. But - as the real canvas a real painter finds in a shop - texture may vary a lot, so you may do some experiment. I like to increase the first value but not the others - I like the result of -texturize_canvas 50 but it's a matter of taste.
Note that with this command (as well as with the previous one) you get different results even if you do not change parameters, i.e. G'MIC creates the texture to a certain extent "randomly" (at least: this is the effect running it in the G'MIC console and hitting "update" without changing parameters, try it).
Another couple of commands which could be useful to transform a little bit your photos are:
-light_patch -shadow_patch
I like them to increase the atmosphere of a garden with trees, especially the first one. The second one can be added with a very low level of shadow, which correspond to a high level of the single parameter: "opacity" (?!).
Some settings I have used previously are:
-light_patch 20,0.8,2.1 # density, darkness, lightness (defaults are: 10,0.9,1.7
-shadow_patch 0.8 # opacity, default is 0.7
- Colors with uniform_distribution
Today we talk about a "funny" command:
-uniform_distribution
I call it "funny" because - if I play with the second parameter - I may get funny results. Certainly they are not funny for a scientist, but we talk among non-scientist gimp users. Anyhow, to avoid confusion, we will strictly adhere to a basic rule: because the second parameter is the "spectrum" (which is the name of the fourth dimension of an image, i.e. the "channels") we will use this second parameter: a) set to 3 when we play with an RGB image b) set to 4 when we play with an RGBA image
The first parameter defines the number of colour-levels, which for us become stripes. First of all we set the environment:
- Open a new gimp image, white, RGB, default 640x400 pixels
- Start GMIC console (you know how to) and set output to "new image"
- Enter this sequence of commands (after having cleaned the area):
-uniform_distribution 64,3 # step 4 - as in the example on page 34 of the handbook
#this will create an image 64x1x1x3
-normalize[1] 0,255 # step 5 - normalize as usual
-resize[1] [0] # step 6 - expand the created image to the gimp image
-keep[1] # step 7 - to have as output only the new image
Case A) RGB image
With the shown parameters we get an image 640x400x1x3 filled with coloured stripes. You see 64 stripes (=1°parameter), in 4 groups, with colours moving from dark to light. Each group can be considered subdivided in 4 sub-groups. Each of the 4 sub-groups contains 4 stripes. The colours vary as such:
(r)the red varies on each stripe with a sequence of 0 - 85 -170 -255 (g)the green varies on each sub-group with a sequence of 0 - 85 -170 -255 (b)the blue varies on each group with a sequence of 0 - 85 -170 -255
Case B) RGBA image
(1) modify step 1 to get an RGBA image (use Layer->Transparency->Add alpha channel) (4) modify step 4 to set the second parameter to 4 (-uniform_distribution 64,4)
You still see 64 stripes, but in 3 groups subdivided in 3 sub-groups. Each sub-group has 7 stripes, except the first one wich has 8 stripes (or perhaps there is an initial group of one stripe only, you cannot distinguish). The first group (1+7*3 stripes) is totally transparent, because of alpha set to 0. The second group shows an alpha of 127. The third group shows an alpha of 255 (full colours). We will consider the last group for colour analysis (for the other two apply alpha). In this third group the colours vary as such:
(r)the red varies on each stripe but not with an equal sequence on the sub-groups (g)the green varies with the sequence 0-0-0-127-127-255 along each sub-stripe (b)the blue varies regularly among groups with value 0-127-255
Maybe that - having an additional channel - the number of stripes has to be different.
What to do? It's up to you. I play converting those images to gimp palettes and mapping one of my images with them.
- Creating gradients
Let's talk about gradients (in Gimp language). One could say: well, there are fantastic gradients in Gimp, so why bother? Right, but G'MIC is not able to access Gimp functions, so if one likes to create a custom G'MIC command self-standing, it's better to know how to create gradients to be used for overlaying images and so on.
Recall; to define a new image with predefined colours we need:
- Enclosing parenthesis ( ... )
- A string of numbers inside where:
- Points on the same row are separated by commas (,)
- Columns are separated by semicolons (;)
- Colours are separated by the symbol ^
Values "per-se" are irrelevant, what's important is the proportion among them. At the end we will insert the command -normalize to get visible values.
I write down here some examples of gradients: Note the full sequence of commands is written only on gradient 1, for the other only the line related to the gradient is shown. In the last two examples we make use of an escape character (backslash "") in order to split the single command into several lines. Where it's the last character on the line it means treat the following line as part of the current one (in other words ignore the newline).
#gradient 1 (generic)
(2,2,0;2,2,0;0,0,0^0,2,2;2,2,2;2,2,0^0,0,0;0,0,2;0,2,2)
-normalize[1] 0,255
-resize[1] [0],3
-keep[1]
#corners:
#top-left=red
#top-right=green
#bottom-left=green
#bottom-left=blu
#mid-points:
#top=yellow
#left=yellow
#right=cyan
#bottom=cyan
#gradient 2 (landscape)
(0,0,0;0,0,0;3,3,3^0,0,0;3,3,3;1,1,1^2,2,2;3,3,3;0,0,0)
#top-line=blue
#mid-line=cyan
#bottom-line=red-orange
#gradient 3 (seascape)
(0,0,0;1,1,1;0,0,0^1,1,1;3,3,3;2,2,2^2,2,2;3,3,3;2,2,2)
#top-line=blue
#mid-line=cyan
#bottom-line=red-orange
#gradient 4 (blue-cyan vignette)
(0,3,3,0;2,5,5,2;2,5,5,2;0,3,3,0^\
1,3,3,1;3,5,5,3;3,5,5,3;1,3,3,1^\
1,3,3,1;3,5,5,3;3,5,5,3;1,3,3,1)
#corners="dirty"-blue-cyan
#mid-points="dirty" white
#gradient 5 (red-orange vignette)
(3,8,8,3;3,11,11,3;3,11,11,3;3,6,6,3^\
0,2,2,0;2,8,8,2;2,8,8,2;0,2,2,0^\
0,0,0,0;1,5,5,1;1,5,5,1;0,0,0,0)
#corners="dirty"-red
#mid-points="dirty"-orange
- Naming images in the stack
Today we talk about a rarely mentioned command: -name It does neither create nor modify an image. So, why to talk about it? Well, as said many times, this topic is for non-scientist candidate coders in G'MIC world, thus clarity is very important for us. For this reason using a name to refer to an image in the stack rather than an index can be beneficial.
While prototyping a filter we are usually more concerned with readability, so following some simple rules can help:
- One line per command
- The full-text command instead of the abbreviated one (-remove not -rm, -reverse not -rv, ...)
- Use the command -name to better understand the code, especially when it becomes complex.
Here an example. Assume we call G'MIC after having created a new image in GIMP, white. We enter:
-name[0] white_image
# from now on, we can refer to the image received in input as "white_image"
Then we enter:
[white_image]x3 # we ask GMIC to create 3 copies of the received image
Then we rename all three copies as such:
-name[1] first_copy
-name[2] second_copy
-name[3] third_copy
We like to fill the copies with different colours, so we enter:
-fill_color[first_copy] 255 # pure red
-fill_color[second_copy] 0,255 # pure green
-fill_color[third_copy] 0,0,255 # pure blue
Well, better now if we rename those three copies with more meaningful names, so we enter:
-name[first_copy] red,1 # the ,1 stays for renamed ("is_modified")
-name[second_copy] green,1
-name[third_copy] blue,1
OK, now we now which layers we manage, so let's enter:
-reverse[green,red] # we reverse the order between the second and the first copy
# after this command, the series of layers will be:
# white, green, red, blue
We enter a command which will verify the order we imposed to the layers. The blend command blends each pair of layers on the stack and we use average-mode to better verify values of colours.
--blend average # two new layers are created:
# the first new layer comes from blending white and green
# the second new layer comes from blending red and blue
We double-check the result using the colour-picker tool of gimp... On the first new (fifth in the list) we find the colour: 127,255,127 OK On the second new (sixth in the list) we find the colour: 127,0,127 OK
We could also play again and enter anew:
--blend average # other three new layers are created:
# the first two are exactly the same as before
# the third one comes from blending the pale green (fifth layer) and the purple (sixth layer)
We double-check again with the colour-picker and we find the colour: 127,127,127 OK
Have fun!
- Image clean-up using bilateral
Today we will enter into photo manipulation/enhancement. At first, a very useful denoising command: -bilateral
This works better than other "traditional" methods:
- It does not blur the image
- It does not create halos
- Because it preserves edges (does not average pixels across edges).
Warning: this edge-preserving "quality" may become undesirable when the command is used with high values, the result of which could be a "cartoonised" image.
The command uses two parameters:
- The "space" (extension of the area around each pixel to be used for averaging)
- The "range" (the minimum amplitude for considering an "edge")
We detail two approaches:
- Applying the denoising function to each colour channel separately.
- It's known that noise is greater on red and blue channels than on the green one
- Applying the denoising function separately on luma and chroma
- It's known that we may blur colours more than luminosity
Case 1
Enter the following sequence of commands:
--split[0] c # the input image is split into 3 layers: R,G,B
# we use the naming command as already learned
-name[1] red
-name[2] green
-name[3] blue
# now we call -bilateral with different values for each colour
-bilateral[red] 2.5,5
-bilateral[green] 1.25,2.5
-bilateral[blue] 3.75,7.5
# small values for green, higher values for red and blue
# now we recombine the 3 layers into a single RGB image
--append[blue,green,red] c
# we give it a name
-name[4] cleaned
# we save only the result, discarding the rest
-keep[cleaned]
The first value can be better entered as a percentage of image space, for example:
--split[0] c
-name[1] red
-name[2] green
-name[3] blue
-bilateral[red] 1%,7
-bilateral[green] 0.25%,3
-bilateral[blue] 1.5%,10
--append[blue,green,red] c
-name[4] cleaned
-keep[cleaned]
Case 2 using YCbCr to split the image (luma-chroma)
-rgb2ycbcr # split the image into 3 layers, 1 for luma, 2 for chroma
--split[0] c
-name[1] luma
-name[2] chromaB
-name[3] chromaR
-bilateral[luma] 1.25,1.25
-bilateral[chromaB] 8.75,8.75
-bilateral[chromaR] 8.75,8.75
# low values for luma, higher values for chroma
--append[luma,chromaB,chromaR] c
-name[4] cleaned
-ycbcr2rgb[cleaned]
-keep[cleaned]
Also in this case, we better use percentage as first parameter
-rgb2ycbcr
--split[0] c
-name[1] luma
-name[2] chromaB
-name[3] chromaR
-bilateral[luma] 0.25%,3
-bilateral[chromaB] 3%,10
-bilateral[chromaR] 3%,10
--append[luma,chromaB,chromaR] c
-name[4] cleaned
-ycbcr2rgb[cleaned]
-keep[cleaned]
- A further cleanup optimisation
Most images have more noise in the shadows. A simple method of changing the noise reduction strength in the shadows is to us the -apply_gamma command before the noise reduction, and then again afterwards to reverse the initial gamma change.
-apply_gamma 0.7 # makes image darker and reduces contrast in the shadows
# rest of the filter goes here.
-apply_gamma {1/0.7} # Reverses the gamma change at the start to give correct brightness.
This works because the gamma change reduces the contrast between dark pixels, and increases the contrast between light pixels, so the bilateral filter smooths darker parts of the image more than the lighter parts.
A gamma value less than 1 will increase the noise reduction in the shadows, a gamma value greater than 1 will have the opposite effect and the highlights will have more noise reduction. A value of one will have no effect.
Thanks to dinasset for both the idea for this page and the majority of tips themselves.