Could you share your full code, and the relevant line? This is easy to do.
It’s not normalized. So, the image is 0,1 value only. I normalized my example image to demonstrate the output. White (255 in provided image) is 1 and Black is 0.
Could you share your full code, and the relevant line? This is easy to do.
It’s not normalized. So, the image is 0,1 value only. I normalized my example image to demonstrate the output. White (255 in provided image) is 1 and Black is 0.
I’m sure of it. But i’ve re-read the tutorial and i still don’t know if i should use brackets or accolades or quotes or…
This is the closest to something that i want:
1,8,1,3,'$C1R,$C1G,$C1B,$C2R,$C2G,$C2B,$C3R,$C3G,$C3B,$C4R,$C4G,$C4B,$C5R,$C5G,$C5B,$C6R,$C6G,$C6B,$C7R,$C7G,$C7B,$C8R,$C8G,$C8B' d
map.. 3,0 d
But:
Here are the default values:
#@gui : Color 1 = color(255,0,0)
#@gui : Color 2 = color(255,113,57)
#@gui : Color 3 = color(255,255,0)
#@gui : Color 4 = color(85,0,255)
#@gui : Color 5 = color(0,0,255)
#@gui : Color 6 = color(0,113,165)
#@gui : Color 7 = color(85,170,0)
#@gui : Color 8 = color(255,255,255)
They are mixed up in the palette. 1st color became 255,0,113, etc.
Try this toy GUI filter:
#@gui 7 Color Palette Example:fx_7_color_example
#@gui:Color 0=color(44,73,88)
#@gui:Color 1=color(139,151,156)
#@gui:Color 2=color(196,196,196)
#@gui:Color 3=color(75,79,77)
#@gui:Color 4=color(34,39,37)
#@gui:Color 5=color(18,17,19)
#@gui:Color 6=color(42,19,30)
fx_7_color_example:
rm
(${1-3};${4-6};${7-9};${10-12};${13-15};${16-18};${19-21}) permute. cyzx
Ok so i did write it with the parenthesis and “;” before, but i was missing the permute
command…
Now the colors are right in my script, but the map
command still outputs a 12 channel image, fully red. Note than the circles are rendered on their own with an alpha channel.
Doing an alpha blending with the background before mapping works but then i have a 9 channel image…
This also gives me a 12 channel image :
gmic run 'sp tiger s. c . a c map cool'
SHould i use compose_channels
or something?
The reason map outputs a 12 channel image is that you’re mapping color array per individual channel. 4 channel image, and 3 channel palette is 12, and 1 channel gets mapped with all of the corresponding color. You should use a 1 channel image as a map target. You can have scenario where the map target consist of 2+ channels, but likely with a 1 channel palette (which is how it’s used in my Bit-Plane Shuffler filter).
Ok, i think i’ll stick to black… good night!
I have not read the code, but by any chance, have you considered tiling the patterns? That may be more efficient and solve the last pixel row and column missing issue.
Ok, I’ll explain map again.
Try this code:
foo:
(5,4,1,7,8)
+resize. 100%,100%,100%,2,1
pal spec
+map[0,1] [2]
Ok, let’s break it down.
The first image is a single image of 5x1x1x1. It has only one channel.
The second image has 2 channels as it’s dimension is 5x1x1x2. But, every pixels has equal channel value. As the +resize denotes, this second image is a derivation of the first.
pal
is a custom command for creating palette. In this case, we generated a palette of 12x1x1x3.
Let’s see what map does for the target images [0,1]
It appears that map assigns a color to each corresponding value. 5 will return the 6th color of pal image which is [168,45,45].
[5] => [168,45,45].
[5,5] => [168,45,45,168,45,45].
That’s why you see 12 channels.
Assuming the R value of your first color is $6
(so B value of your 8th color is $31
).
Something like:
(${6-31}) r. 3,8,1,1,-1 permute. yzcx
should work.
Well my guess is that i got the radius wrong. And that maybe the outilne is drawn outside the circle, so the radius is 1px larger?
When i tiled the pattern at the beginning of this adventure, that’s how i found out it was missing a pixel, there was holes (2 whole crossing lines of them) in between the middle circles.
Also, i don’t want to use mirroring. But maybe it would work for that particular pattern.
Anyway the missing pixels are sort of fixed for now… color is another issue.
Actually i understand what’s happening with the channels, it’s just that’s it’s a bit annoying. I have a RGBA image, when i do split c
i get 3 black images and the circles are all on the alpha channel…
That tells me that mapping will never work on this image. I tried mapping to a duplicated of the alpha channel: does nothing
I also quickly tried match_rgb
and it sort of work, it’s a bit too smooth though and only one color ( probably expected though).
(${14--1}) r. 3,8,1,1,-1 permute. yzcx
yes, this works just as good as @reptorian’s solution yesterday.
THe thing is i always end up with 12 channels. Looks like an impossible mission here. For some reason the circles are only drawn on the alpha channel, probably because I filled the image with black and 0 alpha.maybe i have to fix that first.
But i’d be perfectly fine with grayscale images, i never was good with color anyway.
You should use display,
shortcut d
, for debugging breakpoints (some, I understand, also use display
to look at images. Interesting). See Post 7, Documentation and examples for writing scripts .
At the outset, interleave this command between those that make up your experimental pipeline. You will effectively single-step through your experimental pipeline. That way, when your pipeline diverges from how you think it should work to what it’s actually doing, then the next d ,
command stops the pipeline right at the genesis of that divergence, so that you can notice what is going awry, exactly at the point you are leaving the rails. Witnessing such departures is vitally important to furthering your understanding of G’MIC.
Strangely, the deepest insights to be garnered about G’MIC emerge not from my tutorials (splendid though they may be), but from seeing pipelines break. That is because bugs actually reside in our heads. Malformed code is but an outward manifestation of inward — and unsuspected — misunderstandings of G’MIC workings. When a pipeline breaks — and an aptly placed display
command catches the calamity in the making — we feel a momentary frisson of bewilderment, as some hitherto cherished idea of how G’MIC works shatters. What we held to be so does not cover the facts in front of us. Fortunately, because of a breakpoint, we are still well-situated to work out the nature of the bugs in our heads, because the event in question has yet to be obscured by the running of subsequent commands. Absent such a breakpoint, and — if we are lucky — then some aspect of the calamity leads to G’MIC throwing an exception, a sort of automatic breakpoint, and we are not yet too far removed from the genesis of the mistake. However, it could be our lot that the defective pipeline runs to completion and we are confronted with a black image or a twelve channel image or an image with weird colors and have little idea of how we obtained the mess.
Now, instead of all of this seeming bother, it may be tempting to test little G’MIC snippet pipelines in the Custom Code
filters of gmic-qt
. Alas, that handy facility has its limits; it is not built for pipelines running more than a modest length, nor is it really possible to use display
as a debugging breakpoint. Whatever is going awry, for example, may produce an image in excess of four channels, or pels with negative values. gmic
, operating in a shell, easily takes in stride pels that are less than zero or deep channel images, but such sows no end of confusion within paint programs, where layers cannot exceed four channels and get hysterical with blacker-than-black pels. You need to debug in a shell, debug without the overhead and excess machinery of paint programs getting in the way and — possibly — sowing additional confusion.
So. Before becoming the lead actor in your own personal snuff film, you wrote this pipeline:
`gmic run 'sp tiger s. c . a c map cool'`
It produced a 12 channel image. How did that happen?
Single stepping through the pipeline given as the run
argument, then a debug exercise provides this narrative:
sp tiger
d ,
The image stack acquires from the sample
command one w
×h
×d
×s
sample with dimensions 750x500x1x3. It appears to be a tiger image.s. c d ,
The single image on the stack, so selected with a pip (.
) splits, channel-wise, into three scalar images. Put a pin through “scalar”. I’ll revisit the word in the sweet by-and-by. We might interpret this threesome of images, now splayed along the image stack, as the “red”, “green” and “blue” channels of the once-composited tiger
, but that is just our suppositions at work. G’MIC’s split
command couldn’t care less about our self-imposed interpretations.input [-1]
. This re-inputs what we interpret to be the blue channel of the tiger
image and leaves an image stack with four scalar images, each dimensioned 750x500x1x1.append
command, unrestrained by any selection, consoldates the four scalar images into one 750x500x1x4 item. Because display
commands have been interleaved, this gives us a readout of image geometry and a pause to consider: do we really want a four channel RGBB image (imposing, still, our color channel interpretations)? Possibly we stop to wonder if what is happening on the image stack has anything to do with our aims are. An RGBB image? we might ask ourselves. Of course, we may not pause to consider, because it is such a pain to interleave d ,
commands throughout our pipelines. So we let the pipeline flow on.First, a tip of the hat to @David_Tschumperle . His language is terse and efficient. When he wrote the #@cli
header for map
, the help text runs just so: “Map specified vector-valued palette to selected indexed scalar images” (emphasis mine). A scalar image in G’MIC-speak is a precise idea. It represents a single channel image — always. Should an image be made up of more than one channel, then it is a vector-valued image — always. That is because a pixel of a multi-channel image is multi-part, just like a vector. Though not written out anywhere in any appendix, @David_Tschumperle uses consistent expressions for each of the common image types in G’MIC. A scalar image is a one-channel image.
Second, The help text of map imposes one further quality on its selected images. Not only are selected images composed of single-channel scalars, those scalars are to be taken as indices. What do they index? The vector-valued palette given as map's
first argument, either explicitly, as a selection of some palette image on the stack, or symbolically, one of the palettes known to the G’MIC palette
command.
Now, I wrote earlier that, generally, G’MIC imposes no general interpretations on image channels. However, that does not preclude certain G’MIC commands from placing specific interpretations on the channels of “selected images.” In this case, map
expects selected images to be composed of scalar look-up values that correspond to pixel positions of the given palette.
As I whimsically noted in its tutorial, map
is G’MIC’s paint-by-numbers command. It’s modus operandi is to scan each selected image, left-to-right, top-to-bottom, and with each picture element, (pel), i(x,y) , (1) take it to be a scalar value, and (2) use it to retrieve a vector-value from the palette, found by counting from the beginning of the palette until it reaches the position equal to the given i(x,y) index value. map
then replaces (‘maps’) the scalar with the retrieved vector value. Here’s a knock-on effect: the selected image goes from being a single channel image of scalars to a vector valued image, one with a channel count equal to that of the of the palette.
Finally, It should be clear, now, how the map cool
portion of the pipeline left the rails. map
, lacking a selection decorator, defaults to selecting all images on the stack. There is only one image on the stack, the 750x500x1x4 vector4-valued RGBB tiger
image. That’s not built like an indexed, scalar image. map
is not getting the kind of image that it expects. So it punts.
As with many G’MIC commands, map
is designed to behave as reasonably as possible when handed unreasonable selections. When its selection is vector-valued instead of the expected indexed scalar value, map
internally (1) performs split c
; in the case of the tiger
image, it now has four indexed scalar images, inputs more to its liking. (2) map
then performs its left-to-right top-to-bottom scan on each of the four split-out channels. Recall the knock-on effect: tiger's
channels go from being scalar images to vector-valued ones, composed of vectors retrieved from the palette. As you may surmise, the cool
palette is a three-channel vector-valued image. That means each of the four channels of the tiger
image become three-channel, vector-valued images in their own right. So, finally, (3) map
appends these four, three channel, vector valued images together along the spectral axis, making one output image that has 4×3=12 channels.
The key take-away is not a blow-by-blow of how some particular experimental pipeline left the rails. The key take-away is the technique of single-stepping through pipelines, using interleaved display commands that furnish the raw information on how G’MIC behaves. You observe pipelines unfold one step at a time, and can study each step in a leisurely way, as long as you want.
And — when confronted with unexpected outcomes — you can trace the incorrect results to the bugs (G’MIC misunderstandings) that are residing in your head, where all the really vexatious bugs reside. I daresay that all regular contributors to this forum follow this or a similar debugging pattern when spelunking pipelines. I routinely extract custom commands that I wish to better understand from gmic_stdlib.gmic
, put the extracted commands in small foobar.gmic
files, and then interleave display
commands through out portions of the command’s pipeline that I want to better understand. I sometimes even re-transcribe such commands in what I call the tutorial style, not because I think all custom commands should be written that way, but to force myself to closely read the code as I go about transcribing it.
When you master this technique, there is no real reason to stick with hazy guesses about how G’MIC behaves. You can observe its behavior in a concrete fashion and develop practical understandings on how G’MIC commands work. Soon, you will be proceeding less by guess-work, and more by preconceived, deliberate, engineered plans.
That’s when the fun really begins.
Ha! Changed the documentation on me!
Oh d, oh d, I know thee!
Oh Oh w! I know thou!
William Fakepears
Seriously, d is the comand i use the most, even more than " "
(read: input
), to the point it bceomes painful to remove them from the script afterwards. So many of them. I also use repeat N { [stuff happening] w } to "done"
to check if a repeat goes on for too long (useful for these damned circles).
Lol really?
Yes. I wanted a 4 channel image here because it is what i have in my script. RGBB worked as RGBA here. It wasn’t important what the alpha what. Could have used to_a
instead but nvm.
I followed your recommendations btw, drawing circles with color 0,0,0,255
over an image filled with 0,0,0,0
. Except i forgot i was drawing black on black so in the end i have 3 black channels and an alpha filled with circles, which is to be expected. Went too fast there. So using map
even on only one channel of this image doesn’t do much. My bad, fell into a pit trap there.
Thanks, this is the info i needed.
Reptorian summed it up here, so yes i understood then what map does. 3 x 4 = 12… 3 x 1 = RGB. It was pretty clear then. Except i need the alpha… since i think i’m going this way (Gimp simulation), or at least something like that :
@David_Tschumperle thanks, the map
definition is more clear now.
Ok thanks guys. But in the end the thing that annoys me the most is my inability to fill an image evenly with these circles. It only works for square images. No portrait, no landscape. Sad. Gotta figure it out, but i keep failing. @Reptorian got it, but i can’t read his code lol. But don’t bother explaining it to me, you’ve wasted enough time already. I have to come up with my own.
mmmm, my first shot at this :
Biggest uestion will be : OMG how am i gonna fill this!? (>_<)
label_fg is your friend. It identifies what can serve as a background region. From there a mask, a color background image fashioned from such a mask, and a composite. Serve cold.
Thanks. I somehow managed to do it with flood
, by blending the leaf with a white background (leaf is just black lines on alpha). This will probably work (although not perfect) as long as the background is a plain color.
The leaf itself is not always generated properly anyway lol.
I’ll try label_fg
to see if i can manage…
EDIT: got this far. There are still a feww holes and a bit of alpha but that’s a start…
You can always remove the gray area as a copy before label_fg. Still a great start.
EDIT: +neq 0
would do. neq is short for not equal. That will remove the greys.
Ha! I was looking for a fill
expression to do that.
The fill expression equivalent would be just +f bool(i)
.
Even more confusing. +f !!i