The sketch of the implementationThe thing was coded in C, but I write it in pseudocode here. data contains the position, size and color of the points, and its layout is optimized for rendering, not for compression. Rendering and image comparison are the slowest steps in the algorithm, so having the data optimized for rendering speed is a good idea. The data is rearranged and optimized for compression only after the best data has been found, and it's done only once. Care should be taken, tho, so the speed optimized and size compressed data both render the same images, otherwise the algorithm could be converging to the wrong fixed point. // init image = loadImage( "image.png" ); data = randomdata(); difference = infinite; // compute while( !happy ) { newdata = randomize( data ); newimage = renderImage( newdata ); newdifference = computeDifference( newimage, image ); if( newdifference < difference ) { data = newdata; difference = newdifference; // data contains the compressed/encoded image saveToDisk( data ); } } The renderImage() function was implemented in OpenGL. However, computeDifference was done in C, but could have been optimized by implementing it in OpenGL too by image differencing and few reduction passes (log(imageResolution)/log(2) passes, to be more precisse). For my experiment I use the traditional euclidean distance between the two images, ie, the square differencing metric (quadratic error), which might or might not be the best metric. Some considerationsWell, the code seems simple, but the real trick here is to find a nice randomize() function. Usually, such a function randomizes one or a few of the values of data by a small amount, in an attempt to do a random walk towards the minima of the function. Of course, as it often happens with these methods, there is no one but many minimas, which are local minimas but most of the times not the best minima possible. So, from time to time it is a good idea to generate a completelly random sequence from scratch, and let the mutation start a new evolutionary line. Well, there is a long theory you could read out there, and learn on mutation strategies. You will end up reading about concepts like like ergodicity, methods like metropolis, and stuff. Certainly too much stuff to be described here. The good news is that you don't really need all that to get started and play around a bit - common sense is probably more than enough. |