174 comments

[ 4.3 ms ] story [ 80.3 ms ] thread
that is a lot of fun and much more "artsy" than many of the filters available in paint programs.
How long until this is made a filter on Instagram? Soon, I hope :)
No way this can be done in real time... at least in the near future and using the same technique :-)
Probably not for real-time, but not impossible as a filter. I would imagine it'll be more like Prisma, take your snap and let it chug for a few seconds to give you a pretty picture.
I'm just testing it and it takes ~1 minute per photo on a quad-core i7.
Yep, I later read the technique used by the OP, and is quite different compared to programs similar to this one, including mine, where a fixed set of shapes is evolved in order to find an optimal arrangement. This is a complex optimization problem that takes a lot of time. In the OP implementation old shapes are never re-arranged, just new ones are added in order to decrease the error. While the visual effect is still very interesting, you need more shapes this way to approximate the same level of details, and is in some way less interesting IMHO, at least conceptually, compared to "arrange N items to get the best result" which looks like a quasi-human task.
Prisma uses neural networks to learn the features, so it requires very hard training, but it leads to fast generation
I believe prisma uses Neural Style for most of its images, and that generally doesn't take too long to train IIRC
It's really cool how it isolates some of the really pretty colors and blends them into the rest of the picture.

I'm loving their twitter, too: https://twitter.com/PrimitivePic

Those pics remind me very much of the old game Out of this World. I wonder if someone can modify this to encode video. It would make for an interesting effect.
Heh, my coworker said the same thing.
Naive (probably non-realtime) version for video should pretty easy, just run the algorithm frame-by-frame. Biggest problem would be the lack of temporal stability ("jitter"), but I imagine using previous frame as the base state for next frame would help.

Real-time graphics rendering is another story altogether, I don't see any trivial ways of applying this sort of thing for typical graphics pipeline.

I just tried using primitive on video frames - i has a nice effect, but somewhat jittery. I blended some frames together to avoid it.

Here it is, with the bash scripts: http://rybakov.com/blog/primitive/

upd: used a better video example and cleaned up the scripts.

Nice! More iterations per frame would reduce the jitter probably.
Wow, I really loved the result! I actually find what you describe as "jittery effect" to be a very interesting quality!
If you like it, try lowering the number of shapes primitive uses. I added an example video with n=15, it works really well for simple forms. Almost like a low poly rendering.
(comment deleted)
Hi HN, OP here. I've tinkered with this problem a few times over the years, but only now am I happy with the results. This time I wrote it in Go and implemented things a bit differently that helped performance quite a bit.

I plan on implementing SVG output pretty soon. It won't be hard I just haven't done it yet.

For the Twitter bot, I'm planning on adding another mode where it posts a GIF showing the iterative progression of drawing an image.

Let me know if you have any questions or if you have ideas for other features!

Do you have nay plans on putting a website front end on this? It would be great to upload an image and get a result
A few people have asked that, so maybe. Another thought was you could tweet an image to the Twitter bot and have it tweet back the result, but then your image is out there for the world to see, so maybe that's not as good.
I could see this becoming super popular in some twitter circles, though.
I was about to create such a website a couple of years ago, but isn't this too much computational expensive to be a free service? It's going to make people wait a lot if the service hits HN or something like that. Or maybe my code was too much unoptimized and it's possible to train the images in a quite faster fashion after all. Anyway would be great to have such a site.

EDIT: Now I checked better your implementation and is very different, and indeed, can be made a lot faster. What I (and others before me) do is to have a fixed set of polygons and move, rotate, change color in order to find the best arrangement. In your case instead you add shapes incrementally in order to lower the error.

If you create a frontend, it may be a good idea to add a button for buying a print (which you could do through one of the many online services available). Some of these look very nice and I'm considering printing something like this on a canvas to hang on the wall.
All the +1 in the world for this. I've been browsing the Twitter bot for a while just thinking "some of these are great; I'd happily hang one".
(comment deleted)
Grab primitivepics.com NOW.
Also available is primitive.pics. I'm surprised no one has grabbed these yet...
That's a terrible name if he's planning to monetize this tho.
why?
I assume because "primitive" generally has negative connotations. (Don't try to make rational arguments about that doesn't apply here or how obvious it is that it's not the "bad" sort of primitive. We're talking about marketing here. Rational arguments are a category error.) I'm not creative enough to come up with a positive, just some more neutral ideas that you would have the opportunity to shape, like Shapify (taken by other things though), something with "simplify", something with "fun" maybe ("fun up your photos!").
And to me, Shapify is just another generic "web 2.0" name. Lost in the sea of a million other "ify" domains. The point here is that they should at least claim the domain name for their product, regardless if that is going to be the actual public facing product.
This is another one of those "your tone suggests you disagree with me, but you're just repeating my point back at me" posts. I told you "Shapify" was a neutral word that you can pour your own connotations into. A lot of brands are. What's a "Cisco"? What's a "Nike" in a country where most people won't get the classical allusion? What's a "Coke"?
Those brands aren't generic "ify" names that sound like they came from a domain name generator. Primitive sounds like a pretty good company name to me. There is already a skateboarding company of the same name that does well.
Is it pure Go? Could you compile with GopherJS and do the processing all client side?
That would be cool. It is pure Go...
You could accept DMs as well
You could also make it an app the way Prisma did...
Make stroke of a brush a geometric primitive and you have an interesting painter.
I was thinking along those lines, perhaps a general swash shape that is randomised at the edges a little.
Yeah, I briefly thought about that but haven't tried anything yet...
Great work so far, I hope you can pull it off.

... Then just come up with some fake name and portfolio website because I have a feeling that people will want to pay less for automatically generated art even if in a blind test they would like it more than a "real" one ;)

This is really impressive. I'll bet if you printed these out as high quality giclees and didn't tell anyone how you did it you could sell them for thousands of dollars in fine art galleries.
You could probably sell them even though you revealed how you did it.
I dunno, I think a lot of the hoity-toity types who are willing to overpay for art would be put off by knowing that it was done by computer. For them, the value is in the scarcity more than the aesthetics: they want to have something that their friends don't (and can't!) have. So if it were me, I would choose not to reveal that anyone who knows how to use github and an inkjet printer can reproduce the results.
That's not necessarily true. There are many examples of fine art which is made by computer and easily replicated by anyone. However, the prints themselves are limited in quantity (or, there may just one official print).
Of course. But do people pay top dollar for those? I don't actually know, but I doubt it.
This is how photography nearly always worked. I think there's some early photo tech that did only result in one image, but all of film photography produced 'prints'.

Although I remember growing up with one print that deliberately had a fold in it, made by the artist as part of the art.

"I dunno, I think a lot of the hoity-toity types who are willing to overpay for art would be put off by knowing that it was done by computer. For them, the value is in the scarcity more than the aesthetics:"

There is a portion of the art market that caters for interior design. A client might say something like, "I want a dozen in this colour, style with an ocean breeze feel." As soul destroying as this may be to an artist, some clients want their art by the numbers, colours and feel.

On a related note, perhaps Richard P Gabriel could also sell his machine generated poetry. The future will be interesting for artists.
I feel compelled to note that "giclée" is a fancy word for "inkjet printed". It has connotations of higher quality, but it's not a distinct process. See https://en.wikipedia.org/wiki/Gicl%C3%A9e
That's not quite true. It's a particularly high quality of ink-jet print. You can easily tell the difference between a giclee and the output of an HP OfficeJet.
Also it's often done on some type of canvas.
Since we're talking art and commerce, I smell a business opportunity - selling inkjet printers with Giclée Enabled™ label, at extra markup.
It's still the same process. The printers used to make "giclée" printes are ordinary inkjet printers, they're just not HP OfficeJet printers—probably.
Depends on what you consider "ordinary". A giclee printer can fill a room and cost many thousands of dollars. e.g.:

http://www.adorama.com/iesp20000.html?gclid=CNz7x4-in88CFQqE...

I have a similar printer.

The word "giclee" does not even appear in the description, but "inkjet" does. It's still an ordinary injet printer. It's bigger and more accurate than most. I've never seen them put in rooms so small that they'd "fill the room", I've usually seen them in rooms with several printers.

> It's bigger and more accurate than most.

Then it isn't ordinary.

From Wikipedia (and professional photographers I've spoken to mirror this sentiment), “since [giclée] is an unregulated word it has no associated warranty of quality.” It's like “premium”.
I'd love to help with the SVG implementation. I'll follow the repo. Great project.
Nice work!

As far as other ideas, morphing from one photo to the next one. Making changes (morphing shapes, changing colors, adding / removing shapes) would look interesting.

Can't believe you didn't input Duchamp's Nude Descending A Staircase ;)
I like it. I noticed that the oval brushes were almost always of lower quality (in the sense of doing a worse job recreating the original). I think it's because you only take axis-aligned ellipses and not arbitrarily rotated ones, which might be fun to try too.
Actually ellipses perform pretty well. I've analyzed this a good bit... http://i.imgur.com/82Aksg0.png (lower is better, this shows average score over 100 different input images)
As an aside, it would be nice if you could cite the original sources of the images posted by the Twitter bot; it would be nice to compare, and probably most safe legally too.
to add to this, I want to compare to the source image! You should definitely link to the original.
Just wanted to say this is really awesome. Nice work!
I have tinkered with this myself. Have you tried a fitness function that doesn't just compare the source pixels, but also compares the source and approximation after each has been run through various convolution kernels, and adding the result to the overall score? it takes a little longer but it can let you fine tune things like giving a higher score to images whose edges line up.
There is lots of work on "artistic rendering" like yours, from the early 1990s to the present. It started with work by Paul Haeberli at SGI [1]. The first chapter in "Image and Video-Based Artistic Stylisation", edited by Paul Rosin and John Collomosse [2] describes many techniques you might be interested in. Have a look; you will like what you see.

1.http://dl.acm.org/citation.cfm?id=97902

2.https://books.google.com/books?id=YjXlTPFYGEYC

Hey, that book looks right up my alley... I just ordered a copy. :)
This is great work! I've tinkered with another algorithm recently that gives similar results: http://imgur.com/a/djqnR

Will share another time, thanks again for the post.

Very cool. One variation I'd like to see in the same algorithm is without the padding or borders, just the gradient-ed quadrants.
Can you link to the algorithm itself? Thanks - cool work.
Awesome! Thanks for sharing this. Feature request: combine modes(e.g. triangle+rect).
The code is very readable! Especially because it's not using a lot of external libraries. Including the twitter bot is a very nice touch. Awesome!

One of the key features of golang is concurrency. Your code is single-threaded, even though hill-climbing and annealing (and also all kinds of image operations) could be highly parallelized. Maybe that's something rewarding to look into at some point?

If you ever find the time, can you outline your strategy for your choosing a convergence algorithm? How did your experiments go for choosing the parameters (you called them maxAge, maxTemp, etc.) for those? Why did you currently end up choosing hill climbing over annealing, here: https://github.com/fogleman/primitive/blob/master/primitive/...

Thanks. This is wonderful. I just put go on my mac and got this running in ~5 minutes. I am going to do a few images tonight and will share the google photo album as a comment to this comment when I get a chance tonight.

This is very cool. Thanks.

I noticed that the alpha default is 128, but usually the scale is 0-1. Is the scale then 0 - 256 for this option?
This is really well done, nice work.
For those asking about a web version of this, I made a similar thing with HTML5: https://franciscouzo.github.io/genetic_art/

It employs hill climbing and supports different kinds of shapes.

As you translate images into groups of primitives -- I wonder if this would facilitate image search like:

- given an image, find similar images

- given image, find all images which it is a subset of

I'm extremely short-sighted. After looking at all the pictures, and thinking "Okay, that's pretty nifty," it occurred to me to try taking off my glasses and viewing them again. The result is amazing :) All of the individual shapes blur into invisibility, leaving only a very recognisable if fuzzy version of the original image.
That’s “near-sighted”, not “short-sighted”, which is another thing entirely.
Near-sightedness and short-sightedness are the same thing in the context of ophthalmology, no? https://en.wikipedia.org/wiki/Near-sightedness
Originally they were synonyms, but one of them has come to have a more metaphorical meaning, to the point of using it literally is actually confusing.
OP is from Scotland, same as my wife, and I can confirm 'short-sighted' is the correct usage in Britain for what most Americans call 'near sighted'. The term does not have the negative connotation in Europe that it does in America.
Cheers for clearing that up :) I was rather confused by the comment.
You've failed to consider the rest of the world and their usage of the term; it's a bit short-sighted, really.
But not near-sighted. Only one of the terms is overloaded. ;)
Funny! I'd never heard "near-sighted" before that Wikipedia article.

Surely in using 'short' exclusively metaphorically, its metaphoric effect is lost entirely?

Don't feel too bad. I had to read it twice to get the meaning, myself. The fact that it's used in a literal sense outside of the U.S. isn't something that I would have considered. I suppose that my viewing of foreign media has had a dearth of references to optometry.
What do you call "extremely" ? I am -6 and did not notice any of what you describe, so I assume I'm not nearly as bad a case as you are ?
-9 plus heavy astigmatism. My maximum clear vision distance without glasses is about six inches!
-11 in both eyes here. Seeing the same thing!
You can get a similar effect by pressing Ctrl "-" a couple of times in your browser, to shrink the images. The result is that they look much sharper. But of course, this spoils the original effect.
Huh, it really does. Very cool!

Similarly, the mosaic effect that they use on TV to hide faces sometimes leaves them still recognizable if I take my glasses off, even if they're completely unrecognizable when seen clearly.

I wonder if this effect works for people who aren't short-sighted? Like, maybe short-sighted peoples' visual systems develop to use more focus-invariant features.

Most people can manually defocus their eyes to accomplish the same effect as a farsighted person taking off their glasses
Yes, but I think the GP was talking about learning, forming new (different) brain connections, because most near-sighted people navigate the world with blurry vision for at least a few minutes daily, sometimes more.

(personally, since my eyesight without glasses or contacts is pretty bad, no more than 15 mins until I get annoyed with the difficulty spotting small objects and go for my glasses :p gonna laser those puppies one day, maybe. it's amazing living in an age where they can actually fix this sort of thing, shame if I didn't take advantage of it)

Pretty cool! I think if you can introduce some bias towards smoother primitives like ellipse or circle, it may look better.
Very nice! Now I want a render farm so I can use this for 4K video. :-)
Cool! Now someone should try doing this in 3D :)
You absolutely could but the search space would be so much larger. Also, what is your heuristic? It would only be one angle of 3D space?
I suppose going volumetric and matching colored cubes to an input model would lead to a pretty neat mesh-to-Minecraft converter :).
If you were smart, you'd snag primitivepics.com , stat. Forget Twitter, establish your brand. I wouldn't even open source it until you've done so. It's unique, and non trivial.
"If you were smart"?

His results speak for themselves!

Sounds like a good reason to grab it then! Anyhow, looks like someone got it.
this reminds me of the "GIMPressionist" plugin in the GIMP, which can be coerced into producing pictures like this
Nice!

A few years ago, there was an HN post about a similar algorithm: https://news.ycombinator.com/item?id=4912964

Inspired by this, I wrote my own implementation in Perl: http://qumsieh.github.io/blog/2012/12/14/Evolutionary-Image-...

Pretty cool effect.

Back there lots of people posted their implementation (been there, done that... an easy one with triangles in pure C). It's a fun exercise you can then show around and get very interesting output of
This is amazing. Does anyone know if there is a prisma type open source project as well in addition to this?
This is awesome, what motivated you to start such a project?
My inspiration is mentioned in the README. :)
Have you tried using it as a lossy compression algorithm for images?

The position, shape, orientation and color of the primitives should provide a rather synthetic representation of the starting image.

Yes, I'd love to see the compression ratio vs. image quality comparison.
I feel like it's a perfect task for a GPU. Calculating diffs on every attempt with the CPU must be slow.
If the images are small enough SVG versions of these would be nice as preloaded images while the originals download.
Likewise, if the random component could be removed, it might make for a very nice video encoding.
You might have to wait a while on the encoding side. It's taking a minute a frame to encode here! :)
As long as decoding is fast enough, it can be worthwhile :)
What if the seed for the next frame is the previous frame once it hits a certain fitness.
Possibly naive question: can this be used for image compression? Use this for a rough approximation to the original colours, and encode the diff to the actual image using some efficient algorithm (lossless or not)?
It would definitely be lossy compression, but yeah. If you are just talking about 50-200 polygon coordinates... It would be interesting to try and use these types of images in demoscene or size based game competitions.
Why definitely lossy? If you encode the deltas in a lossless manner, the result will be identical to the original image.
You could store the combo shapes for 50 images in about 350 bytes. If you want to fix to axis and pick one shape, you can get it down to 300. (That's 256x256 images, for each shape you need two coordinate pairs, or 4 bytes, 1 byte for rotation, 3 values for rgb (15-bit color), and 2 bits per shape for choice between ellipse, rectangle, and triangle
It's interesting how quickly the Mona Lisa was recognisable.

You could make an image quiz out of this.

Or perhaps CAPTCHA?