Core Image filter for overexposed areas



Because cameras are not as smart as they should be when it comes to dynamic range, neither from a hardware nor software standpoint, and mostly because I'm not very good at using my camera, I sometimes get overexposed areas in my photos. An overexposed area is an area where pixels are all-white (i.e. lit up all the way). If the overexposed area is large enough, the photo gets an unpleasant "burned" look.

In our sample photo on the left side, the overexposed area is caused by the camera facing the light source - a common reason for overexposures as the camera's software computed the exposure based on the tulip's shaded side.


You can detect overexposed areas in a number of ways - on my Nikon D70 there's a highlights mode that blinks overexposed areas and there's a histogram on the green channel - the histogram less reliable because it does not show the red and blue channels as well so a relatively big value in the right hand side of the histogram might not necessarily mean an area has been overexposed.





Overexposed ares show up in the photo's histogram (see below for a RGB histogram - the white bar on the right side represents overexposed pixels - nearly 10% of all the photo's pixels have been overexposed).


Using Core Image filters, overexposed areas are very easy to identify.
With Core Image, using a histogram doesn't make sense - building a histogram is a computationally intensive task because it requires going through large amounts of data (a 6MB photo has, yes, 6MB of data) - it's better to write a filter that highlights the areas that have been overexposed.


Here's my (possibly naive) solution:



kernel vec4 replaceOverExposed(sampler image, __color color)
{
vec4 p = sample(image, samplerCoord(image));
float multiplier = 1;

float level = (p.r + p.g + p.b) / 3.0;

vec4 res;
res.r = level > .99 ? 1.0 : p.r;
res.g = level > .99 ? 0.0 : p.g;
res.b = level > .99 ? 0.0 : p.b;


return vec4(res.r, res.g, res.b, p.a);
}



Here's a rendering of the overexposed filter above applied on the tulip photo.
The filter has replaced all the overexposed pixels with a red pixel (p.r 1.0, p.g 0.0 and p.b 0.0).