\[ \begin{align}\begin{aligned}\newcommand\blank{~\underline{\hspace{1.2cm}}~}\\% Bold symbols (vectors) \newcommand\bs[1]{\mathbf{#1}}\\% Differential \newcommand\dd[2][]{\mathrm{d}^{#1}{#2}} % use as \dd, \dd{x}, or \dd[2]{x}\\% Poor man's siunitx \newcommand\unit[1]{\mathrm{#1}} \newcommand\num[1]{#1} \newcommand\qty[2]{#1~\unit{#2}}\\\newcommand\per{/} \newcommand\squared{{}^2} \newcommand\cubed{{}^3} % % Scale \newcommand\milli{\unit{m}} \newcommand\centi{\unit{c}} \newcommand\kilo{\unit{k}} \newcommand\mega{\unit{M}} % % Percent \newcommand\percent{\unit{{\kern-4mu}\%}} % % Angle \newcommand\radian{\unit{rad}} \newcommand\degree{\unit{{\kern-4mu}^\circ}} % % Time \newcommand\second{\unit{s}} \newcommand\s{\second} \newcommand\minute{\unit{min}} \newcommand\hour{\unit{h}} % % Distance \newcommand\meter{\unit{m}} \newcommand\m{\meter} \newcommand\inch{\unit{in}} \newcommand\foot{\unit{ft}} % % Force \newcommand\newton{\unit{N}} \newcommand\kip{\unit{kip}} % kilopound in "freedom" units - edit made by Sri % % Mass \newcommand\gram{\unit{g}} \newcommand\g{\gram} \newcommand\kilogram{\unit{kg}} \newcommand\kg{\kilogram} \newcommand\grain{\unit{grain}} \newcommand\ounce{\unit{oz}} % % Temperature \newcommand\kelvin{\unit{K}} \newcommand\K{\kelvin} \newcommand\celsius{\unit{{}^\circ C}} \newcommand\C{\celsius} \newcommand\fahrenheit{\unit{{}^\circ F}} \newcommand\F{\fahrenheit} % % Area \newcommand\sqft{\unit{sq\,\foot}} % square foot % % Volume \newcommand\liter{\unit{L}} \newcommand\gallon{\unit{gal}} % % Frequency \newcommand\hertz{\unit{Hz}} \newcommand\rpm{\unit{rpm}} % % Voltage \newcommand\volt{\unit{V}} \newcommand\V{\volt} \newcommand\millivolt{\milli\volt} \newcommand\mV{\milli\volt} \newcommand\kilovolt{\kilo\volt} \newcommand\kV{\kilo\volt} % % Current \newcommand\ampere{\unit{A}} \newcommand\A{\ampere} \newcommand\milliampereA{\milli\ampere} \newcommand\mA{\milli\ampere} \newcommand\kiloampereA{\kilo\ampere} \newcommand\kA{\kilo\ampere} % % Resistance \newcommand\ohm{\Omega} \newcommand\milliohm{\milli\ohm} \newcommand\kiloohm{\kilo\ohm} % correct SI spelling \newcommand\kilohm{\kilo\ohm} % "American" spelling used in siunitx \newcommand\megaohm{\mega\ohm} % correct SI spelling \newcommand\megohm{\mega\ohm} % "American" spelling used in siunitx % % Capacitance \newcommand\farad{\unit{F}} \newcommand\F{\farad} \newcommand\microfarad{\micro\farad} \newcommand\muF{\micro\farad} % % Inductance \newcommand\henry{\unit{H}} \newcommand\H{\henry} \newcommand\millihenry{\milli\henry} \newcommand\mH{\milli\henry} % % Power \newcommand\watt{\unit{W}} \newcommand\W{\watt} \newcommand\milliwatt{\milli\watt} \newcommand\mW{\milli\watt} \newcommand\kilowatt{\kilo\watt} \newcommand\kW{\kilo\watt} % % Energy \newcommand\joule{\unit{J}} \newcommand\J{\joule} % % Composite units % % Torque \newcommand\ozin{\unit{\ounce}\,\unit{in}} \newcommand\newtonmeter{\unit{\newton\,\meter}} % % Pressure \newcommand\psf{\unit{psf}} % pounds per square foot \newcommand\pcf{\unit{pcf}} % pounds per cubic foot \newcommand\pascal{\unit{Pa}} \newcommand\Pa{\pascal} \newcommand\ksi{\unit{ksi}} % kilopound per square inch \newcommand\bar{\unit{bar}} \end{aligned}\end{align} \]

Dec 04, 2025 | 719 words | 7 min read

10.3.2. Task 2#

Learning Objectives:#

  • Utilize the pathlib library to access and manage files in a directory.

  • Manipulate matrices using NumPy.

  • Utilize matplotlib functions to display data.

  • Visualize the distribution of color intensities in an image.

Introduction#

Digital image processing plays a vital role across many areas of engineering, from medical diagnostics to satellite imaging. A key task in this field is analyzing an image’s color distribution, which can be visualized with a histogram where the x-axis represents intensity values (\(0\)\(255\) for 8-bit images) and the y-axis shows the frequency of each value. This visualization reveals an image’s brightness, contrast, and overall color balance, and provides insights that are essential for applications such as image enhancement, segmentation, and object detection.

An image’s overall brightness, or luminance, can be calculated using a weighted sum of its red, green, and blue channel values. The formula for luminance is given in (10.3), where \(R\), \(G\), and \(B\) are the linearized values of the red, green, and blue channels, respectively. The weights (\(0.2126\), \(0.7152\), and \(0.0722\)) are derived from the sRGB color space and reflect the human eye’s sensitivity to different wavelengths of light. You can read more about this here.

(10.3)#\[Y = 0.2126 \cdot R + 0.7152 \cdot G + 0.0722 \cdot B\]

Task Instructions#

Develop a Python program that produces a color distribution histogram of a user selected image to aid in image analysis. The program should allow the user to select from a list of all images in their images folder.

Before writing your program, create a flowchart of your algorithm and save it as py4_ind_2_username.pdf. Then, start coding by making a copy of the ENGR133_Python_Template.py Python template. Name your program py4_ind_2_username.py. You will also need to create a folder named images within the same folder as your Python script. Then, download each of the sample images in Table 10.10 and place them into your images folder. You can use your own images if you prefer, but ensure they are in a common format such as PNG or JPEG.

Table 10.10 Sample Images#

Image

Download

spongebob

spongebob.jpg,

landscape

landscape.jpeg

grayscale_landscape

grayscale_landscape.jpeg.

Your program should do the following:

  1. Construct a menu that lists all images in your images folder and allows the user to select one by entering its corresponding number. Be sure to include an option to quit the program.

    Hint

    The iterdir() method from Python’s pathlib module can be used to create a list all files in a directory.

    from pathlib import Path
    
    path = Path('images')
    files = list(path.iterdir())
    

    You will need to find a way to exclude non-image files from your menu. Path objects have a suffix method that may be useful for this. You can read more about it in the official documentation .

  2. Use Image.open(path) from the PIL module, where path is the path object of the file, to load the image selected by the user. Then convert the resulting Image object into a NumPy array.

  3. Verify that the data type of your image’s Numpy array is numpy.uint8, which will have pixel values in the range \(0\)\(255\). If the image has any other data type, raise a ValueError with the message “Image is not 8-bit.” You can check the data type of a NumPy array using its dtype attribute. See the official docs for usage details.

  4. Normalize the image’s pixel values to the range \(0\)\(1\) by dividing each value by \(255.0\). This is necessary for the subsequent linearization and luminance calculations.

  5. Linearize the pixels in the image by applying the transformation in (10.2).

  6. Using the linearized pixel values, calculate the average luminance of the image using (10.3) and display the result in the terminal.

  7. Create a figure with two side-by-side subplots using matplotlib. Show the linearized image on the left, and on the right, plot an intensity histogram showing the distribution of pixel values for each channel (red, green, and blue for color images, or gray for grayscale images).

    Hint

    For color images, plot three overlapping histograms (one for each channel) using the colors red, green, and blue. Use an alpha value of \(0.5\) to make the histograms semi-transparent so that overlapping areas can be seen. You will need to find a way to convert each channel’s values from a 2-dimensional array to a 1-dimensional array. Then the code to add the histogram for each channel to the plot should look something like this:

    axes[1].hist(channel_values, bins=256, color='red', alpha=0.5)
    

Sample Output#

Use the values in Table 10.11 below to test your program.

Table 10.11 Test Cases#

Case

User Input

1

[1, ‘q’]

2

[‘spam’, 2, ‘q’]

3

[3, ‘q’]

Ensure your program’s output matches the provided samples exactly. This includes all characters, white space, and punctuation. In the samples, user input is highlighted like this for clarity, but your program should not highlight user input in this way.

Case 1 Sample Output

$ python3 py4_ind_2_username.py Available images: 1. spongebob.jpg 2. grayscale_landscape.jpeg 3. landscape.jpeg Select an image (q to quit): 1 The average luminance of the image: 0.553 Available images: 1. spongebob.jpg 2. grayscale_landscape.jpeg 3. landscape.jpeg Select an image (q to quit): q

Case_1_output.png

Fig. 10.2 Case_1_output.png#

Case 2 Sample Output

$ python3 py4_ind_2_username.py Available images: 1. spongebob.jpg 2. grayscale_landscape.jpeg 3. landscape.jpeg Select an image (q to quit): spam Invalid choice, please try again.

Available images: 1. spongebob.jpg 2. grayscale_landscape.jpeg 3. landscape.jpeg Select an image (q to quit): 2 The average luminance of the image: 0.178 Available images: 1. spongebob.jpg 2. grayscale_landscape.jpeg 3. landscape.jpeg Select an image (q to quit): q

Case_2_output.png

Fig. 10.3 Case_2_output.png#

Case 3 Sample Output

$ python3 py4_ind_2_username.py Available images: 1. spongebob.jpg 2. grayscale_landscape.jpeg 3. landscape.jpeg Select an image (q to quit): 3 The average luminance of the image: 0.210 Available images: 1. spongebob.jpg 2. grayscale_landscape.jpeg 3. landscape.jpeg Select an image (q to quit): q

Case_3_output.png

Fig. 10.4 Case_3_output.png#

Table 10.12 Deliverables#

Deliverables

Description

py4_ind_2_username.py

Your completed Python code.

py4_ind_2_username.pdf

Flowchart(s) for this task.