Wednesday, July 20, 2016

Computer Generated Stained Glass

I wrote a  program few months ago that generates"stained glass". This came about because I was cleaning out my email and ran across a message that I had sent to myself of a flckr post by Mario Klingemann.  Mario
created these really cool images because he needed Christmas cards. I'm not sure how I found this...probably through an image search for spirals (which it's definitely not) for yet another project of mine in the thinking-about-but-haven't-done-much stage.

Mario Klingemann's "Ornaments in a Box"
More info on what Mario did is on his flickr page.

The core of his images is based on Voronoi Diagrams. So I went and found a JavaScript library (by Robert Hill I believe) and coded up a quick-and-dirty JavaScript page. Mario's algorithm seemed like a bit of a pain, so I just used polar equations with random parameters for the first go-round. The color always fades to white as the equation goes on.

Note: these images are high-resolution screen-shots from my home computer...they're quite large.





After a bit of playing around whit the random one I decided I wanted more control and actually built another JavaScript page using Knockout to code up a crude interface and to let you see the polar equations that generate the "glass" and set there parameters and colors.

Polar Equation Parameters (and  Colors)


Polar Equations Plotted

Resulting Voronoi Diagram

The user interface needs some re-factoring...it's a pain to move around and set all the parameters. Straight polar equations also don't give as nice a result. I may play around with this once a couple of other projects get done.

I do have one more "stained glass" generator, but it uses an entirely different method of laying out the pattern. So that will have to wait for another post.


Weeding & Gate Design

So I got up early this morning to weed out a couple of beds in the garden and to write blog posts. I'm trying to get up early at least one day a week to stay on top of all of the flower beds and garden.

 
Scraggly Corn
I weeded the bed in front of the peas..and yes this corn is pretty scraggly. It got (mostly) dug up and replanted twice when it was only a couple of inches tall. I think either the crows or a baby bunny that I chased out of the garden dug it up and ate it.

I built a new garden gate earlier this year, but I still haven't put a sign on it yet. The old gate had a "Weed 'em and Reap" sign that I carved. I think it's time for a new saying, but I haven't come up with one yet.
Old Gate

New Gate

Saturday, July 2, 2016

Teaching a Computer to Paint

One of the (too many) things I do is manage the website for the Westerville Community Bands (www.westervillebands.org).  I needed a "summer" themed background picture for the site. I had a nice photo of the band playing at the Alumn Creek Amphitheater in Westerville, but it was a bit too busy for a background. I wanted something more abstract.

So I wrote a quick-and-dirty program to "paint" a picture by drawing a 45 degree stroke up and to the left. It worked by choosing the pixel under the current location and moving up one and over one until the pixel wasn't "close enough" in color to the original color or we were at the edge of the picture. Then it would draw a line from the start location to the end location using the original color. Repeat ad nauseam. Of course the original algorithm had a math error that caused strokes to get too long the further right you got in the picture...but I did figure that out eventually.

For the last year or so I've been playing around with the algorithm in between other activities. Below are some images of the results.  

NOTE: you'll need to view these full-size on a fairly big screen. They look pretty much like regular photographs when they're shrunk down.

Except for this one...I had the "abstraction" level cranked up pretty high.
Olivia Wilde

The current version is based on seed fill regions - the "paint bucket" tool in most graphics applications.

The basic outline of the code is:
  •  Do a 3x3 "blur" operation on the image to smooth out any noise and coincidentally smooth out the edges of regions.
  • Check points every 10 pixels (or so) and see if the colors around that point are pretty close  to each other and that it's not part of a seed fill region. If so then start a seed fill region.
  • Go back through every point on the image and if it's not part of a seed fill region start a seed fill region there.
  • Merge any regions that are smaller than some size (usually between 5 - 25 pixels) with the neighboring region that has the closest average color until all regions are above the minimum size.
  • Go back through the image merging adjacent regions who's average color is "close enough" to each other. Continue to do this until no more regions are merged.
  • Figure out the slope of each region. For wide regions use the top edge or bottom edge; whichever one is not horizontal. For tall regions use the left edge unless it's vertical.
  •  Create a stroke for every line segment that intersects the region by going down and across. Pick the median color of the points that intersect the region from the original image, not the blurred image. The median color is used to minimize getting a streak of the wrong color across the image.
  • Create the output canvas. 
  • Fill the regions with the average region color, possibly passed through a color transforming function. The filling is used because I'm using anti-aliased line drawing and with a white background you get a lot of streaks. I have also just painted everything twice, but filling works a bit better.
  • Draw the strokes on the canvas, possibly passed through a color transforming function.
Of course there was a lot of playing around to figure out what worked. There was a lot of code that got thrown away because it didn't work or the time it took to run didn't make an appreciable difference in the output.

Mountains in the Fall


And once again I learned that you really need to profile the code before optimizing. A couple of "optimizations" that I made, really slowed down the processing.

I also added the ability to manipulate the output colors, though none of these pictures are using it.

Asters in the Garden
Now all I have to do is build the robot to actually paint the picture....of course they do make them; they're called ink-jet printers...
Mountain Scene

Neuschwanstein Castle