Dec 04, 2025 | 719 words | 7 min read
10.3.2. Task 2#
Learning Objectives:#
Utilize the
pathliblibrary to access and manage files in a directory.Manipulate matrices using NumPy.
Utilize
matplotlibfunctions 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.
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.
Image |
Download |
|---|---|
|
|
|
|
|
Your program should do the following:
Construct a menu that lists all images in your
imagesfolder 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’spathlibmodule 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
suffixmethod that may be useful for this. You can read more about it in the official documentation .Use
Image.open(path)from the PIL module, wherepathis the path object of the file, to load the image selected by the user. Then convert the resultingImageobject into a NumPy array.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 aValueErrorwith the message “Image is not 8-bit.” You can check the data type of a NumPy array using itsdtypeattribute. See the official docs for usage details.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.
Linearize the pixels in the image by applying the transformation in (10.2).
Using the linearized pixel values, calculate the average luminance of the image using (10.3) and display the result in the terminal.
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.
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
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
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
Fig. 10.4 Case_3_output.png#
Deliverables |
Description |
|---|---|
py4_ind_2_username.py |
Your completed Python code. |
py4_ind_2_username.pdf |
Flowchart(s) for this task. |