Reptorian G'MIC Filters

I’ll wait for David to see what he has to say about this bug. I’ll use a temporary set of code which is this line:

  v=crop(#0,x,0,0,0,1,height,1,1,0);
  n=carry_over+sum(crop(#0,x,0,0,0,1,height,1,1,0));

And it works. I have to do crop(#0,x,0,0,0,1,height,1,1,0); twice to get the correct result. No wonder my frustration.

I finished Tupper’s Self Referential Formula as a new showcase filter. Showcase here means to demonstrate capability of G’MIC as it’s not useful outside of that and it’s a fun filter too in terms of coding it in as there were challenges like the absence of BIGINT support. To be fair, BIGINT support would make this filter run much faster, and would work with images 300x300 well, and I’m not thinking of BIGINT support in content of math parser, but in content of ('create_string_here').

I have some ideas for that like specialized commands such as bigint_hex2dec,bigint_dec2bin,bigint_bin2dec,bigint_add,bigint_sub, and all of them parse a image as if they’re string, then output a image as if it was a string. But none of them would be used on math parser.

Now I am remaking a filter. It was made by @Joan_Rake1. I am now in the process of extending it.

image

Not much news, but I made a little command which converts a large integer number into base 16,777,216 as a image. This allows to do things similar to bigint library.

$ +rep_num2base_float_max 56525845877585816763039586007520750277353196450595841567735618780688400140898024981743696598491218713015714928398271962117249251816126135758313291996549277852226925632342583919395030421983352656778405325777741906072873874481412543269713885225217255170734791425252274534182128499770100304909062813395973629729728331022409858974448530410675416671693127285242093542682941391314786490816144814610513955188130873521380296068200591469100034890490542735132321279502689903923668808556530273882231399913969596693343635681966013405787571940000044023807 echo {crop(#-1)}

The following command creates a image with these values:

131071,4162048,3375332,9705540,83968,800,3145728,1605872,6,4194528,6,7936,8388608,262145,14680064,2097183,17920,5767184,131073,2040,1597440,3840,2031616,10240,112,114688,640,7,6144,7340040,8192,448,65536,512,16646144,131073,8389792,1212416,8396800,127,3584,100,126976,0,2228225,303106,2624,25,2097120,4595712,3313735,344,762,1048564,24576,1836848,2032,1032192,4608,3145764,0,4194496,294914,1536,3670016,2048,2097376,8634368,16711680,1023,8704,2097192,0,8135840,13273173

And according to Python, it checks out after comparing numbers.

v=[131071,4162048,3375332,9705540,83968,800,3145728,1605872,6,4194528,6,7936,8388608,262145,14680064,2097183,17920,5767184,131073,2040,1597440,3840,2031616,10240,112,114688,640,7,6144,7340040,8192,448,65536,512,16646144,131073,8389792,1212416,8396800,127,3584,100,126976,0,2228225,303106,2624,25,2097120,4595712,3313735,344,762,1048564,24576,1836848,2032,1032192,4608,3145764,0,4194496,294914,1536,3670016,2048,2097376,8634368,16711680,1023,8704,2097192,0,8135840,13273173]
vn=0
base=1<<24
num_mult=1
for n in v:
    vn += n*num_mult
    num_mult *= base
    
print(vn)

Yes, digits are reversed though.

Any news on the modf fix I wonder?

I have looked a bit into refactoring, but I have not yet solved it. So, I will let you know when it’s ready.

This is my current progress
#@cli modular_formula : operation,max_channel_value={ float_value | [image] },channel_values={ float_value(%) | [image] }
#@cli : Apply modular formulas into selected images. 'channel_value' can be values outside the channel ranges of image.
#@cli : When using a image argument to max_channel_value, the dimension should be equal to the spectrum of target images.
#@cli : When using a image argument to channel_value, it can be single spectrum or equal to the spectrum of target images.
#@cli : (eq. to 'modf').
#@cli : operation can be { 0=modulo | 1=modulo_continuous | 2=divisive | 3=divisive_continuous | 4=additive | 5=additive_continuous}
#@cli : In addition, they can be the corresponding string as argument.
#@cli : Author: Reptorian.
modular_formula_new:
if isint($1)
 modular_mode={int($1)%6}
else
  modulo,modulo_continuous,divisive,divisive_continuous,additive,additive_continuous=0,1,2,3,4,5
  modular_mode=$$1
  if !narg($modular_mode) error invalid_input fi
fi

max_images_index,utilize_max_channel_image,utilize_channel_values_image={$!-1},0,0

if ${is_image_arg\ $2} pass$2 1 name[-1] max_channel_image fi
if ${is_image_arg\ $3} pass$3 1 name[-1] channel_values_image fi

fill[0-$max_images_index] "begin(
  const modular_mode=$modular_mode;
  const epsilon=.00000000000000000000000001;

  if($utilize_max_channel_image,
   const max_channel_reference=$max_channel_image;
   s#max_channel_reference>1?(
    const max_channel=i(#max_channel_reference,0,0,0,0);
    const max_channel_mod=+epsilon;
    0;
   ):(
    max_channel=crop(#max_channel_reference)+epsilon;0;
   );
  ,
   const max_channel=$2+epsilon;
   0;
  );
  
  if($utilize_channel_values_image,
   const channel_value_reference=$channel_values_image;
   dividier()=max_channel/I(#channel_value_reference);
   modular_mode==0?( modular_output()=(I*dividier())%max_channel_mod;
   ):
   modular_mode==1?(
   ):
   modular_mode==2?(
   ):
   modular_mode==3?(
   ):
   modular_mode==4?(
   ):(
   );
   0;
  ,
   const dividier=$3;
   modular_mode==0?(
   ):
   modular_mode==1?(
   ):
   modular_mode==2?(
   ):
   modular_mode==3?(
   ):
   modular_mode==4?(
   ):(
   );
   0;
  );

 );
 I;
 "

keep[0-$max_images_index]
1 Like

No problem, what does ‘dividier’ mean? (I don’t understand any of this tbh) Typo (should it be ‘divider’)? Anyway, wishing you well.

Done via a python script to produce a textfile which I then feed into windows cmd (maybe there’s an easier purely gmic way?) and made into this^^
Using not one but two Reptorian filters… !

start = [35.1,113.9,0.3,50,50,1,1,1,1,0,1,0,0,1,1,1,2,1190,0,50,50]
end =   [486.05,0.418848,85.3073,50,50,0.793,2.684,2.189,0.239,0,1,0,0,1,1,1,2,3895,0,50,50]

start_fx = [2,1,0,72.6415,99.6269,0,0,1,2,0,1,0.5,5]
end_fx =   [2,1,39.6,10.587,36.9403,0,0,1,2,0,1,1.401,5]

num_steps = 268
step_size = [(end[i] - start[i]) / (num_steps - 1) for i in range(len(start))]
step_size_fx = [(end_fx[i] - start_fx[i]) / (num_steps - 1) if isinstance(start_fx[i], (int, float)) and isinstance(end_fx[i], (int, float)) else 0 for i in range(len(start_fx))]

with open("gmic_commands_001.txt", "w") as file:
    for i in range(num_steps):
        params = [start[j] + i * step_size[j] for j in range(len(start))]
        params_fx = [start_fx[j] + i * step_size_fx[j] if isinstance(start_fx[j], (int, float)) else start_fx[j] for j in range(len(start_fx))]
        params_str = ",".join(str(int(x)) if int(x) == x else str(x) for x in params)
        params_fx_str  = ",".join(str(int(x)) if int(x) == x else str(x) for x in params_fx)
        command = 'gmic v -99 19a2.png rep_sqrlogpindis_gui {} gui_rep_polkal {} normalize 0,255 o out_{:04d}.png\n'.format(params_str, params_fx_str, i)
        file.write(command)
2 Likes

Cool!

Probably. @Reptorian could probably guide you through that.

1 Like

I would have to get back to you on the python thing. I’ll have to understand the code first even though I know Python myself. And yes, there’s a G’MIC approach to doing that.

That being said, I did not reply to you for that reason. I replied to notify you that I made fixes to modf.

There’s new feature for it for CLI users though. And it is faster as well.

The new feature for cli users is how it parses arguments. The command itself tried to find the optimal optimization.

Valid example #1

$ sample +fill [40,50,120] modular_formula[0] divisive_continuous,255,[-1] rm.

Valid example #2

$ sample modular_formula[0] 4,255,85

Valid example #3

$ sample cat rgb2hsv (360,1,1) modular_formula[0] 3,[1],40% rm. hsv2rgb

Here’s the G’MIC way of doing your Python script:

19a2.png 
steps=268 

(35.1,113.9,0.3,50,50,1,1,1,1,0,1,0,0,1,1,1,2,1190,0,50,50^486.05,0.418848,85.3073,50,50,0.793,2.684,2.189,0.239,0,1,0,0,1,1,1,2,3895,0,50,50) 
(2,1,0,72.6415,99.6269,0,0,1,2,0,1,0.5,5^2,1,39.6,10.587,36.9403,0,0,1,2,0,1,1.401,5) 

fill[-2,-1] "begin(const steps=$steps;);v=I;v[1]-=v[0];v[1]/=steps;v;" 

split[-2,-1] c 
name[-4--1] sqrlogpin_vars,sqrlogpin_step,polkal_vars,polkal_step 

repeat $steps { 
 +rep_sqrlogpindis_gui[0] {crop(#$sqrlogpin_vars)} 
 gui_rep_polkal[-1] {crop(#$polkal_vars)} 
 add[sqrlogpin_vars] [sqrlogpin_step] 
 add[polkal_vars] [polkal_step] 
} 

remove[0-$sqrlogpin_step]
output movie.mp4
1 Like

Nice!
I tried naming your gmic script test.gmic, I ran ‘gmic test.gmic’ in cmd, 17 minutes later - nothing so far…
except 18 minutes in and:

[gmic] *** Error in ./_main_/ *** Command 'output': [instance(270,512,0000016857577f88)] gmicList<float32>::save_ffmpeg_external(): Invalid instance dimensions for file 'movie.mp4'.
[gmic] Command 'output' has the following description:

  output (+):
      [type:]filename,_format_options

    Output selected images as one or several numbered file(s).
    (equivalent to shortcut command 'o').

    Default value: 'format_options'=(undefined).

what could that be? I don’t know whether gmic calls ffmpeg, or what, to make the mp4 file, perhaps I need that in the gmic cli folder??
Anyway it certainly seems somewhat easier, code-wise, than my python effort! :slight_smile:
Good to hear about your modf efforts, I just went to use your ‘Attractor’ filter and got an error in the cli (*first time), it simply says:

[gmic] *** Error in ./ *** narg($13)<13==F

My bad, there was a bad code. Replace remove[0-$sqrlogpin_step] with remove[0-$polkal_step], and then it will work.

Alternatively:

19a2.png 
steps=268 

(35.1,113.9,0.3,50,50,1,1,1,1,0,1,0,0,1,1,1,2,1190,0,50,50^486.05,0.418848,85.3073,50,50,0.793,2.684,2.189,0.239,0,1,0,0,1,1,1,2,3895,0,50,50) 
(2,1,0,72.6415,99.6269,0,0,1,2,0,1,0.5,5^2,1,39.6,10.587,36.9403,0,0,1,2,0,1,1.401,5) 

fill[-2,-1] "begin(const steps=$steps;);v=I;v[1]-=v[0];v[1]/=steps;v;" 

split[-2,-1] c 
name[-4--1] sqrlogpin_vars,sqrlogpin_step,polkal_vars,polkal_step 

start_index:=$!

repeat $steps { 
 +rep_sqrlogpindis_gui[0] {crop(#$sqrlogpin_vars)} 
 gui_rep_polkal[-1] {crop(#$polkal_vars)} 
 add[sqrlogpin_vars] [sqrlogpin_step] 
 add[polkal_vars] [polkal_step] 
} 

keep[$start_index--1]
output movie.mp4

As far as Attractor goes, that is in need of a update. Which I have to do after series of other updates I want to do first.

1 Like

That works great, gmic language seems pretty intuitive but I’m not suggesting it’s easy to learn! (certainly not for me that’s for sure…)
The video produced via gmic was a bit rough, but I suppose it was using default options, so I changed the last line to:

output movie.mp4,_24,_avc1

…which helped quite a lot,

output movie.mov,_24,_ap4h

…helped even more.

I wonder if there’s a way to control for pixel format like in ffmpeg (yuv444p, yuv422p … etc) or is that down to the codec implementation?
If I wanted to produce an image sequence instead what would be the correct command?

Anyway, thanks for all your hard work and help, I’m off to experiment! :slight_smile:

Small update:

Photographic Mosaic GUI filter is currently on work. It’s quite a difficult rewrite. I’d put on 3/10 in difficulty where 9/10 means it’ll take a decade to do for most people. Bad scale, I know, but 3/10 is very difficult. But, am getting there. The CLI version has been completed in terms of rewrite, and everything works including CMYKA mode support.

Color Modulo Texture has been fixed after forgetting to change some code due to new modf syntax.

Modulus Operation is disabled pending update.

Three-Coupled Oscillator has been repaired.

Also, repaired Cascading Self-Glitch in joan_rake work. A lot of her work needs a rewrite. This one too to fix things, I only fixed broken things related to my own changes, nothing else.

1 Like

Ok, here’s some snapshots of the Photographic Mosaic GUI filter:

Exhibit A


Exhibit B
image

Exhibit C
image

Exhibit A displays the images to be stored in persistent memory. Having all of those stored in persistent memory would allow the user to make changes without having to load images all over again and do unnecessary processing.

Exhibit B demonstrates that tiles are placed dependent on the color of pixels with alpha>0. In addition, you can tell that it isn’t just simple down-scaling. The algorithm when downscaling pixel has taken pixels with [0,0,0,0] into account, and eliminates that issue entirely in all cases.

Exhibit C demonstrates that it is transparent.

@afre , and @garagecoder :

I know you both talked about ordering images by indexes before. I pushed the best solution I can think of. I found that “dream algorithm”, but couldn’t have put it into code before.

1 Like

@David_Tschumperle Any more 3d shape_ commands? I actually think it may be feasible to do 3d version of ‘rep_form_pixels’ though with some caveats like no dual coloring per tile.

Figured out how to do weighed color average, and added a few more features to Picture Mosaic which has yet to be finished.

EDIT:


Improved indexing approach.

1 Like

The above was a example of weighed color average and all channels indexing. I have further improved the Picture Mosaic with regards to multiplication of alpha over the previous one by considering weighed multiplication, so that the tile will be appropriately multiplied by the correct value.

New Formula:

alpha_tile*=mini_tile_alpha>=palette_alpha?1:mini_tile_alpha/palette_alpha;

Old Formula:

alpha_tile*=mini_tile_alpha_relative_value;

The old formula is the alpha value of mini tile used to map into larger image. And it’s relative, so it’s alpha_value/maximum_alpha_value.

See how the new formula is a massive improvement to old formula? The outline of the blurred cupid is a lot more clear, and less faded out. You can still see that it fade alpha on the new formula which is intended for the parameter used for this test.