Assignment 3: A Bird's Eye View

Well, it's finally time to do some real hacking inside CHDK. Yeah, you've written scripts, but now you're going to write and compile some actual C code to run inside your PowerShot. You're going to transform a circular "bird's eye" image into a much more ordinary-looking ultrawide shot.

What Is A Bird's Eye View?

Not having been a bird, I can't say what birds see in real life. However, I can tell you about bird's eye lenses. The first bird's eye optic I'm aware of is a product of the source of many odd things photographic: Spiratone. I actually managed to find one on eBay not too long ago. Here's a shot taken with my Spiratone Birds Eye attachment:

It's sort-of like a fisheye image gone wrong. The image seems to be distorted into a circle, a lot like a fisheye lens would distort the view. However, the camera is pointed the wrong direction. The photograph contains the camera and what's behind it, not what's in front. You've probably guessed that's because we're really looking at a reflection in a mirror. The really funny thing is that the mirror isn't curved the right way to be a lens; it's convex, not concave. Put simply, that actually means it doesn't work like a lens. A lens would focus an image onto our sensor, but all this mirror does is to present an image of the scene on the mirror's surface. To get that image in focus, we must focus on the mirror surface itself... which is curved, so we'll need to stop down to get DoF to cover the entire scene on the surface of the curved mirror. Fortunately, the ELPH115IS has enough DoF that it isn't a really an issue. Incidentally, fisheye lenses don't have that problem at all: they're lenses forming an image on a flat plane.

Anyway, the cool fact of the matter is that you can basically get a 360 degree view in a single shot. As we discussed in class, there is some inconsistency in how view angles for fisheye and birds eye lenses are quoted (just like there is no reason "birds eye" is two words and "fisheye" is one). Typical birds eye lenses don't see much past their middle point, but can see everything behind them; thus, you could reasonably say they're usually around 360x180 degrees out of a possible 360x360, but in truth, 360x90 with the 90 looking sideways rather than back at the photographer would still capture the same view as 360x180 with the 180 point back. In any case, most birds eye lenses capture at least close to one hemisphere.

Your Project

Hemisphere? Them's curved thingies. Everyone knows the world is really flat, right? So, let's change that nasty birds eye projection into something more American. There are many different kinds of projections ( here are a few of their projection formulas). Most lenses try to be rectilinear, which keeps straight lines straight. Unfortunately, it cannot represent 180 or more degrees in the view angle, and it even makes anybody standing off center apparently gain some weight. Here, we're aiming for a projection that simply maps things to a regularly-gridded cylinder.

The goal of your project is simply to extract a nice cylindrical projection from a birds eye image... but you're going to do it inside the CHDK code. You're also going to be doing it using not my Spiratone birds eye, but a little homemade rig to capture the 360-degree view off a "Holiday Glass Ornament" (hey, that's what the package calls them). These glass balls are very shiny and mostly spherical, although they really are not high-precision instruments. There will be some distortion beyond what one would hope to see. For that reason, you'll be doing a callibrated mapping rather than simply applying a formula to remap the projection.

I'll actually accept either a transformation of the raw buffer or of the frame buffer. The raw buffer has the disadvantage that it is too big to have two copies, so you'd need to write the transformed projection out to a file (or very carefully order accesses to raw data so that no data is overwritten before you're done using it, which is very hard for a birds eye lens projection). You also have to ensure that you grab a pixel from the correct color channel. Playing with the frame buffer is easier, but you don't really have access to change the live frame buffer display; instead, you'll have to use the graphical overlay support to generate a real-time live display in the correct cylindrical space. That's not hard, but you have very limited color information and few output colors, so stick primarily to Balck and White for the overlay.

Stuff To Know About

The first thing you need to do is figure-out how to rebuild CHDK from scratch. You can (and should, if possible) install the build environment on your own computer, but we also have it on Coal at port 10085: yourname@super.ece.engr.uky.edu -p 10085. The default password is yourname. The build-dir in your home directory was created using the script at http://chdk.wikia.com/wiki/Gcc452. The BuildNotes.txt file in your home directory includes helpful notes for working with CHDK, including a command you must run each time you log in to use the arm toolchain. There is a sample build script at the bottom of the file.

You can't modify CHDK if you can't even rebuild it unmodified. I would suggest first making sure you can rebuild CHDK intact, and only after you have had that experience, add some dummy code to generate some output that is of the right type, but not the right values. For example, maybe just displaying an overlay of alternating black and white stripes rather than the actual live data.

Once you've done that, it's time to start playing with the mapping. Here's a JPEG of a simple test chart that is printed four times and then aligned and taped together to make a cylindrical target. Here's what the camera sees:

The key algorithm we discussed in class is apparently best known as Bresenham's algorithm, although I learned it as simply the "incremental differential." This technique allows you to step along N-dimensional lines, circular arcs, etc., using nothing more than integer add, subtract, and compare. This not only dramactically improves performance over the obvious constructions that use divides, but also explains how there can be cheap hardware implementations.

Due Dates, Submission Procedure, & Such

You will be submitting source code for your tethered control program or script, a make file (which does whatever is necessary), and a simple HTML-formatted "implementor's notes" document.

For full consideration, your project should be submitted no later than November 26, 2015. Submit your .tar or .tgz file here:

Your email address is .
Your password is

Which type of student are you?
Undergraduate registered for EE599
Graduate registered for EE699


http://aggregate.org/CACS/ Cameras as Computing Systems