Reptorian G'MIC Filters

I agree and that sounds roughly how I handled the matter in my case. (Just had trouble expressing myself yesterday.) I am wondering why you did [1,{$!-1}] instead of [1,-1]. Would like to know for my education.

I’ll use [1,-1] instead. You wouldn’t happen to know how to send a image as variable? I’d like to do this.

Image0=[0]
l[1]$Image0 rm… endl

What I should see is Image0 on [1]. It would solve my issue and keep the fast processing speed offered by apply_parallel.

As far as I can tell, a variable cannot store an image in this manner. Perhaps in (…) form but I don’t think that is what you want. Other than that, I guess

Image0=[0]
l[1]$Image0 rm… endl

would become

l[1][0] rm… endl

Yeah, I guess my filter would have to be on hold until I can find a solution to this. $[] did not work for me, and it seem to be on the manual. I would love to be able to create [0] within l[1] or apply_parallel “” for that matter.

I don’t quite know how to use your commands. Both commands yield the same thing: a copy of tiger.

gmic sp tiger +rep_form_pixel -1,20,20  # psnr = inf
gmic sp tiger +_rep_form_pixel -1,20,20 # psnr = inf

You need to have at least two images to work with -1 or any other negative number. Otherwise, named shapes or 0-23 would create shaped tiles using the corresponding shape.

The results for both commands are identical.
gmic sp tiger,flower,50 +rep_form_pixel -1,20,20 +_rep_form_pixel[0,1] -1,20,20 rm[0,1] a[2,3] x a[0,1] x

image

They’re identical, but for defined shapes case, rep_form_pixel is at least 3-8 times faster. If I could send image to variable, the image as shape reference case would be faster for rep_form_pixel than _rep_form_pixel.

If I am getting you right, you mean to say that defined shapes currently run faster using the apply_parallel command, and you want the same to be the case for an arbitrary image pair.

Yes, that is what I want to solve.

Have you tried changing the format of the image? E.g., (…) form as I guess-suggested? I don’t quite know which format the defined shapes are in… You probably know enough C(++) code to dig into CImg and G’MIC.

The issue been solved. Now I have finished and made a pull request on gmic-community.

Here’s a picture to go with it -

Process with polygon as shape tile on HSL colour space.

2 Likes

Another filter is in work. Here’s the code for playing around with this filter.

offset_x=0
offset_y=-0*-1
mode=0; #HARD;MEDIUM;SOFT;DESTROY#
{w},{h},100%,4,0
#Formula creates the basic donut#
f. "
ang=110;
ang=pi*(ang/180);
r=max(w,h)/min(w,h);
xx=((x/w-.5)*2)*(w>h?r:1);
yy=((y/h-.5)*2)*(h>w?r:1);
sph=sqrt(xx^2+yy^2);
mv1_sph=1;
mv2_sph=.4;
max_val_sph=max(mv1_sph,mv2_sph);
min_val_sph=min(mv1_sph,mv2_sph);
sph_bnd=sph>max_val_sph||sph<min_val_sph?0:1;
nv_sph=((1/((max_val_sph-min_val_sph)/1))*(sph-max_val_sph)+max_val_sph);
nv_sph-=.5;
nv_sph=cos(nv_sph*pi)*sph_bnd;
XX=xx*cos(ang)-yy*sin(ang);
YY=xx*sin(ang)+yy*cos(ang);
xx=XX;
yy=YY;
xx/=2*(w>h?r:1);
yy/=2*(h>w?r:1);
xx+=.5;
yy+=.5;
[nv_sph,sph_bnd,xx,yy];
"
shift. {($offset_x*100)/2}%,{($offset_y*100)/2}%
f.. "
donut_x=i2#-1+"$offset_x"/2;
donut_y=i3#-1+"$offset_y"/2;
donut_opacity=i1#-1;
donut_depth=i0#-1;
xx=(x/w);
yy=(y/h);
donut_xx=donut_opacity>0?donut_x:xx;
donut_yy=donut_opacity>0?donut_y:yy;
xx=donut_xx*donut_depth+xx*(1-donut_depth);
yy=donut_yy*donut_depth+yy*(1-donut_depth);
i(xx*w,yy*h,z,c,2,3);
"
k..

@afre I’m wondering something. Is it possible to generate non-existent color noises based on absolute integer value? I could do a script to test values and if passed, then color doesn’t exist and proceed to make it. This idea comes from pdn forum in which a member wanted to see if it is possible to automatically create non-existent color noises.

I’m thinking of using store and restore command to do this, but my idea with eq and compose_channels, I’d imagine it would be super slow.

Here’s a slow command that separates all the pixels, and then convert them to color.

s y s x remove_duplicates a x

Extended version

if w>1 s x fi if h>1 s y fi remove_duplicates a x
ww=w
repeat=15
rn=0
equality=0
alpha=0
if !$alpha to_rgb fi
do
do
chan_v1={round(u(0,255))}
chan_v2={round(u(0,255))}
chan_v3={round(u(0,255))}
chan_v4={round(u(0,255))}
{w},{h},100%,100%,$alpha?[$chan_v1,$chan_v2,$chan_v3,$chan_v4]:[$chan_v1,$chan_v2,$chan_v3]
+eq
equality={iM#-1} rm. r. 1,1
if !$equality a x else rm. fi
while $equality
rn+=1
while $rn<$repeat

I found some time to reply. Hope it helps.

By non-existent, do you mean for the entire image or for a given region (e.g., 1 or more pixels)? Depending on your criterion, you would need to approach it differently.

It would be more efficient if you could use builtin commands. colormap 0 would help you index all of the colours in an image. Then generate noise that contains colours that don’t belong to this index.

1 Like

I’m looking at trying to change my rep_frblur to use a better algorithm. The main problem is that blend alpha don’t really work on 5 channels and it’s hard to modify it so that it can work with CMYKA. Any idea where to start with? As of now, it is problematic because if I set duplicates to 200, there can be erm, issues. blend alpha doesn’t even give the same result.

I have a idea on using store image to do the job. Maybe that should give me a better result here.

First of all, you need to know what blend alpha does. It is the base blend with a parameter that controls how much A you get on top of B. You could easily do that yourself in G’MIC, Krita or GIMP.

I figured how it works. I have this proof of concept code which can be copied and pasted all over again. Source Over blending mode.

sh[-2,-1] 0,{s-2}
sh[-4,-3] {s-1}
#/[-2,-1] 255#
f[-4] "i*i0#-2*i0#-1+i*(1-i0#-1)+i#-3*(1-i0#-2)"
f[-2] "i*i#-1+i*(1-i#-1)+i#-1*(1-i)"
#*[-2] 255#
rm[-5--1]

Now, here’s something that makes me really confused.

#color_space,keep_original={ 0 = remove_original | 1 = keep_original },_duplicates_count>=2,_distance>0,0<=_angle<=360,0<=_boundary_conditions<=3,_interpolation={ 0=nearest_neighbor | 1=linear }#
initial_angle=270
distance=0.05
duplicates=5
incremental_angle={360/$duplicates}
impose={1?1}
duplicates+=$impose
max_alpha=255
adiv={$max_alpha*$duplicates}
nn=0
repeat $! l[$>]
    dist_hypo={$distance*sqrt(w^2+h^2)}
    if {s==1||s==3} 
        {w},{h},100%,100%,1/$duplicates a c
    else
        sh {s-1}
        /. $adiv
        rm.
    fi
    +store[0] fragment
    rep_sdaxy $dist_hypo,$initial_angle,2,1
    nn+=1
    restore fragment
    rep_sdaxy. $dist_hypo,{$initial_angle+$nn*$incremental_angle},2,1
    sh[0,1] 0,{s-2}
    sh[0,1] {s-1}
endl done

With that code, I noticed the last 2 “layers” (they’re not really layers as they’re shared) are not in 0,1 range. And yet, if I removed the part below fragment and use s c,-3 , I would note that the last channel is 0-1. So, did I ended up with a bug?

EDIT: Ok, last time I checked, {s-1} means last channel because of 0,1,2,3 in case of 4 channels image. Now, I fixed it by putting {s} instead. Now, I’m really confused as to why is this happening.

Are you getting any shared related errors? It won’t work in some cases such as with local and perhaps store. I don’t use shared much for that reason; it might not be stable. I would use it only on mature filters.

Nope. I’m just confused by the fact that I had to do {s} instead of {s-1}. 4 is outside of 0-3 range.