3.2.1. Contrast Stretching

Consider a scalar (gray value) image \(f\) with values \(f(\v x)\) that are only in a subset of the possible scalar values (of course dependent on the range of the image). E.g. consider a gray value image \(f\) with possible range \(R=[0,1]\subset\setR\) but whose values are in the range from \(a\) to \(b\).

Show code for figure
 1import numpy as np
 2import matplotlib.pyplot as plt
 3from ipcv.utils.files import ipcv_image_path
 4
 5a = plt.imread(ipcv_image_path('lowcontrast.png'));
 6N=50; bins = np.linspace(0,1,N+1);
 7ha, ea = np.histogram(a.flatten(), bins=bins);
 8b = (a-a.min())/(a.max()-a.min());
 9hb, eb = np.histogram(b.flatten(), bins=bins);
10plt.figure(1, figsize=(10,10)); plt.clf();
11plt.subplot(221); plt.imshow(a, vmin=0, vmax=1); plt.axis('off');
12plt.title("Low contrast orginal");
13plt.subplot(223); plt.imshow(b, vmin=0, vmax=1); plt.axis('off');
14plt.title("Contrast Stretched");
15plt.subplot(222); plt.bar(ea[:-1], 1.0*ha/np.sum(ha), width=ea[1]-ea[0] ); plt.xlim(0,1);
16plt.title("Histogram of low contrast image");
17plt.subplot(224); plt.bar(eb[:-1], 1.0*hb/np.sum(hb), width=eb[1]-eb[0] ); plt.xlim(0,1);
18plt.title("Histogram of contrast stretched image");
19
../../../_images/contraststretch.png

Fig. 3.7 Contrast Stretching.

The point operator:

\[g(\v x) = \phi(f(\v x))\]

with:

\[\phi(v) = \frac{v-a}{b-a}\]

results in an image \(g\) that uses the entire range of gray values from 0 to 1.

Assuming we have overloaded the arithmetical operators to work on images we may write:

\[g = \frac{f-f_\text{min}}{f_\text{max}-f_\text{min}}\]

In Python/Numpy we can write:

g = (f-f.min())(f.max()-f.min())

3.2.1.1. Exercises

  1. Given an 8-bit gray value image \(f\), i.e. \(f(\v x)\in[0,255]\subset\setZ\), what is the point operator that stretches the contrast of the image to the entire possible range.

  2. Explain why contrast stretching of a digital image cannot always lead to satisfactory results when the original image was very very dark (or very very light).

  3. Contrast stretching of color images is not a trivial generalization of what is discussed for scalar images.

    1. Explain that scalar constrast stretching of the Red, Green and Blue channels (images) independently is not a good idea.

    2. Let’s first change the color model from RGB to HSV. And then stretch the contrast in the V image and use the new V values together with the original H and S values. Implement this contrast stretching algorithm. Why is this contrast stretching method leading to reasonable results?