Wednesday, March 23, 2011

Image Processing (Extension of Contour Plotting)

Wrote a few extra lines of code to test out the Image processing capabilities using the contour plotter.
Not bad for a few hours of work:
I'm not too keen on posting my actual likeness on the internet, but this is obfuscated enough.  the 75x75 image took 30msec to process and print.. .anyways I can see how being able to quickly run through images could have a number of practical purposes... I'm pretty sure the folks who do image scans/retina scans use something similar, also for something like Microsoft's Kinect Body tracking it uses some fast implementation of this, likewise OCR solutions likely want to differentiate between signal and noise in an image

It's kinda neat having this power at your fingertips, from an artistic standpoint overlaying or converting filmed or captured images and running them through some code to spit out contours could yield some interesting stuff.  (Keep in mind the implementation I'm using is not attempting to smooth out edges but this would be an easy step to make things smoother.  Alright well the code is in a "good enough" state, now lets get the android port working.

Sunday, March 20, 2011

Contour Plot with Perlin Noise (Android)

SUCCESS!... alright I finally got it working, a mechanism for generating random "terrain" using Perlin Noise as well as a mechanism for plotting contours... here's a look:

Generated Contour map from 400x400 Perlin Noise Matrix Took 484ms

...Generally speaking I wouldn't be too happy saying anything takes 1/2 second (484ms) on my desktop, but this is not a normal case... usually you will not have an exact 1-to-1 correspondence between your contour map and the data (image) and normally you'll get a much smaller matrix/list of elevations/list of points... (say 80x80) and you'll need a contour map for this... heres a look (the generated bitmap is in the top left)

...for this scenario the generation of the 80x80 matrix took 16 ms. (I could make this look "better" if, instead of painting pixels that are 1x1, I'd paint pixels that are 5x5.... I generated another image and upped the tile size:

...this took about 31 milliseconds to generate the contour for it.

You might argue that the image above is rather smooth in comparison, so I fooled around with the Perlin noise "turbulence" and generated the following image (using 4x4 tiles, 100x100 Perlin noise generated matrix to generate a 400x400 contour map image)
..this took 41 milliseconds... acceptable.

So a few things had to come together to make this happen.  First, I had to adapt the W.V Snyder Conrec routine to work in a "non-Java-applet" mode...second I had to fiddle with the implementions of Perlin Noise to find out which one had the best fit.  Anyways I'm not "there" yet (currently it's running in a Java JFrame and I'm using an in memory BufferedImage), but I built all the AWT specific stuff in an abstraction so I'm nearly there.  Anyways originally I was going to use some processing based "blobification" tools but those were slow didnt scale (beyond 256x256 matrix for my Desktop... ewww) and did alot of "new"'s which kill Android.

Anyways it's nice to have a generic configurable contour plotting mechanism for Java/android anyways,( I can configure the number of contour lines/etc.) but also this can be used for image manipulation (instead of "feeding" it Perlin noise, feed it an image and it will contour plot the images based on HSB (Hue Saturation Brightness) Or this can be used by feeding it in actual elevations (I think from USGS) and it can develop a map like the one above from this data...    Big thing is... it's Fast, and it'll run on Android (even though I havent tested it yet)

So I'm gonna try and figure out a way to make the contours a little less jaggy (at the moment these circular looking contours are actually the result of a bunch of individual drawLines, so I might see some optimizations using breziers and drawPoly, gotta check on that though)

FWIW a 2000x2000 matrix with 4,000,0000 unique elevations took 17,735 msec to contour  (and I still didn't run out of memory... the blobDetector I was using prior, choked on images much larger than 256x256)

Well I need a beer, will work on it tommorrow, gotta celebrate the little victories!

Saturday, March 19, 2011

Graphics AWT/Swing/Android interoperability woes

Gotta take the good with the bad I guess, but I got a gripe and maybe writing this post will help me get it out of my system.

Interoperability for android graphics are a mess... I wonder whether sometimes they change the API just to annoy me.  For instance in android we have Colors that are treated as ints, but in AWT it's a Color object/class, likewise drawing on the canvas (in Android) is simular but different than in Android... So what I'm asking for is a simple Middleware interface API that allows you to implement both i.e. an interface that abstracts drawing to a canvas (whether it be a AWT/swing canvas or an Android canvas)...

Here's why... I'm writing this middleware (A contour plotting application) that should work for BOTH a Java Desktop application AND Android, but in order to do so I have to write all this abstraction around the implementation... (wait a minute, what happened to write once, run anywhere?)

This "contour engine" which (given a matrix of elevations) generates a contour map presents contour graphs on the screen.

I'm basically stealing (like all great artists do) code from WV Snyder  ...who wrote it in FORTRAN... in 1978.  Now, I'm not doing crazy OpenGL graphics or anything like that, I'm doing the very basic of basic, setting colors, drawing lines, drawing the occasional text... But its a pain to basically separate the logic out to write to separate Canvas implementations (one for AWT, one for Android).

And this is just the beginning, I also ran into some major differences trying to do many other "simple" operations... maybe I'll write one, but you'd think Google could go ahead and whip one up just to make me happy.