Reptorian G'MIC Filters

Since the equation to solve is transcendental, it is highly unlikely there will be a simple solution.

1 Like

He does have the habit of entering transcendental planes.

1 Like

Yep, and often sometimes knowingly I might make a mistake or it’s a subject way out of my league. Like forgetting to save negative overload function which actually makes the thorn fractal more interesting, I ended up just leaving what I got there which points to that direction knowing it may not be solved but still does the description. This spiral distortion case is way out of my league it seems.

Maybe later…


12/12/2020: I found a new algorithm for Fragment Blur in case of alpha channel with variance. I think there might be a issue there, but honestly I doubt it.

EDIT: Just checked, no issues. New algorithm worked as expected.


I just had upgraded rep_form_pixel and its gui filter Tiled Form!

New features : Inherent color space conversion support, and z-convolution.

z-convolution options are used to boost contrast of tiles. Color space conversion option enables users to use other color space while minimizing artifacts.

New filter! Dynamic Contrast. It is pretty fast as well as I optimized it even though it doesn’t need it. Lowest time is 0.005 s.

2 Likes

I made some bit of changes to blur[splinter] in hope of optimizing it. It didn’t work.

However, I must ask though:

@David_Tschumperle How come periodic wrap around in convolve_fft is so much faster than other wrap-around. With periodic wrap-around, the splinter blur is over 3 times faster.


Okay, it looks like I found negative overload feature for Thorn Fractal. Maybe it’s not the same as before, but a test shows that it does indeed work as expected (two different results for positive and negative overload). I pushed it in hope that it enables even more fractals. Now this feature I found before, and lost it won’t haunt me anymore.

If you are talking about boundary conditions, fourier space already has a periodic effect.

1 Like

Just a small update. It seems that I had managed to optimize almost every filters I had made. Just in time to do them all for New Year or maybe not all as some don’t need it even though it could use them. I figured out how to optimize rep_sptbwgp thanks to permute, and knowing what it does. It is quite a interesting technique to optimize filters using large number of channels and that is how I optimized Popcorn Fractal i.e using large number of channels.

2 Likes

Okay, recently I think I fixed the rep_axis_streak_algorithm after the github update. However, afre_compare doesn’t tell me which is correct implementation of my idea. The new algorithm or the old algorithm before github update? The idea is to smudge along axis and increasing alpha.

Maybe @afre can help shed some light on this. I been using afre_compare, and a z to compare, and yet the result doesn’t match the right.

Left : Original without alpha. Middle Left : New algorithm Middle Right: Old Algorithm before github update Right: Difference

EDIT: Turns out that the max difference is max = 6.10352e-05. I don’t think I need to fix the new algorithm at all.

Depending on the calculations, differences can be up to e-05. It also depends on what your metric is; e.g. subtraction vs content aware.

The metric I used to verify the level of difference is abs(new-old). The greater the number, the worse it is. I ended up using something else other than the original formula. The streak looks smoother now.

I use PSNR because that is available. Would have preferred SSIM and derivatives but it would be annoying to code. I also do DE (with Jzazbz), now that it is available but it isn’t that dissimilar to PSNR, which is much faster. Of course, there are other measures such as MAD and custom ones.

Hmm, noticed. That being said:

I finally upgraded Axis Streak. It is much faster than before. Took a while to rewrite those. Just the Chirikov-Taylor is left as a must optimize. Don’t care for the others that are slow as they’re not that useful like Vibrato for one.

There’s also the Reverse Engineer Gradient Map filter, but I don’t know how to optimize it. I’ll figure that out.

I have a hard time understanding what it does, but the core algorithm could be like histogram?

Here’s the pseudo-code:

  1. Have a color image.
  2. Have a gray image.
  3. Both must have the same dimension.
  4. Create a strip of values representing the grays. So, in case of 8-bit gray, that’s 256,1,1,(number of channel of color image)
  5. Loop along x-axis and y-axis within the gray image. When value is at a number from 0-255 (in case of using 8-bit gray. Add that to x position (x-position is equal to found value) to strip. Each time the value is found, add the occurance.
  6. Divide the strip by occurance of value.

It does sounds very like histogram 256 to me - would it not do the same? I don’t think I understand the end goal though!

See this picture:

The right image is the end goal. Histogram 256 does not do the same.

Ah I see, so your step 5 adds a value from the same position from the colour image. In that case, it’s much more similar to colormap 256,0,1

Some other related commands:

map
index
warp
equalize
autoindex
quantize

Yep. I don’t think there’s a way I can optimize it. This is basically the code for rep_regm which reverse engineer gradient map. I think there’s gotta be a way to do the eval ${-math_lib} and do it via parallel.

#@cli rep_regm: eq. to 'rep_reverse_engineer_gradient_map'. : (+)
rep_regm: rep_reverse_engineer_gradient_map $*
#@cli rep_reverse_engineer_gradient_map: _array_size>0
#@cli : The array size is used to define the depth of gradient map, if you're using float, then you need to scale image to something higher than 256. The only instruction is to have two images of same width and height dimension with the first one being a grayscale image.
#@cli : (eq. to 'rep_regm').\n
#@cli : Default values: '_array_size=256'\n
#@cli : Author: Reptorian.
rep_reverse_engineer_gradient_map:
skip ${1=256}
if $!!=2 v + e "Only 2 images are acceptable!" v - fi
if w#0!=w#1||h#0!=h#1 v + e "Dimensions do not match!" v - fi
if s#0==3||s#0==4 if !{(i0==i1)&&(i1==i2)} rgb2hsl8.. channels.. 2 else to_gray.. fi #Lightness is at least continuous all-around within RGB model, hence why this is used.#
elif s#0==5 s c.. -3 rm.. cmyk2rgb.. rgb2hsl8.. channels.. 2 #Extracting Lightness from CMYKA model#
elif s#0==2||s#0>5 channels.. 0
fi
if im#-2<0 -.. {im#-2} fi
f.. round(i)
$1,1,1,{s#-1}
eval ${-math_lib}"
 const ar = $1 ;
 for(v=0,v<ar,v++,
   p=0;
   for(xx=0,xx<w#0,xx++,
    for(yy=0,yy<h#0,yy++,
     if(i(#0,xx,yy)==v,
      I(#2,v)+=I(#1,xx,yy);
      p+=1;
     );
    );
   );
   if(p,I(#2,v)/=p);
  );
"

Also, why does this not work?

{$mv},1,1,1,"begin(basecrop=["$cropinfo"];);
sum(basecrop==x);
"
#cropinfo is a whole crop of black and white image#

You can avoid looping over every value and use built-in image looping by replacing the end like this:

round.. 1
$1,1,1,{s#-1} $1,1,1,1
f[0] "i[#-1,i]+=1;I[#-2,i]+=I(#1,x,y,z);i"
+eq. 0 add[-2,-1] div[-2,-1] # avoid div by zero

The method there is to build two images during the loop rather than one - the second is a histogram to divide by. That also replaces the fill to round values with native round.

For your second question, we probably need to see an example of what might be in $cropinfo or how it is set.

Edit: just to demo how histogram can do the same thing

round.. 1
$1,1,1,{s#-1}
f[0] "I[#-1,i]+=I(#1,x,y,z);i"
+histogram[0] $1,0,255
+eq. 0 add[-2,-1] div[-2,-1]

Amazingly that works so well.

C:\Windows\System32>gmic sp cat +to_gray rv tic new_rep_regm 256 toc
[gmic]-0./ Start G'MIC interpreter.
[gmic]-1./ Input sample image 'cat' (1 image 600x550x1x3).
[gmic]-1./ Force image [0] to be in GRAY mode.
[gmic]-2./ Reverse positions of images [0,1].
[gmic]-2./ Initialize timer.
[gmic]-3./ Elapsed time: 0.022 s.

I think I will work from it as a base and see how I can fill in the missing value as well as looping along multiple image and convert them to gradient.

The second question, I learned that it doesn’t support == or !=, but it will support >, and <. I wonder if @David_Tschumperle can address that limitation of the math parser in gmic.

EDIT: I never realized that fill can access outside images and fill them in. Interesting. I must experiment with that actually.

EDIT:

new_rep_regm:
round.. 1
$1,1,1,{s#-1} $1,1,1,1
f[0] "i[#-1,i]+=1;I[#-2,i]+=I(#1,x,y,z);i"
+f. i!=0
+eq. 0 add[-3,-2] div[-3,-2] # avoid div by zero
inpaint_pde.. .
k..

This works to find gradient map of image.

1 Like