Photo Mosaic with G'Mic

And using patchmatch can not look for morphological resemblance (?)

I tried that, didn’t understand how it works, so I’ll just continue with this approach.

I only use this, but short pieces of the image:

gmic sample cat sample apples +patchmatch[0] [1],64,64,1,1,1 fx_posterize[2] 800,0,0,4,64,0,0,0,50,50 +warp[-2] [-1]

EDIT : Never mind, it didn’t work at all. :frowning:

I’ll try to find out another way, but this is definitely difficult to code.

I do not know if it’s useful, here’s an example of positioning and blending.

# example blending

# Gmicky 2w*1h
rm[0]
fx_gmicky 2
resize[-1] 200%

# variables
Color_Tolerance=10
Maximum_Number_of_Output_Layers=2
Minimal_Area_PourCent=8
Autocrop_Output_Layers=0
W_Origine={w}
H_Origine={h}
# 2 layers
quantize[-1] $Maximum_Number_of_Output_Layers
fx_split_colors[-1] $Color_Tolerance,$Maximum_Number_of_Output_Layers,$Minimal_Area_PourCent,$Autocrop_Output_Layers
to_rgba[-1,-2]
# Gmicky rgb
+fx_gmicky 0
to_rgb[-1]
# where you want to see Gmicky
expand_x[-1] {abs({$W_Origine-{w}})/2},0 
expand_y[-1] {abs({$H_Origine-{h}})/2},0
# blend alpha
blend[-1,-2] alpha

rv[-1,-2]

I did just found the solution, to creating photo-mosaic, but the result are atrocious, but it works nevertheless.

#@cli rep_lbchstatfunc_to_pal: (eq. to rep_layers_by_channel_statistical_function_to_palette)
rep_lbchstatfunc_to_pal: rep_layers_by_channel_statistical_function_to_palette $*
#@cli rep_layers_by_channel_statistical_function_to_palette: variable
#@cli: Converts layers to palette using statistical function by channels per layers into 1x1 tile, then append them.
rep_layers_by_channel_statistical_function_to_palette: to_rgb rep_bchstatfunc $1 a x

#copy and paste below into code filter in g'mic, and copy and paste above to somewhere where you can remove it when not needed#
v=5
te={w<h?$v/w:$v/h}
to_a
at[0] "rep_bchstatfunc ia,0",{$te*w},{$te*h} r[^0] {$te*w},{$te*h},1,4,5 r[^0] {w#0},{h#0},1,4,0,2 +rep_lbchstatfunc_to_pal[^0] ia split_opacity[^{$!-1}] index[0] .,0,1 rm. l[^0-1] repeat {$!/2} +rep_bchstatfunc[{$>*2}] ia,0 done endl l[^1-{($!-1)-($!-2)/3}] repeat {$!-1} l[0,{$>+1}] f. "i#0==i#1?255:0" to_gray. endl done endl repeat {($!-2)/3+1} l[{1+($>*2)},{($!-1)-($!-2)/3+$>}] / 255 f.. "i#0*i#1" * 255 endl done rm[^0-{($!-1)-($!-2)/3}] repeat {($!-2)/2} a[{$>+2},{$>+3}] c done blend[^0-1] alpha rv[0,2] rm. split_opacity[0] blend[^0] multiply a c

Using code, you can change the value of v. Works with any layer greater than 3 as 2 are at least needed minimum for the mosaic.

Here’s the atrocious result -

That’s due to the indexing technique. I may need to find out just how to get a better indexing for the purpose of generating the mosaic. Either that or I may have to add blending using the original [0] image. Or both.

EDIT: One more example, but this time, more passable. Had to add more images for the mosaic result.

EDIT: I may have to keep in mind about expand_x, and expand_y for future filters.

1 Like

Not quite what the OP was looking for, but nevertheless interesting. Reminds me of those Lego grid bases. Or a map of grid based video games.

Exactly, however, I"ll admit that this is a start to a new filter unless someone makes a better version than my own. Also, I’ll share this result too -

1 Like

Now add an option, that every photo can only used 1 or n times.

That’s going to be hard given that it’s a bit hard to maintain the code.

I made a better algorithm to make the end image better. There’s two problem - A incredible annoying bug, and having to figure out shift due to nearest neighbor scaling issue. This approach uses indexing instead.

#@cli rep_lbchstatfunc_to_pal: (eq. to rep_layers_by_channel_statistical_function_to_palette)
rep_lbchstatfunc_to_pal: rep_layers_by_channel_statistical_function_to_palette $*
#@cli rep_layers_by_channel_statistical_function_to_palette: variable
#@cli: Converts layers to palette using statistical function by channels per layers into 1x1 tile, then append them.
rep_layers_by_channel_statistical_function_to_palette: to_rgb rep_bchstatfunc $1 a x

#copy and paste below into code filter in g'mic, and copy and paste above to somewhere where you can remove it when not needed#
v=25
isw={w>h?1:w/h}
ish={h>w?1:h/w}
vw={floor($v*$isw)}
vh={floor($v*$ish)}
nsw={ceil(w/$vw)}
nsh={ceil(h/$vh)}
to_a

l[0] +r[0] {$nsw},{$nsh},1,{s},5 endl
+rep_lbchstatfunc_to_pal[^0-1] ia
split_opacity[1]
index[1] .,.85,1
a[1,2] c
r[1] {w#0+($v-(w#0%$v))},{h#0+($v-(h#0%$v))},1,{s#1},1
shift[1] {w>h?0:0},{h>w?0:0}
f[0] "i#1"
rm[1]
r[^0,{$!-1}] {ceil($vw)},{ceil($vh)},1,4,5
r[^0,{$!-1}]  {w#0},{h#0},1,4,0,2
split_opacity[^{$!-1}]
l[0,{$!-1}] pal_l. r[^0] {w#0},{h#0},1,3,1 endl

ti={($!+1)/3}
repeat {($ti-1)} l[0,{$!-$ti+$>+1}] f. "i#0==i#1?255:0" to_gray. endl done
repeat {($ti-1)} l[{($>*2)+3},{$!-$ti+$>+1}] f.. "i#0==i#1?255:0" endl done
rm[^0-{$!-$ti}]
repeat {($!/2)-1} a[{$>+2},{$>+3}] c done
blend[^0-1] alpha rv[0,2] rm. split_opacity.. blend[^0] multiply a c

Some part of the image are shifted for some reason, and I don’t know how exactly do I fix that bug. There’s also the need to add shift because some areas have bigger side than the other areas. See what I mean by deleting everything after shift and checking for yourself.

That would also depend on how many input files you have for the mosaic.

EDIT: Finally, I figured out what’s wrong with the colors. So, irrelevant part of post is gone.

EDIT: It is uploaded to g’mic community. And here’s a sample image. It uses indexing, and no apply_tiles.

^Also works with transparency too.

1 Like

Ok, now I got a issue here. When developing the gui filter - I am not exactly sure how do I get the number of layer inputs to affect the dynamic options. It seems to treat $! as one every time.

u "{$1}_"{$!>=1?2:0}\
"{$2}_"{$!>=1?2:0}\
"{$3}"\
"{$4}"\
"{$5}"\
"{$6}"\
"{$7}"\
"{$8}"
text_outline {$!},2,22,23,2,1,255 # nb layers
text_outline {{$!}-1},2,42,23,2,1,255 # nb layers - 1

This is the first test that does not block my PC with your ‘Mosaic’ filter.
The result is funny on the picture of ‘Gmicky’
Under G’MIC-GIMP-QT the command line used is ’ rep_mosaic_gen 20,{{$!}-1} '.
Thumbnails are from www.uihere.com

rep_mosaic_test_01

1 Like

Photo-mosaic has been updated. I think I should add the option to have the end result resized to nearest divisible numbers by tile_width, and tile_height? Is there anything else other than that I should add (I can’t do automatic rotation to make the end result even better as a option)? Should I add the option to have users to use original picture color as a blending mode?

For your reference,

#@cli rep_mosaic_gen: 0>=tile_width,0>=tile_height,0>=dithering<=1,1>=interpolation<=6,autocrop-by-median_bool[0=Do not autocrop by median|1=Autocrop by median]
1 Like

Your parameter conditions and formatting need revision. See example:

With the bug on my aspect ratio, I gotta say that I give up on the mosaic project. I couldn’t find a fix despite it works mostly.

Now that the aspect crop bug is fixed. I’m on my way to fixing my cli formatting. All of them. A few info might go amiss though considering the large info I added.

Okay, now I think I got a working mosaic filter with dynamic options all working irrespective of software one is using (Paint.NET or Krita or GIMP). So, I believe this thread is solved. Mind you, sometimes autocrop has to be enabled for the filter to work, and that’s something I’d really like a explanation for. Other than that, it works 100%.