G'MIC Challenge: Create image from photographs with a single line

Hope grosgood doesn’t mind the play. Anyway, sometimes you just have to stick with the devil you know. I did have to reighn in on dot (used Inkscape for that). lol

Kept it as a vector. :slight_smile:

Untitled

1 Like

Meant “one” not “on”. lolol

Also, used 24K dots. :slight_smile:

Using the TSP tools and batch files, still only took 10s of seconds on my old dilapidated 2014 vintage PC, afre. Of course my new toy finishes 3 times quicker. lol

:slight_smile:

I couldn’t get it to work in custom command either. I wonder if whirl drawing and thin lines could be somehow put together for this.

Actually not much slower on a Dell Latitude E6430 2-core (4 threads):

$ uname -a 
Linux gwen 5.15.16-gentoo-gwen #1 SMP Tue Feb 1 15:14:04 EST 2022 x86_64 Intel(R) Core(TM) i5-3320M CPU @ 2.60GHz GenuineIntel GNU/Linux

Runs were maybe only 25% or 30% longer on this bedside-browsing laptop than the dual Xeon playpen I typically use. Methinks there is not a lot in my implementation that takes advantage of a large core count. Credit where credit is due: @David_Tschumperle for implementing TSP and @garagecoder for the pointer that piqued my interest and sent me off into the weeds for recreational coding. And, of course, @Reptorian for throwing the gauntlet down.

Not hard to wrap this up for gmic-qt insofar as mechanics go; but my reluctance stems from the sensitivity this particular implementation has to its input: it is a bit tedious, those of you with a CLI bend can easily see what I mean by fiddling with the curve-and-noise bits. Real design work needs to be applied here. I like plug-ins that (a) don’t have a bazillion controls (3 - 5 is about right) and (b) more-or-less gravitate to interesting results on their own without a lot of tweaking. This toy is a bit temperamental for that. It likes large areas of light and dark, without a lot variation in either. I, for one, would like this toy to render more interesting results over a wider range of inputs. Don’t see many time-slices for me to actually do that design. It has been a busy six months for me, alas, and the Spring looks crowded already. And there are large swaths of tutorial writing I’m keen on doing.
Perhaps next weekend I can wrap it, as is, for gmic-qt and throw it in the ever-growing testing bin. Perhaps @lylejk or others can then suggest in what directions improvements should go, so that in the future it can be made to be fun without a lot of tedious adjustment.

Some hints to get better results (at least using the TSP batch files) is to first extracted the subject and placed on white background, then added contrast to you target image. I usually use a blending of G’MIC Painting preset set to lighten and adjust opacity to taste. It’s what I did to your image. Below’s roughly the result I used (see some flaws on this one since I did this quickly; lol) to feed into my voronoi batch file. Gary. :slight_smile:

@lylejk
Thank you :o)
@grosgood
I had fun with the script.
Starting from a black and white image and modifying the script I arrive by chance with an interesting and very ‘geometric’ result (View at full size to see the lines).


resize 1024,{{h}/{w}*1024}
samj_Masques_Noir_Et_Blanc_Preview 3,50
to_gray
negate
dilate 10
   +r2dx. 25%,5
   pointcloud. 3
   channels. 0,1
   *. 4
   tsp. ,
   permute. cyzx
   nm. points
   i 1024,1024,1,1
   nm. canvas
   eval {V=crop(#$points);polygon(#$canvas,-size(V)/2,V,1,0xffffffff,255)}
   keep[0,-1]
rm[0]
autocrop

You have to update G’MIC GIMP for this script to work properly.

1 Like

Really cool, samj; getting close to getting the Hilbert Curve random density fill that I would like to see. :slight_smile:

It is indeed very interesting!
I surmise there are three contributing factors.

  1. Your preprocessing steps give rise to large solid white masses.
  2. There is a follow-on multiplication of the point set scaling all the coordinates up by a factor of 4. In effect, this expands the solid white masses into grids of cities, which you can directly see if you invoke pointcloud. again after the multiplication `*. 4’ on the point set image. It would look like this:
    gmic_000000
  3. ever-so-slight rounding errors could shift North-South cities closer, perhaps, or vice-versa, and it is likely that such behavior would be the same for large regions. The traveling salesperson would tend in the same direction for long stretches of the path until local errors in plotting shift to favor other directions, such as the transition diagonals in the upper left hand patch of the tiger’s head.

You might — for its entertainment value, substitute for *. 4 a fill command f. c==0?i*4.1:i*3.9 to bring cities closer together slightly along the North-South axis; this would lead to a preponderance of vertical lines, like so:

tspout

as the traveling salesperson finds North-South cities slightly closer in the grid than East-West cities. Overall, there are a number of interesting tricks to be pulled here.

@lylejk
Thank you for the pointers! However, these also re-enforce my thinking (perhaps not clear) regarding what I think are good gmic-qt filters: few controls and large “sweet spots” that accommodate many kinds of images, and such that one does not have to do much preprocessing either in preparation or internally, through a number of pre-tsp image conditioners, in order to get splendid results. If a lot of preparation needs to be done in order for an image to be in the filter’s ‘sweet spot’, then the likelihood of the filter user being disappointed is that much greater, and that is especially an important matter of concern for compute-intensive, long-running filters. After prep and long minutes of waiting, the results really need to be good or people will be broken-hearted.

I really like the TSP tool you are using; it responds to tonal changes quite well. It would be interesting to take it apart and see how it ticks. Alas! I am over-booked and see no time for such an exercise on my watch. Perhaps, in a week or two, if some interesting mods show up here, I could wrap it up as a gmic-qt filter, but I make no promises. I also have an inventory of tutorial material nearing release (there has been none from me since last September), and that sits higher on the TODO stack.

And — there’s the rest of life, too…

1 Like

Tiger : https://www.ghostscript.com/doc/examples/tiger.eps


Thanks to @grosgood for his answer, here is the result of his advice :


resize 1024,{{h}/{w}*1024}
samj_Masques_Noir_Et_Blanc_Preview 3,50
to_gray
negate
dilate 10
   +r2dx. 25%,5
   pointcloud. 3
   channels. 0,1
   f. c==0?i*4.1:i*3.9
   tsp. ,
   permute. cyzx
   nm. points
   i 1024,1024,1,1
   nm. canvas
   eval {V=crop(#$points);polygon(#$canvas,-size(V)/2,V,1,0xffffffff,255)}
   keep[0,-1]
rm[0]
autocrop

Stairs/Escaliers

resize 1024,{{h}/{w}*1024}
samj_Masques_Noir_Et_Blanc_Preview 3,50
to_gray
negate
dilate 10
jeje_strip 45,50,0,2,0
   +r2dx. 25%,5
   pointcloud. 3
   channels. 0,1
   *. 4
   tsp. ,
   permute. cyzx
   nm. points
   i 1024,1024,1,1
   nm. canvas
   eval {V=crop(#$points);polygon(#$canvas,-size(V)/2,V,1,0xffffffff,255)}
   keep[0,-1]
rm[0]

You don’t need to wrap around w, and h. It works.

C:\Windows\System32>gmic 5,10 echo {w/h} rm
[gmic]-0./ Start G'MIC interpreter.
[gmic]-0./ Input black image at position 0 (1 image 5x10x1x1).
[gmic]-1./ 0.5
[gmic]-1./ Remove image [0] (0 images left).
[gmic]-0./ End G'MIC interpreter.

@Reptorian

That’s right. I simply use the beginning of another project to activate the ‘tsp’ script :o)

That’s cool, Gary. Just sharing some insights I discovered with voronoi stippler over the years. Another one is to invert the target, then after running, invert that result to get white on black (similar results to what you got with yours). :slight_smile:

@lylejk
Thank you : The Traveling Salesman problem. • GIMP Chat

I always have fun with the scripts of @David_Tschumperle and @grosgood

A black line on a white background :

if {w}>{h}
resize 1000,{{h}/{w}*1000}
else
resize {{w}/{h}*1000},1000
fi
samj_Masques_Noir_Et_Blanc_Preview 3,50
to_gray
negate
dilate 10
pointcloud. 3
channels. 0,1
resize. 2%,1
add. 12
tsp. 200
1024,1024,1,1
repeat {0,w}
 line. {0,boundary=2;[I[$>],I[$>+1]]},1,255
done
rm[-2]
dilate 2
negate
1 Like

I like this last one. Black line on white canvas. It still has a laser beam coming out of the eye of the tiger. :rotating_light: :joy_cat:

Going back to Rep’s original, I sort of like the meandering single line (i.e, no picking up the pin) result. Again, I would want this ability in the plugin, since, well, I’m a GIMPer. Not opposed to CLI or scripts (hence TSP), but like to be able to keep withing an editing environment. Maybe David or someone can figure out how to do this within the G’MIC plugin. While I’m asking, would like the Hilbert (and other type) of variable density single line fill render abilities as well (doesn’t hurt to ask). lol

:slight_smile:

Well, the main difference of @Reptorian’s sample and the rest of yours is that the line can cross itself! Although it is different, I recall this:

Somehow, instead of having the edges of the image or shape as direction change points, we could have the edges and textures of the image… and instead of straight lines, we have splines, etc.

Some remarks follows to my tests :

I did some testing with splines but it’s very, very slow.

@lylejk
Make a GMIC-Gimp plug-in is difficult because the rendering is very, very slow.
It could be sequential, for example :

  • At first visualize the completed areas.
  • Then validate the final overview.

The stability of the plug-in during the time of treatment must be taken into consideration.

Just brainstorming. We don’t have to implement all the ideas. I think it would still work with straight lines, we just have to decide when to change directions and how many times.

The thing is G’MIC is probably the wrong program to do this because of the slowness but who knows: you are all geniuses. :nerd_face:

Appreciate the followup, samj. I guess I’m still wanting G’MIC to be the do all of do alls. lololololool

Still, my Dad always told me there’s always more than one way to skin a cat. lol

:slight_smile: