Reptorian G'MIC Filters

I have added Projects to my g’mic-community fork. I’ll put things to do there.


@bazza Does Autofill Coloring Book crash with you using this image?

1 Like

images as an example?

No, just confirming if the image crash G’MIC. @nrcarla reported that the image crash Autofill Coloring Book. I wonder if it also crash one of the Colorize made by @David_Tschumperle which is similar to Autofill Coloring Book on @nrcarla end.

This image works well.

Checked with several builds, it was crashing on that single build.
I built that again and now the filter seems to be working perfectly.
Sorry for the false alarm.

1 Like
repeat $! l[$>]
    +to_gray /. 5
    f.. "begin(val=0;);
    off=abs(round(i(#-1,x,y,z,0)));
    if(off,
    for(xx=off*-1,xx<=off,xx++,
        for(yy=off*-1,yy<=off,yy++,
            val+=j(xx,yy,0,0,0,1);
        );
    );
    val/=sqr(off*2+1);,i
    );
    "
    rm.
endl done

Made this command which average blur depending on pixel values. Is anyone interested in this? I didn’t use crop here because I don’t see boundary condition, and strictly positive only.

A box filter with per pixel kernel size? Hmm I wonder if there’s a quicker way…
By the way, is that correct to only set val=0 for the first pixel?

No, it’s not correct to set on first pixel. That’s the only thing that needs to be changed asides from using a theoretical faster way.

Yeah, there is probably a faster way to do it. I asked @David_Tschumperle about this. I wanted a guassian blur version as well. And yes, this is box filter based on pixel luminosity.

In that case I’ll have a think. Per pixel convolution kernel would be nice too but probably slow (and a memory hog) :slight_smile:

Edit: tomorrow at the earliest, got to sleep now!

Some random ideas that could work (no code):
use a constant size kernel and discard e.g. use crop()
iterate boxfilter per kernel size
trade off by using ram and just product vectors

I suggest you do idea #1 to show @Reptorian how to use crop(). :wink:

BTW, what does the asterisk of off* mean?

Crop only allows positive integer. The asterisk is multiply by.

LOL, I was reading too much into it as some programming thing.

Seems like looping a boxfilter is fast enough most times (just keep the loop instructions minimal):

#@cli gcd_boxfilter_local : [image]
#@cli : gcd_boxfilter_local all selected images with the specified image argument.
gcd_boxfilter_local : check ${"is_image_arg $1"}
  pass$1 0 r. {0,[w,h,d]},100%,0 round. 1 abs. store. arg_img
  repeat $! l[$>]
    {[w,h,d,s]} i $arg_img
    repeat iM+1
      +eq[2] $> +boxfilter[0] $>
      j[1] .,0,0,0,0,1,.. rm[-2,-1]
    done k[1]
  endl done

gmic sp +mirror. x div. 4 gcd_boxfilter_local.. .

Edit: also works fine changing boxfilter for blur:

1 Like

I have tested it. My result is more accurate, however, yours is much faster. Here’s the XOR test.

I don’t know how to get the result nearly exactly the same, but I can only get it close enough to look similar, but obviously different. So, I can’t say for sure.

However, yours is more flexible, I think I’ll stick with gcd_boxfilter_local.

For reference, this was my latest version of my code.

repeat $! l[$>]
    +to_gray
    f.. "
    val=0;
    off=abs(round(i(#-1,x,y,z,0)/2));
    if(off,
    for(xx=off*-1,xx<=off,xx++,
        for(yy=off*-1,yy<=off,yy++,
            val+=j(xx,yy,0,0,0,1);
        );
    );
    val/=sqr(off*2+1);,i
    );
    "
    rm.
endl done

Curious: How do you know? Because the math interpreter uses more sigfigs?

I’m assuming that, yes as well as the fact that my code copy values per every pixels one-by-one, and return the result. If I had to make changes to my own code. I would probably create a multithreaded version, but that would be difficult. Not impossible though.

Another curiosity is why you aren’t programming at a lower level. Clearly, you know enough to do that. I mean code that compiles, which would be much faster.

Well, three reasons.

  1. Don’t feel like I’m ready.
  2. I do spend my time on other things like drawing and 3D modeling. I actually do NURBS modeling. I don’t share my work publicly.
  3. Insomnia.

Yup that makes sense, because I think boxfilter itself is approximate. If you switch it for blur in true gaussian mode it probably gets as accurate (assuming you make a gaussian version), but possibly quite slow too.

Edit: forgot to mention, the loop version will handle multi channel kernel masks (which is how I was testing it). You need to ensure single channel for a true comparison (I guess you noticed that).

Yes, I noticed. By the way, I just realized that there could be variable per-pixel convolution. If you assign an arbitrary function to determine the convolution kernel, in theory, you could make variations of per-pixel convolution.