Monday, 15 June 2009

Consider overriding Equals and Hashcode as a general rule

In both C# and Java, objects have methods for checking equality and producing hashcodes. For the purposes of this post I'll mostly refer to the java methods equals and hashcode, but C# has the equivalent methods Equals and GetHashCode respectively.

If you have two objects, and you wish to test their equality, the equals method is the obvious choice. The default implementation in java is simply to check if the references are the same, i.e. the default implementation of this:

objA.equals(objB)

is the same as this:

objA == objB

However, value objects such as String, have a different implementation of equals:

public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = count;
if (n == anotherString.count) {
char v1[] = value;
char v2[] = anotherString.value;
int i = offset;
int j = anotherString.offset;
while (n-- != 0) {
if (v1[i++] != v2[j++])
return false;
}
return true;
}
}
return false;
}


This implementation actually checks the value of another string that is passed to it, and will return true if the type and the value match.

Seeing this implementation, I postulate the following: All objects that represent a value should override equals and by extension hashcode.

You might argue that this is pointless if you aren't performing comparisons between these objects of this type. What is the point of writing and maintain code that never gets executed at any time within your application? Well, there are a few reasons.

Firstly, utilities such as java's Collections classes use equals and hashcode to manage their contents and to spot duplicates. Since the default behaviour is assume that different instances are not equal, it is possible, for example, to have multiple instances of the same value object in a hashmap key set. Bugs like this are subtle and can prove difficult to spot. Often they might be missed during unit testing, because it is possible that the scenario where multiple instances with the same value may not have been considered.

Another reason to properly override equals regularly is that it aids testability. If you are using matchers for testing the following line will be a common one in your tests:

assertThat(objA, equalTo(objB));

If you are using the default implementation of equals, then what that line does is check that objA and objB are the same instance. That would mean that the above assertion would be equivalent to the following if you have not overridden equals.

assertThat(objA, same(objB));

This is clearly not the case. The intent expressed by equalTo and same is quite definitely different.

A third reason to implement equals and hashcode on your classes is that if you are producing code to be used by another group of individuals or any sort of API, you have no idea how those individuals intend to use your objects. Even if you aren't handling them in collections, they quite easily might.

However, as I alluded to earlier, there are reasons not to implement equals and hashcode on classes. The first that this is a lot of code to implement, test and maintain on many classes. Having said this, I would argue implementing them is still the right thing to do. There are a few cases where implementing these methods just really doesn't make sense. That would be on things like static utility classes which never have objects instantiated. Another example might be on objects where the instance itself can be considered the value, for example a node in a representation of a tree.

Tuesday, 9 June 2009

Shoot some film

I've been interested in photography for over 8 years now, and in almost all that time, I've been shooting digital. I shot film as a child, but never seriously and only as a small hobby. I learnt the basics of exposure, composition and processing in the digital world.

When I found my mother's old Nikon F-501, I realised it was about time I shot some film. I have some old Nikkor lenses which I adapt to my Canon 5D, primarily my Nikkor 55mm f/1.2. This lens is by far my favourite, and I was excited to at the chance to try it on a new (old) medium.

So I put a roll of Kodak Ultramax 36 exp ISO 400 film through it, and this is what I found:

Shooting film tells a story. You think so much more about every single shot when you have a limit of 36 exposures. As a result, you don't end up with 20 shots of the same cat from about 3 angles. Each shot matters and as you go through the roll of the film, you can chart how your life has progressed for the relatively short period.

A month in film

You have flexibility. One of the extremely useful things about digital is that you have variable ISO between shots. Some DSLR bodies will even vary it for you based on available light. However if you ever want to shoot outside that range, you're stuck. Having a film body to hand lets you put through a roll of Kodak HIE or a roll of film like Fuji Velvia, which according to Kevin O'Mara produces delicious colour. Shooting film gives you more choices about how your pictures come out, even if you can't change it shot to shot.

Old lenses become new lenses. If you can get ahold of a cheap camera body with the same lens mount as your current lens set, then all those lenses you have will suddenly be twice as useful, and may produce new and interesting effects.

You get to play with full frame. Although full frame DLSRs like the 5D mk II and the D700 are in reach of amateurs, they are still at the expensive end of that reach. Most DSLRs used by amateurs have a cropped sensor, and shooting film means that you get the chance to see what life is like through a full frame viewfinder for a fraction of the initial outlay.



There are, however, a few problems with shooting film, and reasons why I could never abandon my digital background. The first is lack of feedback. I like to know if my image has been exposed properly before I leave the scene, in case I need to shoot another. Two weeks later when I've had the film developed is too late. Having said that, the skills and rules I have learnt from digital served me well. I had a good idea as to what was going to work, and in the end had no throwaway shots. It's also probable that the fact that you can push film a couple more stops when processing than you ever can with digital helped a great deal.

The most notable drawback however is cost. While the initial cost of buying a film SLR body is very little, the running costs of shooting film are prohibitive. Buying film and having it processed costs too much to make it a viable long term alternative, however that may just encourage me to develop it myself. I'll let you know how that goes...

Monday, 8 June 2009

Bringing back pinhole

The net is awash with guides on how to make pinhole cameras by various means. Many still use the age old design that I recall from kids science project books. These involve taking something akin to a shoe box and placing a piece of film at one end, with a pinhole at the other. While the design is simple, it does involve a lot of fuss. You need darkroom conditions to make the thing, you have to develop the film and you'll have a lot of difficulty determining exposure time.

There are however a couple of very simple guides for turning your digital SLR body into a pinhole camera for basically no added cost. For example, this and this.

I tried out the former since I didn't have my extension tubes with me:

The barn

The attic

Mustn't flinch

As you can see, blurry and noisy, but not without a certain charm. I think, if used properly, with a smaller pinhole and longer exposures at lower ISO values, the results may be more encouraging. I certainly found using a cable release and mirror lock up very useful:

Time lapse - Part 2 - Animating images

In my previous post I described how to generate an image sequence for time lapse movies. In this post, I'll discuss the different ways to turn those sequences into real video. In terms of ease of use, QuickTime Pro is my favourite. To create a film, it's as easy as:



Then, simply choose the framerate you desire, and Robert's your dodgy aunt.

This will produce a silent animation of the image sequence you created. I'm told that you can similar results using the open source app ffmpeg. A colleague of mine provided this little snippet for its use:


ffmpeg -sameq -i timelapse-%d.jpg timelapse.mpg

where:

-sameq: keep the same quality of the input in the output,
so no extra compression is used
-i: take all files starting with 'timelapse-' and a number
(%d = digits) plus '.jpg' in the current directory


However, once you have this film, it's still likely that it is too large in dimensions for general viewing. In this case, you have two options:

  • Resize the source images before making the film

  • Resize the generated film


Both are valid approaches, and some simple searches around batch resizing images will provide solutions to the former. QuickTime Pro will resize the generated films provided you use the Export feature.



QuickTime Pro can also be used to add a soundtrack to a movie:

  1. Open both the video and a similarly lengthed audio track in QuickTime Pro.

  2. Go to the audio track, select all, then copy.

  3. Go to the video track, then use:


  4. Save.




Once you have a video which you are happy with, you need to choose where to display it. Vimeo, flickr and youtube all have HD playback, but in some cases require a paid membership. It is important to remember that each can have contraints on filesize, duration, or both, depending on the kind of account you have, so ensuring that your videos aren't too big is important.

Sunday, 7 June 2009

Time lapse - Part 1 - Generating image sequences

In my photographic travels, I've recently taken a real interest in time lapsing. Having done some research in the area, I've found it is relatively easy and inexpensive for an amateur such as myself to produce one. To that end, I thought I'd give a couple of quick tutorials on how to produce a simple timelapse movie that should work on both OS X and Windows.



The above is a time lapse video I made last night from the top floor of my parents house in France. Despite the fact that chunks of it look like day time, it was mostly filmed in the hours from midnight to about 3am. The illumination comes largely from the moon, so the film almost goes black for a section when the cloud cover becomes very heavy.

So the first thing you have to do when producing a timelapse movie is to produce a sequence of images. This can be done in two ways using a Canon SLR (those of you not shooting with a Canon SLR should skip to the second method). The first and cheapest is to use the remote capture software that comes with your camera. Assuming you have installed it on your computer, when you connect your camera, you should be presented with this:



Start the remote capture application and you should be able to remotely change camera settings using this dialog box:



Once you have the correct settings for the scene, you can start a time lapse using the following menu item:



There are, however, problems with using this method to generate your image sequence. Firstly, your camera has to be tethered to your computer. That means you are either limited by a laptop battery, or your computer needs to be plugged into the mains. If you have a desktop, it's not likely to be very portable. Also, Canon's software is buggy in my experience, and limits you to batchs of 999 images and a minimum recycle time of 5 seconds.

However, as I mentioned earlier, there is another way of generating an image sequence. You can use a timer, such as the TC-80N3 from Canon. The major problem with this device is that it is very expensive for what it is. Fortunately, eBay is to the rescue, with many cheap and cheerful alternatives available from China. This is mine:



Note: This timer and the TC-80N3 only work with a subset of Canon SLR bodies. Check that the timer you are buying works with your body.

It is possible to buy a timer like this one for most SLR bodies, and it has many advantages. It allows untethered shooting, unlimited batch sizes and image periods as short as 1 second. It also has a host of other features such as controlled long exposures in bulb mode, and delayed exposures.

At this point I should mention a couple of things. There are two factors that will limit the number of images in your image sequence. These are, your battery and your memory card. There are a couple or things you can do to maximise both.

To maximise your battery, turn off image reviewing. This stops the LCD screen on the back of your camera being switched on for every single exposure. You aren't going to be watching every single one, so it's just a pointless waste of battery.

To maximise your memory card, switch the image resolution to the smallest JPEG setting you can. Shooting in RAW is pointless, as you'll have to just convert to JPEG anyway and you aren't going to tweak the settings for several hundred or thousand images. Shooting in large resolutions is equally silly as noone watches video in 4372 x 2906.

Finally, when choosing your exposure mode, if at all possible, choose manual exposure. If you allow the camera to meter, it will meter on every single shot. Often your camera will not consistently meter between images, and as a result your video will flicker, when you animate your images together. Also, set focus to manual as well, other wise your camera will attempt a focus lock on each exposure. Particularly in dark situations this can cause the camera to miss shots, as it hunts for focus or refuses to expose because it cannot find focus at all.

In my next post I'll discuss ways to turn your image sequence into a movie, with a soundtrack if desired.