G'MIC exercises

Ok, here’s my problem:

fx_rep_hitomezashi:
# ... snipped out code
u $bin_str_0,$bin_str_a,$bin_str_b,$seed_a,$seed_b

fx_rep_hitomezashi_preview:
ow,oh={w},{h}
skip "${5=}","${6=}","${7=}"

fx_rep_hitomezashi $* r. $ow,$oh,100%,100%,0,0,.5,.5
bin_str_0,bin_str_a,bin_str_b,seed_a,seed_b=${}
u "{$1}"\
"{$2}"\
"{$3}"\
"{$4}"\
"{"$bin_str_0"}"_{!$1?2}\
"{"$bin_str_a"}"_{$1?2}\
"{"$bin_str_b"}"_{$1?2}\
# ... snipped out code

If you were to read the code, I am sending arguments to ${}. However, if the inputs on ${5-7} contains space in them, then this no longer works. How do I fix it so that it works?

And debug doesn’t send out the offending lines.

I’d say you should use $"*" instead of $*.

I tried that, it didn’t seem to work.

But then, what is this 9th argument used in your code ? Have you defined a default value for $9 ?

I found the solution to my problem, see this commit - https://github.com/dtschump/gmic-community/commit/2d29309ccce6981b0c1ff69fbf0dc65d8d94a726 . The only downside is that it doesn’t allow ' char, but oh well to that, not a big deal.

After seeing a mention of pyramid based inpainting in a darktable highlights recovery thread

I thought I’d give it a try in g’mic. Some “insiders” have seen a version already, but it had a problem: upscaling with the resize command in g’mic - in bilinear mode - is not pixel aligned with a downscale. I’ve hopefully solved this by using a 2x2 box filter (that’s the convolve part) after nearest-neighbour scaling.

gcd_pyramid_inpaint : check ${"is_image_arg $1"}
  pass$1 0 ge. 1 store. msk
  repeat $! l[$>]
    wh={[w,h]-1}
    L={ceil(log(max(w,h))/log(2))} # find required number of levels
    i $msk z 0,0,{D=2^$L;[D,D]-1},1 # force 2^n dimensions
    eq. 0 mul.. .
    repeat $L I,M={[$>*2,$>*2+1]}
      +r[$I,$M] 50%,50%,100%,100%,2
      +eq. 0 add. .. div[-3,-1] gt. 0
    done
    i[0] (0.0625,0.125,0.0625;0.125,0.25,0.125;0.0625,0.125,0.0625)
    repeat $L
      l[0,-4--1] rm.
        r. [1],[1],[1],[1],1 convolve. [0]
        eq[2] 0 j[1] .,0,0,0,0,1,[2] rm.
      endl
    done
    rm[0,-1] z 0,0,$wh # restore dimensions
  endl done

gmic sp leaf 100%,100%,100%,1 ellipse. 50%,50%,"{[w/4,h/3]}",0,1,1 negate. gcd_pyramid_inpaint.. .
leafinpaint

On this laptop, it takes 0.072s

1 Like

This looks actually pretty close to what I’ve done with my inpaint_pde command, the one I use to reconstruct 3D color luts from a set of keypoints.

Hah yes, so it does! Yours is obviously more complex. I notice this method is not perfect either, e.g. you can obtain different results by mirroring on an axis. Not bad for an approximate though.

An interesting test is actually to try inpainting a very sparse colored point cloud.
Doing that, it’s easy to see what kind of function profile your inpainting technique is able to reconstruct.

2 Likes

For instance, I did that to compare the reconstruction of colored point clouds, with harmonic functions, my PDE-based inpainting and RBF :

That leads to quite different profiles (particularly for harmonic functions).

Pfff well, I can only say I’m glad I don’t need to be as rigorous. Interesting to see the complexity of each one though!

1 Like

@garagecoder Glad you are back and also helping people outside of G’MIC. Keep up with your exercises, lest you become dull like myself. Ha ha.

2 Likes

I have a question, how exactly do I get the name of [0],[1]…[n]?

1,1,1,1,5 nm. img_of_five extracted_name=?

Basically extracted_name should have string containing the name of [0].

I looked, and it’s not possible to get the name.

name={0,n}
1 Like

Thanks!

I ended up making my very first exporter (Not sure if this is good, but welcomed to criticism as always):

#@cli output_gpl : filename
#@cli : Output selected images as GIMP Palette
output_gpl:
 e[^-1] "Output palettes$? as GIMP Palette file.(.gpl)"
 
 (71,73,77,80,32,80,97,108,101,116,116,101,10,35,80,97,108,101,116,116,101,32,78,97,109,101,58,32)
 
 init_header={t} rm.
 
 (10,35,67,111,108,111,114,115,58,32)
 
 init_colors_info={t} rm.
 
 repeat $!
  if $!>1 filename=${"filename \"$1\",$>"} else filename="$1" fi
  0 nm. $filename rm.
  basename,folder,num_of_cols,palname={b},{f},{whd#-1},{0,n}
  header_info=$init_header$palname
  colors_info=$init_colors_info$num_of_cols
  start_header=$header_info$colors_info
  pal_info="\n"
  mp={w#0-1}
  repeat $num_of_cols,p
   rgb={I(#0,$>)}
   hex_rgb=${rep_int82hex\ $rgb}
   r={([$rgb])[0]}
   g={([$rgb])[1]}
   b={([$rgb])[2]}
   pal_info.=$r"	"$g"	"$b"	"$hex_rgb
   if $p<$mp pal_info.="\n" fi
  done
  ('$start_header$pal_info')
  o. raw:$folder$basename.gpl,uchar
  rm[0,-1]
 done

EDIT: Also, is there a way to make this work?

echo ${arg\ $1+1,"This contains 3 spaces!","No_Spaces"}

From searching at arg\ in stdlib or in updatexxx.gmic, none of them contains spaces. Dash is used instead of spaces.

should be

  echo ${arg\ $1+1,\"This\ contains\ 3\ spaces!\",\"No_Spaces\"}

or better :

  echo ${"arg0 $1,\"This contains 3 spaces!\",No_Spaces"}
1 Like

This is probably not exercise material, but here’s something I’d like to do in bases other than 10:

$ t=40 sa="" sb="" a=1 b={$t} repeat $t sa.=$a sb.=$b a+=1 b-=1 done

Output:
sa=12345678910111213141516171819202122232425262728293031323334353637383940
sb=40393837363534333231302928272625242322212019181716151413121110987654321

Like for base 12, 10 becomes the next character after 9.

This is part of the solution to replicating this - Concatenations — Kerry Mitchell

I would have to do element-wise addition/subtraction since double/float is out of question for large values. And I would have to solve generating a number from two variables (base_10_num,new_base). It’s the last one that’s the problem.

EDIT: I solved it.

This can output what I want
rep_num_to_base_other_than_10:
#$1==current_num
#$2==convert_2_base

num,base={abs($1)},{abs($2)}
digits,use_minus={1+int(log($num)/log($base))},{$1<0}

repeat $digits
 rem={$num%$base}
 num/=$base
 ({48+$rem})
 if $>
  rv[-2,-1]
  a[-2,-1] x
 fi
done

if $use_minus (45) rv[-2,-1] a[-2,-1] x fi

u {t}

rm.

It is exercise material as long as you show the work. :+1:

Agreed. Here’s the result I am getting:

Output
$ +rep_concat_countable_num_str 15,21,0
Base: 10
Direction: Backward
Output: 1,5,1,4,1,3,1,2,1,1,1,0,9,8,7,6,5,4,3,2,1

$ +rep_concat_countable_num_str_alt_base 21,12,31,1
Base: 12
Direction: Forward
Output: 1,2,3,4,5,6,7,8,9,10,11,1,0,1,1,1,2,1,3,1,4,1,5,1,6,1,7,1,8,1,9
Code
#@cli +rep_concat_countable_num_str: abs_num,length,direction
#@cli : Insert image containing set of concatenation of countable numbers in order.
+rep_concat_countable_num_str:
direction,length={$3%2},{abs($2)}
start_num,str={!$direction?abs($1):1},""

if $direction
 repeat abs($1)
  str.=$start_num
  start_num+=1
  if size('$str')>$length break fi
 done
else
 repeat abs($1)
  str.=$start_num
  start_num-=1
  if size('$str')>$length break fi
 done
fi

('$str')

if w#-1<$length
 $length,1,1,1,47
 j. ..,1~
 nm. {w#-2}
 rm..
else r. $length,1,1,1,0,0 nm. $length
fi

-. 48

#@cli +rep_concat_countable_num_str_alt_base: abs_num,base,length,direction
#@cli : Insert image containing set of concatenation of countable numbers in order in bases other than 10.
+rep_concat_countable_num_str_alt_base:
direction,length={$4%2},{abs($3)}
start_num,str={!$direction?abs($1):1},""

if $direction
 repeat abs($1)
  str.=${rep_num2altbase\ $start_num,$2,1}
  start_num+=1
  if size('$str')>$length break fi
 done
else
 repeat abs($1)
  str.=${rep_num2altbase\ $start_num,$2,1}
  start_num-=1
  if size('$str')>$length break fi
 done
fi

('$str')

if w#-1<$length
 $length,1,1,1
 j. ..,1~
 nm. {w#-2}
 rm..
else r. $length,1,1,1,0,0 nm. $length
fi

-. 1
#@cli rep_num2altbase: abs_num,base,start_num
#@cli : Return number in bases other than 10. Each digit is represented by the character at ASCII codepoint (start_num)+(digit value).
rep_num2altbase:
skip ${3=48}

num,base={abs($1)},{abs($2)}
digits={1+int(log($num)/log($base))}

repeat $digits
 rem={$num%$base}
 num/=$base
 ({$3+$rem})
 if $>
  rv[-2,-1]
  a[-2,-1] x
 fi
done

u {t} rm.

Now, the only thing for me to do left is to do element-wise addition/subtraction.

Question: On for loop, does it matter if ++ is in front of "it" or not? On a coding chat, it seems that C++ cares about the position as in there’s a speed difference.