Reptorian G'MIC Filters

Made changes to Bit-Plane Shuffler. Now supports alpha as optional option. Also, code is easier to read, and it does scream micro-optimization fetish too, but good for learning how to use _persistent. rep_bitplane_shuffler has one more option which is about whether to target only color channels. It runs around 0.038 s for 6144x4110 for cli, and when you’re finished adjusting and exiting in gui, even less because of _persistent.

And that reminds me of the Magic Eye books and posters.

Perhaps, @Reptorian, that could be your next project (if you haven’t already done so - you are too prolific to follow completely - ha ha).

Probably more likely to take a break or just do small G’MIC thing like I did just now.

I added a feature to Lavander Binary Map. I added flip(v) function which basically flip bits. Code taken from here - Invert actual bits of a number - GeeksforGeeks . Ideally, it would use ~ instead, but that’s taken, and I don’t think anyone is using ~var.

Follow-up on this post: Reptorian G'MIC Filters - #835 by Reptorian

This actually can be multi-threaded, and can use similar technique to what I did to my combinations, permutation series. There may be a update to rep_find_factor_of after I compare time.

Looks like I solved this problem. I will push a update to rep_find_factor_of now that it is using prime factorization method. Of course, before that, I will have to run a few more test.

For comparison test:

C:\Windows\System32>gmic tic new_rep_find_factors_of 840000000000 toc
[gmic]-0./ Start G'MIC interpreter.
[gmic]-0./ Initialize timer.
[gmic]-0./ Elapsed time: 0 s.
[gmic]-0./ End G'MIC interpreter.

C:\Windows\System32>gmic tic rep_find_factors_of 840000000000 toc
[gmic]-0./ Start G'MIC interpreter.
[gmic]-0./ Initialize timer.
[gmic]-0./ Elapsed time: 0.043 s.
[gmic]-0./ End G'MIC interpreter.

EDIT: Test passed and new changes are pushed.

EDIT: Aw no, it fails on 777. :frowning: I’ll have to test the C++ code to see if it fails there too. No, it’s certainly the G’MIC code that fails, and I need to find why. Seem to be this close to doing so. And I can’t figure it out, and C++/G’MIC code comparison seem to check.

EDIT: Never mind. I just missed the last 7. Oof. Some more test, it will definitely fail with really large values. I’m not sure why, but I believe this is a precision issue. All tests other than really large values passed, but I do not know where I should put the limit on. Could be mitigated via c++ method though.

Here’s test case where it fails (it fails at points where there are really large numbers):

D:\Programs\G'MIC\gmic-community>gmic echo \n${rep_find_factors_of\ 1050100000}
[gmic]-0./ Start G'MIC interpreter.
[gmic]-0./
1,2,4,5,8,10,16,20,25,32,40,50,80,100,125,160,200,250,400,500,625,800,1000,1250,2000,2500,3125,4000,5000,6250,10000,10501,12500,20000,21002,25000,42004,50000,52505,84008,100000,105010,168016,210020,262525,336032,420040,525050,840080,1050100,1312625,1680160,2100200,2625250,4200400,5250500,6563125,8400800,10501000,13126250,21002000,26252500,32815624,42004000,52505000,65631248,105010000,131262496,210020000,262524992,525049984,1050099968
[gmic]-0./ End G'MIC interpreter.

Actual:

1, 2, 4, 5, 8, 10, 16, 20, 25, 32, 40, 50, 80, 100, 125, 160, 200, 250, 400, 500, 625, 800, 1000, 1250, 2000, 2500, 3125, 4000, 5000, 6250, 10000, 10501, 12500, 20000, 21002, 25000, 42004, 50000, 52505, 84008, 100000, 105010, 168016, 210020, 262525, 336032, 420040, 525050, 840080, 1050100, 1312625, 1680160, 2100200, 2625250, 4200400, 5250500, 6563125, 8400800, 10501000, 13126250, 21002000, 26252500, 32815625, 42004000, 52505000, 65631250, 105010000, 131262500, 210020000, 262525000, 525050000, 105010000

EDIT: Now, I understand where it fails. It fails because the math parser will return 1050100000 as 1050099968 which confirms that it is a precision issue. Guess I will have to find the limit by hand and I can’t figure that out.

I fixed the precision issue by staying within math parser, and outputting the result there instead of using image values. :slight_smile:

A few more doing this will solve everything here. Actually no, but this is good enough as it.

Test result:

C:\Windows\System32>gmic echo ${rep_find_factors_of\ 850000000000000}
[gmic]-0./ Start G'MIC interpreter.
[gmic]-0./ 1,2,4,5,8,10,16,17,20,25,32,34,40,50,64,68,80,85,100,125,128,136,160,170,200,250,256,272,320,340,400,425,500,512,544,625,640,680,800,850,1000,1024,1088,1250,1280,1360,1600,1700,2000,2048,2125,2176,2500,2560,2720,3125,3200,3400,4000,4096,4250,4352,5000,5120,5440,6250,6400,6800,8000,8192,8500,8704,10000,10240,10625,10880,12500,12800,13600,15625,16000,17000,17408,20000,20480,21250,21760,25000,25600,27200,31250,32000,34000,34816,40000,40960,42500,43520,50000,51200,53125,54400,62500,64000,68000,69632,78125,80000,85000,87040,100000,102400,106250,108800,125000,128000,136000,139264,156250,160000,170000,174080,200000,204800,212500,217600,250000,256000,265625,272000,312500,320000,340000,348160,390625,400000,425000,435200,500000,512000,531250,544000,625000,640000,680000,696320,781250,800000,850000,870400,1000000,1024000,1062500,1088000,1250000,1280000,1328125,1360000,1562500,1600000,1700000,1740800,1953125,2000000,2125000,2176000,2500000,2560000,2656250,2720000,3125000,3200000,3400000,3481600,3906250,4000000,4250000,4352000,5000000,5120000,5312500,5440000,6250000,6400000,6640625,6800000,7812500,8000000,8500000,8704000,9765625,10000000,10625000,10880000,12500000,12800000,13281250,13600000,15625000,16000000,17000000,17408000,19531250,20000000,21250000,21760000,25000000,25600000,26562500,27200000,31250000,32000000,33203125,34000000,39062500,40000000,42500000,43520000,48828125,50000000,53125000,54400000,62500000,64000000,66406250,68000000,78125000,80000000,85000000,87040000,97656250,100000000,106250000,108800000,125000000,128000000,132812500,136000000,156250000,160000000,166015625,170000000,195312500,200000000,212500000,217600000,244140625,250000000,265625000,272000000,312500000,320000000,332031250,340000000,390625000,400000000,425000000,435200000,488281250,500000000,531250000,544000000,625000000,640000000,664062500,680000000,781250000,800000000,830078125,850000000,976562500,1000000000,1062500000,1088000000,1220703125,1250000000,1328125000,1360000000,1562500000,1600000000,1660156250,1700000000,1953125000,2000000000,2125000000,2176000000,2441406250,2500000000,2656250000,2720000000,3125000000,3200000000,3320312500,3400000000,3906250000,4000000000,4150390625,4250000000,4882812500,5000000000,5312500000,5440000000,6103515625,6250000000,6640625000,6800000000,7812500000,8000000000,8300781250,8500000000,9765625000,10000000000,10625000000,10880000000,12207031250,12500000000,13281250000,13600000000,15625000000,16000000000,16601562500,17000000000,19531250000,20000000000,20751953125,21250000000,24414062500,25000000000,26562500000,27200000000,31250000000,33203125000,34000000000,39062500000,40000000000,41503906250,42500000000,48828125000,50000000000,53125000000,54400000000,62500000000,66406250000,68000000000,78125000000,80000000000,83007812500,85000000000,97656250000,100000000000,103759765625,106250000000,125000000000,132812500000,136000000000,156250000000,166015625000,170000000000,195312500000,200000000000,207519531250,212500000000,250000000000,265625000000,272000000000,312500000000,332031250000,340000000000,390625000000,400000000000,415039062500,425000000000,500000000000,531250000000,625000000000,664062500000,680000000000,781250000000,830078125000,850000000000,1000000000000,1062500000000,1250000000000,1328125000000,1360000000000,1562500000000,1660156250000,1700000000000,2000000000000,2125000000000,2500000000000,2656250000000,3125000000000,3320312500000,3400000000000,4250000000000,5000000000000,5312500000000,6250000000000,6640625000000,6800000000000,8500000000000,10000000000000,10625000000000,12500000000000,13281250000000,17000000000000,21250000000000,25000000000000,26562500000000,34000000000000,42500000000000,50000000000000,53125000000000,85000000000000,106250000000000,170000000000000,212500000000000,425000000000000,850000000000000

Really fast too.

D:\Programs\G'MIC\gmic-community>gmic tic rep_find_factors_of 850000000000000 toc
[gmic]-0./ Start G'MIC interpreter.
[gmic]-0./ Initialize timer.
[gmic]-0./ Elapsed time: 0.001 s.
[gmic]-0./ End G'MIC interpreter.

EDIT: Now it works with really large prime base.

To have fun:

gmic echo ${rep_find_factors_of\ 83333332460371979}

:smiley:

That’s over the limit to what is possible in G’MIC and current code. It doesn’t work with that number. I don’t know what’s the limit is, but certainly having to do with float number and the limit has to do with the largest possible difference which can be used to fix wrong number with dynamic array.

Removed last digit and got this:

D:\Programs\G'MIC\gmic-community>gmic echo ${rep_find_factors_of\ 8333333246037197}
[gmic]-0./ Start G'MIC interpreter.
[gmic]-0./ 1,163,241,39283,212135866559,34578146249117,51124743840719,8333333246037197
[gmic]-0./ End G'MIC interpreter.

EDIT: The limit seem to be around 5000000000000000 or close to 5 quadrillion (likely even lower, but that number was not found through trial and error). I pushed the limit now. It’ll mark a error after you get past that as the final number would likely not be the same as the input. That’s pretty big enough range to work with. The only realistic way of going bigger is well having double support for images as I had to bypass the limitation of float images.

To have fun with integers ± 9999999999999998 and ± 9999999999999997 … Limits?

gmic echo {9000000000000000+999999999999998}
gmic echo {-9000000000000000-999999999999998}

gmic echo {9999999999999997-1}
gmic echo {-9999999999999997-1}

:smiley:

The ranges that are allowed is 0-5000000000000000 inclusive. Likely, there’s a lower bound number in which the last number on the generated list of number always equal to its input. If the last number, then the bound is exceeded. For now, this is the known bound. The most fun number is 4043299481020800. It gives me 36864 numbers. It looks like:

1,2,3,4,5,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,34,35,36,38,39,40,42,44,45,46,48,49,50,51,52,54,55,56,57,58,60,62,63,64,65,66,68,69,70,72,75,76,77,78,80,84,85,87,88,90,91,92,93,95,96,98,99,100,102,104,105,108,110,112,114,115,116,117,119,120,124,126,128,130,132,133,135,136,138,140,143,144,145,147,150,152,153,154,155,156,160,161,165,168,170,171,174,175,176,180,182,184,186,187,189,190,192,195,196,198,200,203,204,207,208,209,210,216,217,220,221,224,225,228,230,231,232,234,238,240,245,247,248,252,253,255,260,261,264,266,270,272,273,275,276,279,280,285,286,288,290,294,297,299,300,304,306,308,310,312,315,319,320,322,323,325,330,336,340,341,342,345,348,350,351,352,357,360,364,368,372,374,377,378,380,384,385,390,391,392,396,399,400,403,406,408,414,416,418,420,425,429,432,434,435,437,440,441,442,448,450,455,456,459,460,462,464,465,468,475,476,480,483,490,493,494,495,496,504,506,510,513,520,522,525,527,528,532,539,540,544,546,550,551,552,558,560,561,570,572,575,576,580,585,588,589,594,595,598,600,608,609,612,616,620,621,624,627,630,637,638,640,644,646,650,651,660,663,665,667,672,675,680,682,684,690,693,696,700,702,704,713,714,715,720,725,728,735,736,741,744,748,754,756,759,760,765,770,775,780,782,783,784,792,798,800,805,806,812,816,819,825,828,832,833,836,837,840,850,855,858,864,868,870,874,880,882,884,896,897,899,900,910,912,918,920,924,928,930,931,935,936,945,950,952,957,960,966,969,975,980,986,988,990,992,1001,1008,1012,1015,1020,1023,1026,1035,1040,1044,1045,1050,1054,1056,1064,1071,1078,1080,1085,1088,1092,1100,1102,1104,1105,1116,1120,1122,1127,1131,1140,1144,1150,1152,1155,1160................................................26955329873472,27505438646400,27884824007040,28078468618200,28274821545600,28880710578720,29299271601600,29730143242800,29950366526080,30400747977600,30631056674400,31102303700160,31588277195475,32089678420800,32607253879200,33694162341840,33977306563200,34558115222400,34856030008800,35159125921920,35467539307200,36100888223400,36757268009280,37437958157600,38507614104960,38877879625200,39640190990400,40432994810208,40841408899200,41258157969600,42117702927300,42561047168640,43476338505600,43948907402400,44431862428800,44925549789120,45946585011600,46474706678400,47568229188480,48134517631200,50541243512760,51837172833600,52510382870400,53201308960800,53910659746944,56156937236400,57761421157440,58598543203200,59460286485600,61262113348800,62204607400320,63176554390950,64179356841600,65214507758400,67388324683680,69712060017600,70935078614400,72201776446800,73514536018560,74875916315200,77755759250400,79280381980800,80865989620416,82516315939200,84235405854600,87897814804800,89851099578240,91893170023200,96269035262400,101082487025520,103674345667200,106402617921600,112313874472800,115522842314880,118920572971200,122524226697600,126353108781900,130429015516800,134776649367360,139424120035200,144403552893600,149751832630400,155511518500800,161731979240832,168470811709200,175795629609600,183786340046400,192538070524800,202164974051040,212805235843200,224627748945600,237841145942400,252706217563800,269553298734720,288807105787200,311023037001600,336941623418400,367572680092800,404329948102080,449255497891200,505412435127600,577614211574400,673883246836800,808659896204160,1010824870255200,1347766493673600,2021649740510400,4043299481020800

Also, this is useful for grid-based filters. I made a filter a long time ago which is Image Dimensions Factors. So, if you want to make grid-based filter parameter to never resize the image, you use this filter to check which factors are available.

For example, for the flower image, this is the output:

Image Width: 640
Image Height: 600
Image Dimensions: 640x600

Factors of Width: 1,2,4,5,8,10,16,20,32,40,64,80,128,160,320,640
Factors of Height: 1,2,3,4,5,6,8,10,12,15,20,24,25,30,40,50,60,75,100,120,150,200,300,600
Factors of Width and Height: 1,2,4,5,8,10,20,40

Then I use Tiled Form and use 20.

This result into this:

image

The image dimension has not change when using new dimension.


Finally was able to replicate this bug and saving for later:

C:\Windows\System32>gmic echo ${rep_find_factors_of\ 25655000,135250200,3125000}
[gmic]-0./ Start G'MIC interpreter.
[gmic]-0./ 1,2,4,8
[gmic]-0./ End G'MIC interpreter.

C:\Windows\System32>gmic echo ${rep_find_factors_of\ {gcd(25655000,135250200)},3125000}
[gmic]-0./ Start G'MIC interpreter.
[gmic]-0./ 1,2,4,5,8,10,20,25,40,50,100,200
[gmic]-0./ End G'MIC interpreter.

This one is curious because there should be no reason why this should happen.


EDIT: Oh, I see what’s going on here. Another issue with double to float conversion as images ends in float. I guess a easy fix can be found.

I have made a new filter to solve this problem: Hide images and reveal effect with a red filter. - Paint.NET Discussion and Questions - paint.net Forum

The idea is that if you were to print this image, and then cover this with whatever really red and transparent plastic you have, you’d reveal another image:

If anyone wants to try and give me a photograph of this though as I don’t have a spare camera these day. You should get a result that looks like this:

A quick test reveal too much yellow, but the image is still revealed.

Looks to me like the same technique used in 3D anaglyph - one image in red channel, one in cyan. If you want to obscure the red channel content more, the cyan can be manipulated.

The technique was basically this:

  1. Convert 2 images into luminosity image. These images are Image 1, Image 2 respectively.
  2. Output as:
    – Channel Red: Image 1 - Normal
    – Channel Green: Image 2 - Normal
    – Channel Blue: Image 1 - Inverted

I think there can be a more scientific way of doing that, but I do not specialize in that.

Well, you could hide it maximally by equalizing luminance to begin with (although clearly patterns which break up edges will make it even better). Since red has a lower luminance than green, you still have room to add to the green channel afterwards (or blue).

gcd_hide_red_channel : check ${"is_image_arg $1"}
  pass$1 0 gcd_srgb2luma.
  repeat $!-1 l[$>,-1] {
    gcd_srgb2luma.. srgb2rgb..
    +mul[0] -0.2126729 add. 55 div. 0.7151522
    +f. 0 a[0,-2,-1] c
    rgb2srgb[0] sh[0] 1 m:=iM rm.
    ri. [0] gcd_srgb2luma.
    n. 0,{255-$m} j.. .,0,0,0,1,-1
  } done rm.

hiddenred

Edit: just to add, blue channel would be much easier to conceal due to very little luminance contribution

A combination of all channels would be ideal as the main goal is for the image to be revealed to the most possible.

I made a test image with blue channel added in by inverting the red channel and appending it.

new_red_acetone

This doesn’t work too well.

Also, I think the base idea can work with any hue in theory. But at that point, that comes down to math and lots of test and knowledge of human perception. It’s probably even possible to have slight color variation as well.

Other news:
Sep 14:
rep_find_factors_of has been fixed.
rep_aspect_crop_2d has been fixed.

Not much, but I’m working more on bug fix and refactoring anyway mostly. And those will be available once the update issue is resolved.

Sep 15:
File exporting palettes commands are fixed.

Perhaps you’re trying to get to a particular artistic look, but I was thinking more about obscuring in general mathematically.

I’m fairly sure equalizing luminance across channels for any red contribution will do most of that, with patterned edges doing the rest. Adding blue = inverse red after that’s been done only makes it visible again, you would need an unrelated blue channel. Perhaps I’ll do a filter as well, it is interesting!

1 Like

If this is artistic, then I could have made a billion “artistic” filters lol. Keep up the good work friends. I have been super busy so haven’t produced any wonderful things in eons.

Does anyone wants an aspect crop 3D tool? I’m not sure if this is needed, hence my asking.

Basically, a 3D version of this:

#@cli rep_aspect_crop_2d: _width_ratio>0,_height_ratio>0,-1<=_shift_factor[%]<=1
#@cli : Crop images based on specified aspect ratio.
#@cli : Code for finding new dimension was provided by Sumruv in discord/generative.
#@cli : Default value: 'shift_factor=0'
#@cli : Author: Reptorian.
rep_aspect_crop_2d:
skip ${3=0}

check "$1>0&&$2>0"

_aspect_crop_ratio_w,_aspect_crop_ratio_h,_arc2d_crop_shift_factor=${1-2},{(cut($3,-1,1)+1)/2}

if $_aspect_crop_ratio_w==$_aspect_crop_ratio_h
  m "cmd_arc_2d_crop :
    if w==h return fi

    if w>h
      start_point={int($_arc2d_crop_shift_factor*(w-h))}
      crop $start_point,0,{$start_point+h-1},{h-1}
    else
      start_point={int($_arc2d_crop_shift_factor*(h-w))}
      crop 0,$start_point,{w-1},{$start_point+w-1}
    fi
    "
else

  _arc2d_crop_ratio={$_aspect_crop_ratio_h/$_aspect_crop_ratio_w}

  m "cmd_arc_2d_crop :
    ratio={h/w}

    if $ratio==$_arc2d_crop_ratio return fi

    new_dim,mode={b=[w,h];aspect_ratio=$_arc2d_crop_ratio;ny=min(b[0]*aspect_ratio,b[1]);ny<b[1]?[round(ny),1]:[round(b[1]/aspect_ratio),0];}

    if $mode
     start_point={int($_arc2d_crop_shift_factor*(h-$new_dim))}
     crop 0,$start_point,{w-1},{$start_point+$new_dim-1}
    else
     start_point={int($_arc2d_crop_shift_factor*(w-$new_dim))}
     crop $start_point,0,{$start_point+$new_dim-1},{h-1}
    fi
    "
fi

foreach { cmd_arc_2d_crop }

um cmd_arc2d_crop

I’m just gonna leave this note to stimulate blend_cmyka for the future:

s[0,1] c,-$nb_col_channels

if $is_alpha_b # Background has alpha

    _$0_$mode[0,2]
    
    if $is_alpha_f # Foreground has alpha
        *[0] [1] /[0] 255 j[0] [2],0,0,0,0,1,[3],255 # Co = Cf*Af + Cb*Ab*(1-Af)
        +f. 255 j[1] .,0,0,0,0,1,[3],255             # Ao = Af + Ab*(1 - Af)
        k[0,1] +max. 1 /. 255 /[0,-1] a c            # [ Co/Ao, Ao ]
    else j[0] [2],0,0,0,0,1 rm. f. 255 a c           # Foreground has no alpha
    fi
    
else # Background has no alpha

    _$0_$mode[0,1]
    
    if $is_alpha_f j[0] [1],0,0,0,0,1,.,255 k[0] # Foreground has alpha
    else k[1]                                    # Foreground has no alpha
    fi
    
fi

Also, thinking of doing blend with offset as option. At least the current blend is way easier to read than the earlier version.

Ok, I have a update, I’m on the final stage of updating Photomosaic. I’m not sure if it is going to be slower than the old one, but it’s looking good so far. There will be new features such as rgb/yuv color support, better method of alpha cropping, and methods of mapping tiles onto image. For color support, I was thinking of attempting to support CMYKA, but decided to make a error to point is as a developmental feature as it’s a little hard to make the new version. Right now, I’m taking my time, and it’s way more readable than the old version too.

Ok, here’s a bit of preview of new version of Photomosaic: It is also faster than the old one. .189 s (New) vs. .251 s (old).

The new version will allow users to handle how they want alpha cases to be handled. It will also support odd case like CMYKA (but I won’t support this too much). It will also automatically convert color space too. You can even determine how alpha tile images would be resized or cropped then resized. So, basically, it is flat-out flexible.


Looks like CLI version is done for the generation part. I just gotta rearrange user input order. Next up is GUI to finish up and release a better Photo-Mosaic. Hmm, very tough problem.


Update on this, I had managed to finish the CLI part. All that is left to do is to do the GUI part, and I’m calling it done.


Another update: It appears to be coming along though I can’t really finish the code with 3.1.6 on Krita, and 3.2.0 on Paint.NET. However, I’m doing what I can with the GUI part as I’m factoring into _persistent variable for the GUI version. The GUI code is like a fork of the CLI code, but with _persistent and GUI temporary variables to be assigned into, and a slight different behavior due to the previously mentioned things. There’s also planned use of to_automode to match CLI behavior too. Thanks @David_Tschumperle


Final update before any update for 3.2.0. I am finished with the parts where _persistent has not been applied. That means that all I can do is to wait so I can proceed to finish it up.

1 Like

You may have or have thought of this already. It would be cool if we could randomly transform the sprites to add some variety. I know how you like complexity. :wink: