.NET, C#

Genetic Programming: Mona Lisa Source Code and Binaries


Source code and binaries are now published:

The code have been downgraded to .NET 2.0 but the solution files are still VS.NET 2008 format.

Many many thanks to my partner in crime Mats Helander for the .NET 2 port and Options / Serialization extensions. 
Do note that the number of polygons are now configurable, and the image above is composed of about 150 polygons.



63 thoughts on “Genetic Programming: Mona Lisa Source Code and Binaries

  1. I put together my own version of your idea yesterday.. my images weren’t looking nearly as good as yours.. after looking at your source, i think the biggest difference was in size of change. Your mutations are much smaller. Now, looking back, that seems obvious, as it allows more room for incremental improvement. Mine would change drastically and would usually be a step backwards. Especially after 30,000 generations.

    Thanks for sharing this!!


  2. Seriously cool, thanks for the source!

    Jordan, you can download the compiled version from the link; it’s called ‘EvoLisaBin.zip’

  3. Great program, and great idea – been having a lot of fun with it.

    I agree with onisahkku (I think). It’d be great to have a feature that saves every nth selected image to a file automatically. You could make neat movies that way.

    Also, I’m looking forward to the export feature you mentioned – SVG, PNG, and/or JPEG. :)

    I looked into a CUDA implementation (that is, an on-GPU implementation), but it may be too big a bite for me to chew. It’d be pretty neat, though. I think it’d be loads faster.

  4. Another thing which is a great side effect of this toolkit is that it’s apparently possible to create an recognizable image of the mona lisa with just 150 flat 1-color polygons! Ask a human to produce that and s/he’ll likely have a hard time! :)

  5. Cool, the binary even works on Linux using Mono. Had to tell it where to find the equivalent of the gdiplus dll but after that it’s all fine.

    I’m still going to rewrite it in C++ when I get a chance, though :)

  6. Thanks for sharing. I love to tinker with these kind of projects.

    I added a factor to the error calculation that comes from an “alpha map” calculated before the evolution starts. Currently I use local differences (basic edge detection) and closeness to the center as “enforcers” of errors. I didn’t do a scientific analysis, but I think this helps the algorithm to converge faster to a recognizable image. In my test runs, the 50K iteration Mona looks like your 350K mona and uses 56 polygons.

    Drop me a mail if you’re interested in the updated source code.

  7. Hey, downloaded the source, was playing with it. I noticed that you often iterate without any mutation happening. But when you do this, you discard your cloned image. I made a quick change to the source to keep the image if it is unmutated, and there was a noticeable speed improvement.

    Just figured, for people trying to pump out pretty pictures, it might be a worthy tweak to the code.

  8. Adrian #2 : I’m interested, but only if it’s a compiled binary version :D

    If you could send it on the web and give me a link, I’ll test it ^^


  9. Really cool,

    I’m also a french guy, sorry for my english!

    I find your site by the link from M. Net! Je ne l’ai pas encore essayer le Rhino, mais je trouve que c’est une excellente idée, surtout car M+ ne marche vrment pas bien! (I said something about the Rss Hack for a french tv show)

    Impressionnant le programme que tu utilise, et c’est fou la progr génétique, je ne connaissais pas! Spécialement, les années de dév de GP sont en mm temps que la course a l’Espace (coincidence ?!?…)

    Lache pas! Et écoute M Net c’est le concours du bas de noel en +, je ne sais pas si tu a le mot moi il me manque une lettre!

    Good Bye everyone,
    Johnny boy

  10. I tried to run the .net binary, but my entire machine just stops. It took several minutes just to get the task manager up and kill the process. What’s going on here? I tried the Javascript version of this, but the .net version should be much faster.

  11. I am totally not a computer programmer, so I don’t know whether I’m asking the impossible, or whether you’ve already done this and I don’t realize it. But is there a version of this program that will run on the Mac? I would love to play with it, but the MAc is all I’ve got.

  12. Great! Many thanks. A few point for us newbies:

    1-There are too many options which I don´t really understand. I wouldn´t mnd less detail to obtain a faster result – which options should I change and in which direction?

    2-I would really like to try and print the resulting polygons in transparencies and then stack them. Can the resulting image be decomposed into the different underlying poligons?


  13. Hi,

    I downloaded “Evo-Lisa Source Code – LGPL – .NET 2.0″.
    Adding the files into an MS VS.NET 2005 project but it won’t compile.

    A lot of the syntax errors look very strange to me, as if this were still .NET 3.0?



  14. Great tool, thanks very much for posting code and binary! Some functionality to export to SVG would be perfect. The SVG format is really simple for this, so it should be very straight forward to add it.

  15. This could be truly interesting to create SVG file from bitmap picture. Even more interesting, it could creates compressed SVG file (SVGZ). I bet the compression ratio would be truly amazing.

  16. 0) Setup a random DNA string (application start)

    1) Copy the current DNA sequence and mutate it slightly
    2) Use the new DNA to render polygons onto a canvas
    3) Compare the canvas to the source image
    4) If the new painting looks more like the source image than the previous painting did, then overwrite the current DNA with the new DNA
    5) repeat from 1
    To be correct this is not really a genetic algorithm – this is Hill Climbing. Roughly speaking HC differs from GA in several aspects:
    – in HC you have one solution, in GA you have pool of several solutions
    – in GA you not only mutate solutions, but also crossover two(or more) of solutions to get new solution.

  17. Correct me if I’m wrong, but I think for it to be hill climbing it would need to rely on the derivative of the fitness function.

  18. He is relying on the derivative in a primitive way.
    He is examining the delta of the fitness function between the parent and child, and choosing the one with the better fitness function (looking only at the sign of the derivative).

    He’s not trying to do any prediction, or scale his mutation parameters, or anything fancy — just hill climbing at it’s most basic (“am I higher or lower, keep going higher”).

  19. I hope you are aware that none of the GA/GP approaches try to “predict” anything.

    That would not be evolution at all…
    And that tuning the mutation params are not a requirement for any of the algorithms.

    And that hillclimbers are based on a fixed size solution.
    While this app uses a dynamic sized (non computational) AST.

    This app does not fit directly under GA/GP since it lacks cross-over and the population size is too small.
    (Atleast in the non-clustered version)

    It also does not fit directly under HC because the solution is based on a dynamic sized AST, and got multiple mutation parameters and that HC requires you to _actually calculate a derivation_.

    (The sign of the derivation was a really weak argument since that could be applied to any GA/GP when killing off the weakest ones in the population too)

  20. « an option to export to bmp, png, or jpg will be nice to the next version of this program »

    That seems counterproductive ;-)

    I do hope that there will be an SVG export someday though. The style that this app produces is so much more appealing to me than other bitmap-to-vector converters, especially for images containing gradients.

  21. hello sir

    ur wrk z really nice,i appreciate it but i need to run it on .NET 2005 version, can you please help me out

  22. @Tim:
    Ah, this reminded me of why I’m not a computer science major any more… I did the first three things you suggested, but now I can’t figure out how to get the program to actually run. What do I need to do here?

  23. This is excellent,

    I’ve written a bunch of articles on C# corner experimenting with GA (some with GA’s and artwork), but this one takes the cake as far as art is concerned. I will definitely mention this in my C# Corner blog. (It would also be great if you were to write an article on C# Corner showing this cool project)!



  24. Hi,

    i really like this idea, and since i am a painter i would like to try this with some images, but since i am not programer i don’t understand where to download application(if there is one) and how to use it.
    Would appriciate if you can help me and show me links where to download.

    Thanks in advance


  25. Hi Roger

    Your program is very interesting.
    I made a similar program, that is different in the way of image production and the GA structure.
    My images are produced with the letters (unicode), and my GA is based on Steady-State Genetic algorithm.

    Also, I speed up the fitness function, by cropping the changed pieces of new images.
    you can crop any polygon by a RECT from min(x,y) to max(x,y) of used points.

    That is interesting for me, to read your opinion about my program.

    My post about EvoPic:


  26. Looking at the source code, I was able to make several improvements. First as Charles Randall pointed out. I call Mutate repeatedly on newDrawing until its dirty to avoid clones that don’t result in a mutation. Second really moved things around a bit to make it multi-threaded. Basically one thread running StartEvolution for each logical processor on the machine. This required modifying GenArt.Classes.Tools to have a thread safe WillMutate function. Overall, things seem to be about 15x faster on my 8 logical processor machine. I’m considering where to post my changes.

  27. I’m trying to create a simpler version of this program in python (using circles instead of polygons) but my fitness is not improving and there are no signs of convergence even after 10,000 generations. This is my first project in python and I need a python programmer to review my code and give me feedback. If someone is interested in helping me out please send me an email: paintelectrons at gmail dot com

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s