I am trying to transform a picture into a “paint by numbers” (childhood nostalgia…)
In photoshop for example, it can be made by using a cutout filter, to split the colors into sample.
I would like to reproduce this cutout filter in grasshopper (using gh components only, not custom python/C++ scripts)
I tried by using a voronoi pattern and merging the cells that are in the same domain of brightness but the result is not very satisfiying yet.
Does anyone have ideas?
Script, example, and first result attached. paint_by_number.gh (4.1 MB)
Here an idea like I used for mosaic using K-Mean Clustering, has color are transformed to points (in [-1, 1] space).
I then use mesh IsoSplitting but you could use Mesh Contour, Mesh Plane Intersection …
K-Mean Clustering is very sensitive to initial condition, so change seed value. There is surely a better approach but I don’t know it.
I also did it a bit fast, so there could be some glitches
Thank you @old_taz, and @laurent_delrieu, these are some serious leads I have to investigate more, and particularly the K-mean Clustering algorithm that seems to be a great solution. @pavel.m thank you for the reference, this app from Github is amazing, the result is just perfect. Actually I compared the results from this app and from your script @laurent_delrieu and the color zones are the same. Only problem is by working with meshes, the zone outline is a mesh itself.
Anyway your gh script will help me a lot.
Also; the reason why I have to make a gh script without custom components is that I’m planning to use ShapeDiver to make an online app (and shapeDiver is not ideal with custom components).
You can see the mesh as a bitmap, there is quite no difference, except the color is on the vertex of the mesh and not on a face (pixel for a bitmap).
And as you work with a limited number of slice, it could be possible to not use mesh iso splitting but a different tool that extract faces of each color (integer indeed). This will supress the interpolation where 2 zones are separated by more than 1 unit.
The contour of the mesh is extracted and transformed to a polyline, I think it is quite the same for a bitmap.
Here it is, a script with no iso splitting. So except 2 c# there are no plugin involved !
Nice! This inspired me to play a bit with the clustering. I know Shapedriver can’t handle Lunchbox ML or Heron, but I found Lunchbox’s K-Means faster than the C# version (maybe multithreaded?) and Heron’s Visual Center helps with the labeling. Some of the labels are misplaced due to self-intersecting outlines, a classic problem when vectorizing a raster. split image color space no iso splitting BW.gh (2.1 MB)
Hi Brian, this is great,I was stuck with the smoothing polylines part. I can’t find the visual center component in Heron plug-in, does it work with Rhino7? If not, is there some equivalent to have the numbers well located? I tried with populate geometry on the meshes with 1 point but it is not ideal.
Here is the updated definition from your script and Laurent’s one, with the “visual center” replaced. I added a part to clean the curves with self intersections (using pufferfish). I guess now the only problem is the blank space left by the small meshes that have been deleted, under 2 kind of meshes (2 colors). A solution could be giving that blank the color (so the number) of the closest mesh. What do you think? Image_sampler_paint_by_numbers_LBI.gh (2.1 MB)
That sounds like a good option. Although, depending on the size of the print, adding a number there might occlude the entire outline given the outline will generally be a pixel wide. You might just leave them unlabeled. @laurent_delrieu 's multi material mesh smoothing script would eliminate these small areas because we could just take the outline of the smoothed mesh instead of smoothing a polyline after extracting a stepping mesh. Maybe you could hire him to help?