Activity 5: Enhancement by Histogram Manipulation
For this activity, I chose a low-light portrait that I shot at the Light Bridge at the Mind Museum (Fig.
1) last April. I imported it as uint8
for ease in the histogram
manipulation later on (something to do with indexing). Its histogram is shown in Fig.
1e. Notice that the histogram values range only from 0 to 226. The “spike” at the
end most likely corresponds to the clipped highlights evident in the light stripes that can be seen in the
original, unprocessed image. This spike is also reflected in its CDF, shown in Fig.
1i.
The first order of business is contrast stretching, which is essentially
stretching the histogram so that it encompasses the entire data space
available for the data type, in this case, 0 to 255. We first convert the
image to float32
by dividing it by 255 in order to constrain the
pixel values between 0 and 1. Since the global maximum of the original image
is 226, no pixel will have an exact value of 1. We want to stretch the data so
that its maximum is exactly 1, so we transform the pixel intensities [1]
according to
We then cast the image back into uint8
by multiplying by 255 and
rounding off. The result of this process is shown in Fig.
1b. At face value, there is no discernible change
since the global maximum of the original image is fairly close to 255. However,
in the eyes of a photographer, there are substantial contrast & detail enhancements,
particularly in the regions with rapid light falloff, such as on the shirt. If
you zoom in quite a bit, the side of the face which is better lit has more pronounced
details. The light stripes also appear less clipped, and are now a tad brighter.
Looking into its histogram (Fig.1f), we see that the brighter range of
pixels are now more even, and now encompass the full range of values up to
255, and the “stretching” is evident by the lack of some pixels in the lower
range. The CDF (Fig. 1j) also reflects
a smoother increase in the upper range of values.
Next, we perform histogram equalization. Generating the desired CDF (Fig.
1k) is trivial: we just use
Finally, we try to simulate a nonlinear response by generating a sigmoid CDF (Fig. 1l) of the form
and scaling it to uint8
then rounding off. The resultant image can
be seen in Fig. 1d, and its histogram in Fig.
1h. Once again, the image appears more properly
exposed, but now is high in contrast. We can also see in the histogram that the
middle values are stretched more than the outer values.
Upon further reading, this is actually the method used for a technique called adaptive equalization [2]. The CDF is a nonlinear response, usually of a sigmoid-like shape which is shifted along the x-axis and/or varied in slope, depending on where most of the original pixel values are clustered, and I generally use this to correct the exposure of images without blowing out the highlights or crushing the shadows. I also recognized the S-curve of the CDF and its effect on the image, and I realized that the CDF is actually what is called the tone curve in photo editing programs such as Lightroom and Photoshop. To test this, I tried to perform a technique called crushing the blacks/whites, which is used to simulate a faded film look, wherein the tone curve is shaped like a sigmoid, but the endpoints are clipped, i.e., the global minimum should be greater than 0 and the global maximum should be less than 255 sort of like the opposite of contrast stretching. To do this, I generated a sigmoid CDF (Fig. 2a) with a bias and scaled it to a value less than 255, so that its minimum and maximum y values are 42 and 197, respectively. Using the same process as before, lo-and-behold, I got the expected result in Fig.2b, and it definitely looks like it was taken with the classic Kodak Tri-X film. Its histogram in Fig.2c also shows the squeezing of the pixel values and con rms that the technique acts like contrast compressing.
Figure 2: “Crushed blacks/whites” post-processing technique using histogram manipulation.
References
M. N. Soriano, Enhancement by histogram manipulation (2019).
S. van der Walt, J. L. Schonberger, J. Nunez-Iglesias, F. Boulogne, J. D. Warner, N. Yager, E. Gouillart, T. Yu, and the scikit-image contributors, Histogram equalization (2014).