G'MIC exercises

I’ll try to explain better with images.

Input Image of 32x32

image

The search image

The placement of the search image

image

The output image

image

The process of what I want:

  1. Using a search radius on the input image and place at x,y,z coordinate (Note: x,y,z place is suppose to be where the center of the sphere or circle is.), find all the white pixels coordinates that resides within the search image placed at x,y,z. The white pixels are on the output image.
  2. Then output the coordinates of all white pixels that resides within the boundary of the search image.

Use the crop() function is retrieve your neighbourhood. Each parameter will loop if you use whds variables or not if you use values. N=crop(...); If you want another shape, you would need a set of conditions to rule out those regions.

@afre
Well, I haven’t figured out a way to avoid the for(z..for(y,...for(x...););); loop thing. I still need to find a way to extract all coordinates, and to do that , the easiest routes was to use the loop. But, I did managed to only need one loop to extract what I need.

imgs={$!}
1,1,1,1
eval ${-math_lib}"
for(img=0,img<"$imgs",img++,
    alpc=s#img-1;
    n0alpc=0;
    for(pz=0,pz<d#img,pz++,
        for(px=0,px<w#img,px++,
            for(py=0,py<h#img,py++,if(i(#img,px,py,pz,alpc),dar_insert(#-1,px);dar_insert(#-1,py);dar_insert(#-1,pz););
            );
        );
    );
);
"
size={iM#-1}
r. 1,{iM#-1},1,1,0,0,0,0
u {"coords=vector"$size"(0);
for(k=0,k<h#-1,k++,coords[k]=i(#-1,0,k););
(coords)
"}
rm.

Sorry for the incomplete answer above; my dad has been terribly sick again. Here is some more to go by on crop(...). Take this silly foo:

f N=crop(x,y,z,c,3*2+1,3*2+1,1,1);min(N)>=128?i/2:i

It takes a radius=3 neighbourhood for every pixel and, if the min(N)>=128, do i/2. If you figure out how to use crop(...) to your advantage, perhaps you could be able to crop a or many ROI and use each window to extract coordinates.

my dad has been terribly sick again.

In that case, I won’t bother you with questions for a while, but I’ll try to find out for myself like usually.


@KaRo You wouldn’t happen to know how to get value found in n placement of a variable assigned? What I’m trying to achieve is Gossamer filter for Paint.NET, but for g’mic. Hence, why I am extracting coordinates.

rep_sphere_search_coords 5,0 #0,-2,0,-1,-1.....#
test=${}
error {$test[4]} #Expected output == -1}#
#Actual Output == Item substitution.....#

I don’t want to recreate the image over and over per loop for efficiency reasons. Hence, my need to do this.

EDIT: Nothing works. I can’t access vectors without going into eval or u, and I wish to be able to access them outside of those. I guess I will settle with crop even though I don’t want to create a image to make the task easier.

Time to post again after what feels like a century.

First, after a long while of trying to figure out how to do this, giving up and then sorting it out using the GEGL implementation as a reference, the kaleidoscope layer cake script is ready to use.

#@gui Kaleidoscope Layer Cake : fx_jr_klc, fx_jr_klc_preview(1)
#@gui : sep = separator()
#@gui : Kaleidoscope Mirrors = int(6,1,64)
#@gui : Mirror Rotation = float(0,-360,360)
#@gui : Result Rotation = float(0,-360,360)
#@gui : Centre (%) = point(50,50,0,1)
#@gui : Mirror Offset (%) = point(50,50,0,1)
#@gui : Scale (%) = float(100,0,1000)
#@gui : Scale Bend (%) = float(0,-5,5)
#@gui : Broken Mirrors = choice("Off","On","Reverse")
#@gui : Layer Cake Density = float(30,0,100)
#@gui : Angle = float(0,-360,360)
#@gui : Angle Mode = choice("Normal","Divide by mirror quantity")
#@gui : Anti-Alias = choice("Off","2","3","4")
#@gui : Interpolation = choice(2,"None","Linear","Bicubic")
#@gui : Boundary = choice(3,"Transparent","Nearest","Periodic","Mirror")
fx_jr_klc:
aa=($14+1)
r2dx w*$aa
num=$1
mrot={$2/180*pi}
rrot={$3/180*pi}
cx=$4*w/100
cy=$5*h/100
ox=$6*w/100
oy=$7*h/100
scale=$8/100
sbend=$9
broken=$10
lcd=$11
lcang={$12/180*pi}
lcam=$13
inter=$15
bound=$16
f "begin(mrot="$mrot";rrot="$rrot";cx="$cx";cy="$cy";ox="$ox";oy="$oy";num="$num";scale="$scale";sbend="$sbend";broken="$broken";inter="$inter";bound="$bound";lcd="$lcd";lcang="$lcang";lcam="$lcam";aa="$aa";);
vx=x-cx+0.5*aa;vy=y-cy+0.5*aa;
maxr=sqrt((w+0.5*aa)^2+(h+0.5*aa)^2)/2;
rad=sqrt(vx^2+vy^2)/maxr;
radius=((rad)^(2^sbend));
ang=atan2(vy,vx)-mrot-rrot-((lcd==0?(radius*scale):(floor(radius*lcd*scale)/lcd))*lcang/(lcam?num:1));
awidth=pi/num;
mult = ceil(ang/awidth)-1;
ang -= mult*awidth;
broken==1?ang=ang:broken==2?ang=awidth-ang:(mult%2==1)?(ang = awidth - ang);
ang += mrot;
xwarp=radius*scale*maxr*cos(ang)+ox-0.5*aa;
ywarp=radius*scale*maxr*sin(ang)+oy-0.5*aa;
I=I(xwarp,ywarp,z,inter,bound)"
r2dx w/$aa
fx_jr_klc_preview:
fx_jr_klc $*

The only issue with this is that the I haven’t figured out a way to perform some kind of bilinear interpolation near the edges of the layers and strips as I was able to do with the layer cake script.

Meanwhile, I’ve been trying to figure out how to speed up the DCT and IDCT commands which would help with speeding up a far more configurable JFIF encoding and glitching filter. The current issue is that when an image is split into small tiles (say, 8x8) it’s painfully slow, and yet performing a DCT on the whole image is pretty fast. Today I’ve been looking for fast DCT algorithms to try and mitigate this but all the implementations I’ve found only work with powers of 2. I’m not sure how to generalise this.

While I was hunting for such generalisations I found an image scaling algorithm which might be useful: https://www.tau.ac.il/~bilevich/DCT_Scaling_Algorithm_SPIE_2013.pdf

1 Like

In that case, I would suggest to create a image, and utilize transformation within a filling of a image much in the same way that I did with rep_rectangular_polar_transform or rep_equi2cube.

Wouldn’t that make the transitions between kaleidoscope strips increase with distance from the centre though?

I thought that was the idea of the layer cake filter?

The layer cake script can blur the layers with respect to the radius. A modified kaleidoscope script could blur the strips only with respect to the angle - but then the degree of blurring would increase with distance from the centre.

I can’t seem to get GUI options to appear and disappear for my neon script.

#@gui Neon : fx_neon, fx_neon_preview
#@gui : note = note("Turns bright image outlines into bright, neon-like lines.")
#@gui : sep = separator(), note = note("Lines")
#@gui : 1. Norm Mode = choice("Gradient norm","Hessian","Laplacian","Rotation-invariant gradient","Afre's Edge algorithm")
#@gui : 2. Thinning  = int(1,1,10)
#@gui : 3. Recovery  = float(1,.5,4)
#@gui : 4. Brightness  = float(1,.5,4)
#@gui : 5. Details  = float(1,.5,4)
#@gui : 6. Smoothness = float(0,0,10)
#@gui : 7. Contrast = float(0.45,0,1.5)
#@gui : 8. Min Threshold = float(40,0,100)
#@gui : 9. Max Threshold = float(60,0,100)
#@gui : 10. Negative = bool(0)
#@gui : 11. Opacity Over Original = float(1,0,1)
#@gui : 12. Saturation = float(1.15,0,4)
#@gui : 13. Blur Colours = float(2,0,20)
#@gui : sep = separator(), note = note("Antialias")
#@gui : 14. Amplitude = float(3,0,100)
#@gui : 15. Edge Threshold (%) = float(0,0,100)
#@gui : 16. Smoothness = float(3,0,5)
#@gui : sep = separator(), note = note("Colour Glow 1")
#@gui : 17. Size = float(20,0,100)
#@gui : 18. Intensity = float(0.4,0,3)
#@gui : 19. Darken = float(0.1,0,1)
#@gui : 20. Saturation = float(1.5,0,4)
#@gui : sep = separator(), note = note("Colour Glow 2")
#@gui : 21. Size = float(5,0,100)
#@gui : 22. Intensity = float(0.2,0,3)
#@gui : 23. Darken = float(0.1,0,1)
#@gui : 24. Saturation = float(1,0,4)
#@gui : sep = separator(), note = note("Boost Glow")
#@gui : 25. Size = float(2,0,5)
#@gui : 26. Intensity = float(1,0,3)
#@gui : sep = separator()
#@gui : 27. Smooth Hues = float(0,0,20)
#@gui : sep = separator()
#@gui : 28. Alpha = bool(0)
#@gui : 29. Alpha Power = float(1,0,5)
#@gui : 30. Alpha Multiplier = float(1,0,5)
#@gui : sep = separator(), 31-33. 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_neon :
repeat $! l[$>]
+fc 0,0,0 rv blend alpha
to_rgb rgb2hsl8 s c
*.. {$8^2.5} c 0,255
a[0-2] c hsl82rgb
if $11
[0] l[1]
b $6
if {$1==1}
+hessian xx sqr.
+hessian.. yy sqr. +[-2,-1]
hessian.. zz sqr.. +[-2,-1]
s={s} s. c +[-$s--1] sqrt.
elif {$1==2}
laplacian abs to_gray to_rgb
elif {$1==3}
gradient xyz abs blend add to_gray to_rgb
elif {$1==4}
afre_edge ${2-5}
else
gradient_norm replace_inf 1 replace_nan 0
fi
c 0,255
^ $7
c $8%,$9%
if $10 negate fi
n 0,255
if {$14!=0||$15!=100}
fx_smooth_antialias ${14-16}
fi
endl
if $13
b[0] {$6}%
fi
blend multiply,$11
fi
+b[0] {$17%*100},1 *[1] {$18*sqrt($17%)*10} -[1] {(($18*sqrt($17%)*128)-1)^(sqrt($19))}
+b[0] {$21%*100},1 *[2] {$22*sqrt($21%)*10} -[2] {(($22*sqrt($21%)*128)-1)^(sqrt($19))}
+b[0] $25,1 *[3] {($18+$22)*$25*($26^2.5)}
rgb2hsl[1-3] s[1-3] c
*[2] {$20^2.5}
*[5] {$24^2.5}
*[8] 0
a[1-3] c a[2-4] c a[3-5] c hsl2rgb[1-3]
replace_inf 1 replace_nan 0
blend add
if $27
rgb2ycbcr s c b[1,2] {$27%*100} a c ycbcr2rgb
fi
if $28
rgb2hsv8 100%,100%,1,1 f[1] "((j(#0,0,0,0,2)/255)^(1/$25))*255*$30" f[0] "[i0,i1,255]" hsv82rgb[0]  a c
fi

endl done
fx_neon_preview :
gui_split_preview "fx_neon ${1-30}",${-3--1}
u "{$1}"\
"{$2}"_{$1==4?2:0}\
"{$3}"_{$1==4?2:0}\
"{$4}"_{$1==4?2:0}\
"{$5}"_{$1==4?2:0}\
"{$6}"\
"{$7}"\
"{$8}"\
"{$9}"\
"{$10}"\
"{$11}"\
"{$12}"\
"{$13}"\
"{$14}"\
"{$15}"\
"{$16}"\
"{$17}"\
"{$18}"\
"{$19}"\
"{$20}"\
"{$21}"\
"{$22}"\
"{$23}"\
"{$24}"\
"{$25}"\
"{$26}"\
"{$27}"\
"{$28}"\
"{$29}"\
"{$30}"\
"{$31}"\
"{$32}"\
"{$33}"

I want options 2-5 to only appear when option 1 has a value of 4 but all of them display no matter what value option 1 has.

@Joan_Rake1 The _ is supposed to be inside the " marks otherwise known as quotation marks.

I tried that and it still doesn’t work.

There could be a miscount. In that case, I would increase numbers of variable. Try 34.

There is no miscount.

Try this. The $31,$32 has to be combined. For points or two variables representing one GUI element, combine them.

u "{$1}"\
"{$2}"_{$1==4?2:0}\
"{$3}"_{$1==4?2:0}\
"{$4}"_{$1==4?2:0}\
"{$5}"_{$1==4?2:0}\
"{$6}"\
"{$7}"\
"{$8}"\
"{$9}"\
"{$10}"\
"{$11}"\
"{$12}"\
"{$13}"\
"{$14}"\
"{$15}"\
"{$16}"\
"{$17}"\
"{$18}"\
"{$19}"\
"{$20}"\
"{$21}"\
"{$22}"\
"{$23}"\
"{$24}"\
"{$25}"\
"{$26}"\
"{$27}"\
"{$28}"\
"{$29}"\
"{$30}"\
"{$31,$32}"\
"{$33}"
1 Like

That worked! I haven’t seen any docs regarding this though, it’s no wonder I missed that out. If there are some, please link them to me. Also I think I’ll push my current file to the repo.

Indeed, there should be an effort to document GUI / plugin syntax. I don’t use most of what it has to offer because I use CLI and generally want it to be limited to sliders, check boxes and rarely menus. However, points, colour selection, etc., and non-interactive elements, may be necessary for certain commands.

Topic change: after finding out about @garagecoder’s InfoMap script I thought I’d make a quick details enhancement script.

.
repeat 3 bilateral.. 10,10 done
-. ..
*. 1.5
+. ..
rm..

``

EDIT: Solved it, but new problem. Random numbers, and the effect doesn’t show up.

f i0
repeat $! l[$>]
    tcr=3
    cmyk_mode=0
    if $cmyk_mode tcr+=1 fi
    if s==2||s>$tcr
    
        ss={s-1}
        {w},{h},1,1,i(#-1,x,y,z,$ss)?1
        
        eval ${-math_lib}"
            const ww=w#-1;
            const hh=h#-1;
            orientation=1;
            direction=1;
            continue=1;
            if(orientation,
                if(direction,
                    for(xx=0,xx<ww-1,xx++,
                        N=0;
                        v=0;
                        for(yy=hh-1,yy>-1,yy--,
                            if(yy==hh-1,
                                old_data=i(#-1,xx,yy);
                                for(tyy=hh-1,tyy>-1,tyy--,
                                N+=i(#-1,xx,tyy);
                                );
                                N/=hh;
                                if(N==1||N==0,break(););
                                if(!old_data,
                                    nyy=yy;
                                    do( v++;
                                        nyy--;
                                    ,(!i(#-1,xx,nyy))&&nyy>-1
                                    );
                                    i(#-1,xx,yy)=v;
                                );
                                
                            ,
                                new_data=i(#-1,xx,yy);
                                if(new_data<old_data,
                                    nyy=yy;
                                    do( v++;
                                        nyy--;
                                    ,(!i(#-1,xx,nyy))&&nyy>-1
                                    );
                                    i(#-1,xx,yy)=v;
                                );
                                i(#-1,xx,yy)=v;
                                old_data=new_data;
                            );
                        );
                    );
                ,
                    for(xx=0,xx<ww-1,xx++,
                        N=0;
                        v=0;
                        for(yy=0,yy<hh,yy++,
                            if(yy==0,
                                old_data=i(#-1,xx,yy);
                                for(tyy=0,tyy<hh,tyy++,
                                N+=i(#-1,xx,tyy);
                                );
                                N/=hh;
                                if(N==1||N==0,break(););
                                if(!old_data,
                                    nyy=yy;
                                    do( v++;
                                        nyy--;
                                    ,(!i(#-1,xx,nyy))&&nyy>-1
                                    );
                                    i(#-1,xx,yy)=v;
                                );
                            ,
                                new_data=i(#-1,xx,yy);
                                if(new_data<old_data,
                                    nyy=0;
                                    do( v++;
                                        nyy++;
                                    ,(!i(#-1,xx,nyy))&&nyy<hh
                                    );
                                );
                                i(#-1,xx,yy)=v;
                                old_data=new_data;
                            );
                        );
                    );
                );
            ,
                if(direction,
                    for(yy=0,yy<hh,yy++,
                        N=0;
                        v=0;
                        for(xx=ww-1,xx>-1,xx--,
                            if(xx==ww-1,
                                old_data=i(#-1,xx,yy);
                                for(txx=ww-1,txx>-1,txx--,
                                N+=i(#-1,txx,yy);
                                );
                                N/=ww;
                                if(N==1||N==0,break(););
                                if(!old_data,
                                    nxx=xx;
                                    do( v++;
                                        nxx--;
                                    ,(!i(#-1,nxx,yy))&&nxx>-1
                                    );
                                    i(#-1,xx,yy)=v;
                                );
                            ,
                                new_data=i(#-1,xx,yy);
                                if(new_data<old_data,
                                    nxx=0;
                                    do( v++;
                                        nxx--;
                                    ,(!i(#-1,nxx,yy))&&nxx>-1
                                    );
                                    i(#-1,xx,yy)=v;
                                );
                                i(#-1,xx,yy)=v;
                                old_data=new_data;
                            );
                        );
                    );    
                ,
                    for(yy=0,yy<hh,yy++,
                        N=0;
                        v=0;
                        for(xx=0,xx<ww,xx++,
                            if(xx==0,
                                old_data=i(#-1,xx,yy);
                                for(txx=0,txx<ww,txx++,
                                N+=i(#-1,txx,yy);
                                );
                                N/=ww;
                                if(N==1||N==0,break(););
                                if(!old_data,
                                    nxx=xx;
                                    do( v++;
                                        nxx++;
                                    ,(!i(#-1,nxx,yy))&&nxx<ww
                                    );
                                    i(#-1,xx,yy)=v;
                                );
                            ,
                                new_data=i(#-1,xx,yy);
                                if(new_data<old_data,
                                    nxx=0;
                                    do( v++;
                                        nxx--;
                                    ,(!i(#-1,nxx,yy))&&nxx>-1
                                    );
                                );
                                i(#-1,xx,yy)=v;
                                old_data=new_data;
                            );
                        );
                    );  
                );
            );
        "
    fi
    if $cmyk_mode tcr-=1 fi
endl done