Sunday, December 23, 2007

The Jewel, Mars

Full Moon and Mars ©2007 Chris W. Johnson

Mars gleams like a tiny jewel
dangling from the full moon on an invisibly fine thread.

Wednesday, December 19, 2007

Wish I'd Thought of That

The Ultimate Present. Although, sooner or later, I think my neighbors, and even local law enforcement, would have objected to the detonations.

Wednesday, December 12, 2007

Spans of Night

When I visited the Bamberger Ranch on the 4th, I was down there to catch some fall color that Margaret told me had just appeared. I was also cleared to enter the chiroptorium, where I intended to shoot a spherical panorama - something I'd been waiting the better part of a year to try. As usual, I drove down there in the wee hours to avoid traffic. The air was dipping below freezing, and the skies were as clear, and the stars as bright, as you can hope for in these parts. On the way out there, I glimpsed two meteors, and saw a third once I'd arrived at the ranch and encamped up at the old windmill near the red pens. It was a gorgeous night, apart from the cold. My plan was to setup a camera looking north past the windmill and let it shoot 30 second exposures until it ran out of power or storage. While it did that, I was going to get some sleep. The point of the exercise was to capture a large number of frames of the moving stars, which I would later attempt to merge into a single image - one of those images you've probably seen that shows the stars blurred into concentric circles around the pole star.

That worked out, except for two things: (1) I completely failed to interpret the compass display on my GPS unit correctly (frankly, it still doesn't make sense to me), and (2) I didn't manage to get to the ranch and start the camera until just a few hours before sunrise - not nearly enough time to capture the kind of motion I wanted, even if I had pointed the camera in the correct direction. Next time, I'll do better.

All the same, when I returned home with all of those sky photos, I set about writing the utility program I'd had in mind for merging the images without accumulating the light pollution that a single, multi-hour exposure would have done. The algorithm was trivial: from each pixel in every one of those photos, take the brightest components, and build a single image exclusively from those. Since the algorithm isn't summing the values of pixels or their components, the sky stays as black as it was in any one of those exposures (and the stars stay as bright), while the motion of the stars accumulates nicely.

The code worked fine and produced the following image from the pre-dawn exposures.

Night sky image. ©2007 Chris W. Johnson

It's not much of an image, but it proved the technique could work. Then, since I still had the much larger set of night sky images I'd shot earlier in the year during the Perseid meteor shower, I ran them through the code. Those frames produced a much more satisfying image:

Night sky image. ©2007 Chris W. Johnson

The windmill is illuminated because I had briefly pointed a little LED flashlight at it a number of times during the Perseid shoot. That trivial amount of light turned-out to be plenty.

So, my shoot on the morning of the 4th was useless, but it did get me to write the little image merge utility that I'd had in mind for a while, and that retroactively extracted a nice little image from my Perseid shoot back in August. A roundabout way of getting things done, but, hey, it worked. And, if you care about this sort of thing, by all means try it yourself; the utility is included below.

That useless shoot turned-up one other interesting thing, after careful examination: While I slept, and the pre-dawn sun began to brighten the sky and make the images useless for the merge experiment, the camera just happened to catch a meteor for me. Not a spectacular one, but a fine one that happened to be in just the right place at the right time to make a pleasant photo. Little space rock, I thank you.

Windmill and Meteor. ©2007 Chris W. Johnson

On the subject of little space rocks, it goes without saying that I've been looking forward to shooting the Geminid meteor shower that'll take place this Thursday-night/Friday-morning. I even placed a rush order for a battery grip for the camera, so that it could shoot for twice as long without me disturbing it. Unfortunately, it looks like the weather in this region is going to make seeing the Geminids impossible. Someday, with a bit of luck, I'll capture an ideal meteor photo, but it looks like I'll have to wait about eight months before I'll get to try again. Bloody clouds.

My Image Merging Utility

I can't be the first person to have come-up with the simple brightness merging algorithm I used to combine my night sky shots; more probably I'm the thousandth person. Nonetheless, since I don't know of any tool that does it, I enclose below the source code for the single-class Java application I wrote to perform the merge. (Consider it GPL-ed.) It makes no effort to be fast, just to be correct, short and clear. An implementation that included direct pixel access could be about four times faster, in my experience, and multi-processor support would be easy enough to add, but all of that would only clutter this little piece of code. And, performance aside, support for so-called "16-bit" images would be a worthwhile improvement. But I'll leave all that cluttering as an exercise for the reader, or for later, or both.

In any case, good luck with your own photos.

package com.mac.chriswjohnson.bmerge;


import javax.imageio.ImageIO;
import java.io.File;
import java.io.IOException;
import java.awt.image.BufferedImage;


/** BrightnessMerge is a program that combines the brightest elements of any number of image files into a single image
 *  file. The first parameter should be the name of the output image file. All other parameters should be the paths 
 *  of the directories containing the images that should be merged to produce the output image file. The directories
 *  may contain other directories.
 * 
 *  @author Chris W. Johnson
 */
public class BrightnessMerge {

    public static void main
    (
        final String[]          Args
    ) 
    throws Exception 
    {
        final int               ArgCount = Args.length;
        
        if (ArgCount == 0) {
            
            System.out.println("The first parameter, the name of the output file, is missing.");
            return;
        }
        
        final File              DestImgFile;
        
        if (Args[0].endsWith(".png"))
            DestImgFile = new File(Args[0]);
        else
            DestImgFile = new File(Args[0] + ".png");
        
        if (DestImgFile.exists()) {

            System.out.println("The output file, \"" + DestImgFile + "\", already exists. Please choose a different output file name.");
            return;
        }
        
        final BrightnessMerge CombinedImage = new BrightnessMerge();
        
        for (int ArgIndex = 1; ArgIndex < ArgCount; ArgIndex++) {
            final File              SrcImgsDir = new File(Args[ArgIndex]);
            
            if (SrcImgsDir.exists() == false) {
                
                System.out.println("The directory \"" + SrcImgsDir + "\" does not exist.");
                return;
            }
            
            if (SrcImgsDir.isDirectory() == false) {

                System.out.println("The item at \"" + SrcImgsDir + "\", which should be a directory of images, is not a directory at all.");
                return;
            }
            
            CombinedImage.mergeDir(SrcImgsDir);
        }

        System.out.println("All images merged.");
        
        CombinedImage.savePNG(DestImgFile);

        System.out.println("Done.");
    }
    
    
/** The image into which all other images are merged. */
    
    private BufferedImage       DestImg;
    
/** The width of DestImg, and of all input images. */
    
    private int                 Width;
    
/** The height of DestImg, and of all input images. */
    
    private int                 Height;


/** Merges all of the images found in a directory, or a hierarchy of directories, into our output image.
 * 
 *  @param SrcImgsDir           The directory of images to be merged, or a directory of other directories containing 
 *                              images to be merged.
 *  @throws IOException         If <code>SrcImgsDir</code> is not a directory, or does not exist.
 */ 
    private void mergeDir
    (
        final File              SrcImgsDir
    )
    throws IOException
    {
        System.out.println("Processing images in directory: " + SrcImgsDir);        
        
        for (final File SrcImgFile : SrcImgsDir.listFiles()) {
            
            if (SrcImgFile.isHidden())
                continue;
            
            if (SrcImgFile.isFile())
                mergeFile(SrcImgFile);
            else if (SrcImgFile.isDirectory())
                mergeDir(SrcImgFile);
        }
    }

/** Merges the contents of an image file into our output image.
 * 
 *  @param SrcImgFile           An image file in any of the formats supported by Java.
 *  @throws IOException         If <code>SrcImgFile</code> cannot be read.
 */
    private void mergeFile
    (
        final File              SrcImgFile
    )
    throws IOException 
    {
        final BufferedImage     SrcImg = ImageIO.read(SrcImgFile);
        
        if (DestImg == null) {
            
            Width   = SrcImg.getWidth();
            Height  = SrcImg.getHeight();
            DestImg = new BufferedImage(Width, Height, BufferedImage.TYPE_INT_RGB);
        
        } else {
            
            if (SrcImg.getWidth() != Width || SrcImg.getHeight() != Height)
                throw new IllegalArgumentException("All input images must be " + Width + " X " + Height + " pixels, but the image \"" + SrcImgFile + "\" is not.");
        }
        
        for (int Y = 0; Y < Height; Y++) {
            
            for (int X = 0; X < Width; X++) {
                final int               SrcPixel  = SrcImg.getRGB(X, Y);
                final int               SrcR      = SrcPixel >> 16 & 0xFF;
                final int               SrcG      = SrcPixel >>  8 & 0xFF;
                final int               SrcB      = SrcPixel & 0xFF;
                
                final int               DestPixel = DestImg.getRGB(X, Y);
                int                     DestR     = DestPixel >> 16 & 0xFF;
                int                     DestG     = DestPixel >>  8 & 0xFF;
                int                     DestB     = DestPixel & 0xFF;
                
                if (DestR < SrcR)
                    DestR = SrcR;
                if (DestG < SrcG)
                    DestG = SrcG;
                if (DestB < SrcB)
                    DestB = SrcB;
                
                final int               NewDestPixel = DestR << 16 | DestG << 8 | DestB;
                
                if (NewDestPixel != DestPixel)
                    DestImg.setRGB(X, Y, NewDestPixel);
            }
        }

        System.out.println("Processed image: " + SrcImgFile);
    }

/** Saves the output image to the specified output file in the Portable Network Graphics (PNG) format.
 * 
 *  @param DestImgFile      The file to which our output image will be written.
 *  @throws IOException     If the file could not be created, or written-to.
 */
    private void savePNG
    (
        final File          DestImgFile
    ) 
    throws IOException
    {
        System.out.println("Saving combined image to: " + DestImgFile);
        ImageIO.write(DestImg, "png", DestImgFile);
    }
}

Monday, December 10, 2007

The Bamberger Ranch Chiroptorium - Main Chamber VR Panorama

The chiroptorium is the artificial bat cave constructed by the Bambergers to try to bring a substantial bat population to the ranch. Like many others, I've photographed it from outside, but all that really shows is the big, artificial cave mouth. I haven't seen any photos of the interior since it was under construction (it was a work of art before its surface was covered with concrete and the whole structure buried). So, I've thought for a while that a spherical panorama ought to be shot inside it in order to clearly show people the end-result of that construction. However, the chiroptorium's success, in the form of the 120,000 Mexican free-tail bats that occupied it this year, kept me from entering to shoot a panorama before last Tuesday, December 4th, because we didn't want to risk disturbing the bats. With the arrival of winter the free-tails have returned to Mexico, so the chiroptorium's only residents are many hundreds of cave myotis tucked-away in the warmth of a pair of internal bat boxes, and untold legions of flesh-eating dermestid beetles occupying the foot or more of accumulated bat guano that covers the cave floors wall-to-wall. The consensus was that I could enter without disturbing the myotis, provided that I wasn't disturbed by the flesh-eating beetles. A pair of rubber boots proved to be adequate for keeping the beetles at bay, and the shoot went smoothly, to the continuous accompaniment of the chattering myotis.

The result is the following high dynamic-range, high-resolution QuickTime VR panorama. The panorama is 8.4 MB, so it may take some time to load.

Chiroptorium Main Chamber. Click to View.

The panorama initially looks from the main chamber into the exit tunnel. If you were an exiting bat, that's where you'd be headed. The tunnel to the right of that leads to the smaller second chamber, which leads in-turn to the very small, inner-most third chamber. The main chamber shown here is the best exemplar of the chiroptorium's design. Key features include the following:

  • The chiroptorium was designed as sequence of intersecting domes. The domes were formed from an elaborate weave of rebar, which was then covered with metal mesh. Concrete thickened with fiberglass was sprayed onto the mesh (without that thickener, the concrete went right through the mesh). The richly textured interior surface created by that concrete is a design feature - it provides innumerable footholds for the bats. When construction was complete, the chiroptorium, built at the bottom of a small valley, was covered with earth, thus effectively filling-in much of the valley, and transforming the domes into a cave. (A large drain pipe prevents the remaining portion of the valley from forming a lake behind the cave, and keeps the cave floor dry.)
  • The floor is covered with years of accumulated bat guano, which, when I encountered it, was a dry, almost fluffy layer of material, that must have been somewhere around a foot deep over the entire area of the floor. It is home to (among other things) a large population of flesh-eating dermestid beetles, which eat fallen bats. (Some of the white specks visible on the surface of the guano are bones. Some of the black, shiny specks are the beetles.) The invertebrate population of the chiroptorium is being studied by researchers who are interested in learning how the invertebrate populations typically found in bat-occupied caves establish themselves. Since the chiroptorium began as a clean slate, so to speak, the chiroptorium probably represents a unique opportunity for such studies.
  • The ceiling of the dome is interrupted by three concentric vertical rings of concrete. They provide additional surface area on which bats may roost.
  • Two bat boxes, one square and one rectangular, hang from the ceiling. They were a part of the chiroptorium from the beginning. Their purpose was to provide roosts for the initial population of bats. Their compactness is a feature with a small population: tightly packed into those boxes, the bats keep each other warm. At the time this panorama was shot, both boxes were filled with cave myotis bats, which find the boxes to be ideal winter roosts.
  • The large tubes extending up through the ceiling are ventilation shafts, though they are not used while bats are present.
  • The wood set into the wall covers the viewing gallery's windows. Those windows turned-out to be the reason that the chiroptorium went for years without acquiring a population of bats. I've heard conflicting explanations of why the windows were a problem for the bats, but, whatever the reason, once the windows were covered, the bats found the chiroptorium (now minus its "torium"-ness) a very agreeable home.

    Margaret Bamberger supplies some details on the conflicting explanations regarding the windows: "Either/or or both are true (probably): (1) When flying around in daylight bats use eyesight for navigation. If light came through the window from the other side, it would look like an opening, and they'd fly into it. (2) Glass doesn't send back a signal to the bat's echolocation, because it has no surface variation, and the bats don't know that it is there. Bats will swoop down and try to drink from very flat surfaces that are horizontal. They have no experience with such surfaces on a vertical plane, except where humans put them. In a cave built for them it becomes a huge problem."

    (I first met David Bamberger at a Bat Conservation International (BCI) outing to Bracken Cave, whose purchase he had years earlier organized on behalf of BCI. Having seen an article about the construction of the chiroptorium in the BCI newsletter years before, I asked him how the project had turned-out. He paused, then said unhappily "let me put it this way: I'm currently housing bats at five thousand dollars a head." During that period, I gather the chiroptorium was labelled by some as "Bamberger's Folly." It took years to realize that the observation gallery windows were the problem, but as soon as the windows were covered, the bats came, stayed, and bred, making the chiroptorium a bigger success with each passing year.)

Margaret Bamberger can say a great deal more about every aspect of the chiroptorium, and what they've learned from it about constructing artificial bat habitat. Post questions to her blog as comments, and I'm sure she'll have plenty to say.

Photographic Notes

This panorama is composed of 12 segments, each photographed at three different exposures: 30, 8 and 2 seconds, all at f8 and ISO 400. Nothing less could produce useful exposures using only the dim, indirect light coming in through the entry tunnel. The images, totaling 364 megapixels, were assembled into three separate panoramas, which were combined into a single high-dynamic range image, then tonemapped down to a range that monitors can handle. Unfortunately, using only three exposures per segment still left the entry tunnel over-exposed, which is exactly the sort of thing that high-dynamic range photography is meant to prevent. My camera will only take three different exposures automatically, so taking additional exposures would have meant a lot of manual manipulation of the camera. Such manipulation brings with it the danger of causing the tripod to shift its footing, thereby ruining the precise alignment of the images. (The spiked feet of my tripod never did find the concrete floor - eventually I just made them stable in the guano.) That limitation may have been fortunate, however: the HDR and image manipulation applications that I depend on kept choking on the size of these images. In the end, it seemed like pure luck that I finally got them to do their jobs. An additional exposure or two might have prevented the tools from ever doing their jobs.

With the three panoramas finally combined into a single rectilinear image (360° by 180°), that image was broken into six images, corresponding to the faces of a cube. Doing so made it possible to heavily retouch the image of the floor to remove the tripod, the panoramic head and its counter-weight from the image. (In other words, the floor seen beneath the caption and copyright notice is an artificial construct.) The cube faces, including the heavily retouched floor face, were then combined to make the final QuickTime VR panorama.

Thursday, December 6, 2007

Fragments of Fall

Reports from Margaret Bamberger of trees displaying their fall colors brought me back to the Bamberger Ranch on Tuesday, November 4th. Walking the Rachel Carson trail did, indeed, lead me to the colors. They were impressive, though confined to the young, scattered maples. However, what they lacked in quantity they made up for in intensity, as the high-dynamic range images below attest.

Due to the fact that most of the other trees in the area had already shed their leaves, I didn't find any scene along that trail that I thought would make a pleasing panorama. However, the grasses continued to be impressive, and as sunset approached, I setup in a tall stand of grass whose seed heads were catching the light beautifully, operating the pano rig while crouching beneath the tripod, in the hope that I could stay out of the shot, without moving around the camera and trampling the near-field grasses that were to be the focus of the pano. That worked-out alright, but the wind never did cooperate. With the last rays of sunlight rapidly disappearing up the stalks of grass, I shot the pano out of desperation, knowing it couldn't work. But, below, a few frames of that failed pano provide good samples of what I was trying to capture.

By the way, the one place where wind didn't interfere with my panoramic efforts, was my first target of the day: the chiroptorium, the artificial bat cave constructed by the Bambergers to try to bring a substantial bat population to the ranch. Like many others, I've photographed it from outside, but all that really shows is the big, artificial cave mouth. I haven't seen any photos of the interior since it was under construction (it was a work of art before its surface was covered with concrete and the whole structure buried). So, I've thought for a while that a spherical panorama ought to be shot inside in order to clearly show people the end-result of that construction. However, the chiroptorium's success, in the form of the 120,000 Mexican free-tail bats that occupied it this year, kept me from entering to shoot a panorama before now, because we didn't want to risk disturbing the bats. With the arrival of winter, however, the free-tails have returned to Mexico, so the chiroptorium's only residents are many hundreds of cave myotis tucked-away in the warmth of a pair of internal bat boxes, and untold legions of flesh-eating dermestid beetles occupying the foot or more of accumulated bat guano that covers the cave floors wall-to-wall. The consensus was that I could enter without disturbing the myotis, provided that I wasn't disturbed by the flesh-eating beetles. A pair of rubber boots proved to be adequate for keeping the beetles at bay, and the shoot went smoothly, to the continuous accompaniment of the chattering myotis. The result should be a good high dynamic-range spherical panorama as soon as I have time to assemble it. Stay tuned.

Tuesday, December 4, 2007

Sunset in High Lonesome

“Bamberger Ranch, Sunset in High Lonesome” ©2007 Chris W. Johson

The last of the panoramas shot on 27-Nov-2007 at the Bamberger Ranch. It could do with a bit more tinkering, mostly with the white balance, but it's pretty fair as it stands, IMHO. Happily, it suggests that my difficulties with Annie Leibovitz and the wind were not the undoing of that day's shooting. More importantly, I hope that it manages, in some small way, to share the beauty of that place and time with those who can appreciate it, but could not be there. Apologies for the tiny image, but Blogger automatically imposes these size limits on images. Once I'm finished working with the image, I'll place a high-resolution version of it on my panoramas page.

Sunday, December 2, 2007

Bamberger Ranch Journal

My friend, Margaret Bamberger has started a blog about the Bamberger Ranch Preserve, the Bamberger Ranch Journal. Ranchers, conservationists, sustainable-use advocates, nature lovers, and even people in general, may all find items of interest there. Please welcome Margaret to the world of blogging, and, if you have any questions relating to the preserve and its work, I expect that leaving a comment for her would be likely to provoke an informative response.