Many weeks ago, I ended up writing a script to take a time series of raw photographs shot at arbitrary exposures from my DSLR, and turn them into a set of correctly-exposed images suitable for stitching together into a video. I initially completed a couple of videos taken in Melbourne, and yet, when I attempted to repeat the same process in Sydney, the script ended up having issues with changes in exposure.
This initially seemed a little odd to me - for the photos taken in Melbourne, I changed the exposure as time went on to allow for the light conditions, and I didn't have any jarring changes between frames. However, the photos taken in Sydney had changes in exposure that were completely out of whack with the settings I had used.
Let's take for example two photos from the Sydney set. Both taken with the same lens, both at f/4.5, both at ISO 100; one photo at 1/80s, the other at 1/60s. You'd expect then, the photo taken at 1/60s to be 1/3 brighter than the other exposure, so knocking down the exposure compensation for the second shot to -0.33 should do it, right? Well... not exactly. After some experimentation, it turned out that the difference between the two shots was about -0.1 EV.
The first (misguided) reason that came to mind to explain the disparity was non-reciprocity of the sensor - that is, doubling the number of photons coming through in the shot would not double the exposure read out from the sensor. This can be a problem with some films during long exposures, but really shouldn't be an issue with DSLRs, especially not with an exposure time of 1/60s. After trying a few other avenues to explain it, I gave up on the set of photos - perhaps there was a bug in the firmware, or some other glitch that caused the issue.
Fast-forward to today, where I took a few sets of time-lapse photos in New York. Jump the exposure down (and back up again) manually with the light level, and the photos appear to behave as observed in Melbourne - calculating the EV for each frame then taking the difference ensured the exposures lined up.
Then, the penny dropped. The photos I took in Sydney were in aperture priority mode, and the photos taken in Melbourne and New York were in manual mode. It turns out, there's a number of EXIF values that correspond to aperture and exposure time, and by default, exiv2 displays Exif.Photo.ExposureTime and Exif.Photo.FNumber - the 'as displayed on camera' settings, and not the actual timings from the camera.
So, you would think given they differ from the above values, that Exif.Photo.ShutterSpeedValue and Exif.Photo.ApertureValue are a couple of aptly-named entries that correspond to the actual timings? Not quite.
Canon, in their infinite wisdom, decided that the actual timings belong in a vendor-specific block of the EXIF data, and plugging these proprietary entries into the EV formula gives a perfect result for the "broken" images.
EXIF might be a useful standard, but when camera manufacturers use their own metadata block for standard data, they're doing it utterly and completely wrong. I think it might be well time for me to rewrite the processing tool to take vendor-specific information into account.