Anyway this type of algorithm could be implemented in G'MIC?

Edge aligning using gradients

My take on the rose:

gmic oellipse.gmic sp rose,1024 oellipse. 30,3,2.5,1,7  o. rose.png

Strong edges tend to orient better than soft-focus photographs:


Base image

gmic oellipse.gmic e_letter.png -blur_linear. 2,0,60 -d , -oellipse. 30,3,2.5,1.1,7 o. e_letter_oe.png

Never pass up an opportunity to foist yet another Goudy 1911 Bookletter ampersand on an unsuspecting world.


Base image

$ gmic oellipse.gmic amper_01.png r. 200%,200%,100%,100%,5 oellipse. 30,3,2.5,1,7  o. ampersand_ellipse.png
oellipse.gmic
#@cli oellipse : Spacefill a surface with edge-aligning ellipses; edges
#@cli : derived from selected images. 1. median factor: preprocess.
#@cli : blur neighborhoods with low local variance; force edges across
#@cli : boundaries between high variance. Larger ⇒ greater effect.
#@cli : 2. ellipse size. Larger ⇒ bigger ellipses.
#@cli : 3. edge sensitivity: lower admits only the most prominent edges.
#@cli : higher detects more edges. Too many edges and orientation is
#@cli : less clear.
#@cli : 4. Spread: Larger ⇒ spreads ellipses at greater step sizes
#@cli : along normals to edges.
#@cli : 5. Search passage count: Larger ⇒ increases the number
#@cli : of passes to find empty spaces to stick ellipses. Each pass
#@cli : tries to fit ellipses with 1/2 the radii of the previous pass.
#@cli : My image is black : Result of not finding edges. Try increasing
#@cli : median and/or edge sensitivity. Try pre-sharpening the image.
#@cli : It takes forever and a day to run!: Yep. Try fewer passes; smaller
#@cli : images. ≈5 minutes on 1024×1024 RGB with 7 passes. Later passes
#@cli : take longer. This with a Xeon(R) CPU E5-2630 v4 @ 2.20GHz running
#@cli : one thread (this toy does not multi-thread).
#$cli : $ image.jpg oellipse. 30,3,2.5,1,7  o. image_ellipse.jpg

oellipse: -skip ${1=10},${2=1},${3=3},${4=1.1},${5=1}
   mfac=$1
   efac=$2
   esen=$3
   sprd=$4
   rcnt=$5
   -name. img
   +luminance.
   -name. gray
   -median[gray] $mfac
   -newtile[gray] $esen,$efac,$sprd,$rcnt
   -name. mask
   -blend[img,mask] shapeaverage0

#@cli newtile : Make a partition (tiling) map of an image.
newtile:
   -check "${1=3}>=0 &&      \
           ${2=1.0}>=0.05 && \
           ${3=1.5}>=0.25 && \
	   ${4=1}>0"  
   -echo[^-1] "Creating a partition map of selected images."
   edgesen={$1/100}
   tsize={$2*0.025*sqrt(w^2+h^2)}
   spread=$3
   rcnt=$4
   -name. metric
   -remove_opacity[metric]
   -gradient_norm[metric]
   -blur[metric] 1
   -ge[metric] {$edgesen*abs(iM-im)}
   -distance[metric] 1
   +gradient. xy
   -append[-2,-1] c
   -vector2tensor.
   -name. orienter
   [-1],[-1],1,1,[-1]
   -name. plottingfield
   -repeat $rcnt
      -echo "Pass\ "{$>+1}
      [metric]
      -name. truedistance
      -round[truedistance] {$spread*$tsize}
      -fill[truedistance] ">
                             abs(i-j(1,1,0,0,0,1))>"{0.5*$spread*$tsize}"?
                             1: abs(i-j(1,0,0,0,0,1))>"{0.5*$spread*$tsize}"?
                             1:0"
      0
      -name. pstack
      -eval[truedistance] ">
               if(0<i(x,y),
               da_push(#$pstack,[x,y,$tsize,$tsize,$tsize]);
               run('plot_ellipse'))"
      -remove[truedistance]
      -if w#$pstack==0
          -echo "Plotting field seems filled"
          -break
      -else
	   tsize:=0.5*$tsize
	   -remove[pstack]
      -fi
   -done
   -keep[plottingfield]
   -fill[plottingfield] i(x,y)==1?255:0

plot_ellipse:
   cx,cy,er,pw,ph:=da_pop(#$pstack)
   offw={round($pw/2,1,0)}
   offh={round($ph/2,1,0)}
   rad={round($er/2,1,0)}
   estats={V=I(#$orienter,$cx,$cy);eig([V[0,2],V[1,2]])}
   +crop[plottingfield] {$cx-$offw},{$cy-$offh},{$cx+$offw},{$cy+$offh},2
   -name plotspot
   -if (ia#$plotspot)<-0.875
       -ellipse[plottingfield] $cx,$cy,$rad,{0.75*$rad},{es=[$estats];rad2deg(atan2(es[3],es[2]))},1,1
       -echo "Plot Ellipse: "$cx,$cy
       -echo "Ave: "{ia#$plotspot}
       -echo "eigens: "{[$estats][0,2]}
   -fi
   -remove[plotspot]

Time to walk Vinny.

EDIT: Documented script listing.
More extensive documentation on making a partition map in Cookbook article Tiled Art. Have fun.

3 Likes