Tuesday, 1 July 2014

Fixing the Leica M240 green shadows

Background
The Leica M240 camera exhibits discolouration (usually a green cast) in the shadows when images are push processed. Jim Kasson on his excellent blog spent some time investigating this issue and his summary http://blog.kasson.com/?p=3343 describes the problem in a nutshell:
The M240 exhibits nonlinear response at ISOs 200, 400, and 800, artificially depressing darker tones. The darker the tone, the greater the depression. In my previous noise floor tests, I saw the noise floor to be artificially depressed at these ISOs.
and:
This is probably the cause of the green shadows, since in most lighting conditions, for most subject matter, the green channel is the strongest. Depressing all the channels nonlinearly leaves the green channel the last one standing, so to speak. 
Because of the above, the green channel shadow shift is probably more accurately characterized as a shadow shift in the direction of the highest-valued raw channel.
From my experience I believe that Jim's analysis is spot on.

The idea
Now its perfectly possible to adjust an individual image in Lightroom or Photoshop to tune out the green cast reasonably effectively, however because this correction is occurring after the image has been demosaiced (and the non-linear gain error occurs in the mosaic data), you need different adjustments for each image.

Inspired by Jim's work I realised that if one could apply gain correction to the mosaic data in the raw file it should be possible to correct all images with one set of adjustments. This means in theory I could simply preprocess any files that were going to be significantly pushed or shadow recovered and not have to make individual colour correction adjustments on each image.

Luckily, processing M240 raw files is made a bit easier by the fact that the M240 uses the DNG format and Adobe make a source code DNG library available free in order to encourage adoption of the DNG format. So its possible to write a program that reads a M240 raw file, applies linearisation corrections each channel and then writes an output DNG file ready to load into Lightroom:

An added bonus
Whilst developing the program I also noticed that often in deep shadows the red channel in the raw file was clipped, whilst there was still useful data in the green and blue channels. It struck me that I could make an attempt to recover the lost detail in the clipped channel in much the same way that highlight recovery works to fill in structure from the non-clipped highlights. So I added a nearest neighbour interpolation to recover the lost shadow detail, plus a small amount of normal distribution noise to smooth/mask blotches in the deepest recovered shadows.

Does it work?
Definitely! Here's a quick couple of examples. Firstly, here is a comparison of an image pushed by 5 stops in Lightroom, the left image is the original DNG file and the right hand image is processed raw file:


Note the green cast to the grey card and in the color checker the second from darkest grey square. In the full size image the green cast is even more obvious, yet most is removed by the processing.

Underexposing by a further stop means we are running out of adjustments in Lightroom, so with a 5 stop push plus 100% shadows adjustment we get from an image that was 6 stops underexposed:


This is a really extreme case but even this shows a significant improvement in recovered image quality.

And one more, this is even more underexposed (it needed exposure +5, shadows +100% plus a tone curve in Lightroom). A 50% crop from a dark corner:



Yes its very noisy, but the colour cast problem is very effectively dealt with. My intention with real life images is not to have to push them quite this far, but it always good to know that the processing is capable of extracting the maximum from the image.