Practical 1: Loading & Displaying Images
Run this practical in Google Colab
Objective
To learn how to load, display, and inspect digital images using OpenCV and Matplotlib.
2. Description / Theory
Theory: A digital image is a 2D matrix of pixel intensity values. For an 8-bit grayscale image, each pixel holds a value between 0 (black) and 255 (white). Understanding image representation is the foundation of all image processing.
# ----------------------------------------------------------------------
# Install dependencies (uncomment for Google Colab)
# !pip install opencv-python-headless matplotlib numpy
import cv2
import numpy as np
import matplotlib.pyplot as plt
import os
# === AUTO-DOWNLOAD DATASET (works in Google Colab and locally) ===
import os, urllib.request, zipfile
# Choose which chapter to download (CH01-CH12)
CHAPTER = "CH02" # Chapter 2: Digital Image Fundamentals
DATASET_PATH = f"datasets/{CHAPTER}/"
DOWNLOAD_BASE = "https://www.imageprocessingplace.com/downloads_V3/dip3e_downloads/dip3e_book_images"
if not os.path.exists(DATASET_PATH) or not any(f.endswith('.tif') for f in os.listdir(DATASET_PATH)):
zip_name = f"DIP3E_{CHAPTER}_Original_Images.zip"
url = f"{DOWNLOAD_BASE}/{zip_name}"
print(f"Downloading {CHAPTER} dataset from imageprocessingplace.com...")
urllib.request.urlretrieve(url, "chapter.zip")
os.makedirs(DATASET_PATH, exist_ok=True)
with zipfile.ZipFile("chapter.zip", "r") as z:
for f in z.namelist():
if f.lower().endswith(".tif"):
fname = os.path.basename(f)
if fname:
with z.open(f) as src, open(os.path.join(DATASET_PATH, fname), "wb") as dst:
dst.write(src.read())
os.remove("chapter.zip")
print(f"Downloaded {len([f for f in os.listdir(DATASET_PATH) if f.endswith('.tif')])} images")
else:
print(f"Dataset ready: {len([f for f in os.listdir(DATASET_PATH) if f.endswith('.tif')])} images")
# List all available images
images = sorted([f for f in os.listdir(DATASET_PATH) if f.endswith('.tif')])
print(f"\nAvailable images ({len(images)}):")
for i, name in enumerate(images, 1):
print(f" {i}. {name}")
# === SELECT YOUR IMAGE HERE ===
selected_image = "Fig0222(b)(cameraman).tif" # Change this to any image from the list above
# Load the image in grayscale
img = cv2.imread(os.path.join(DATASET_PATH, selected_image), cv2.IMREAD_GRAYSCALE)
# Display image properties
print(f"Image: {selected_image}")
print(f"Shape: {img.shape}")
print(f"Data type: {img.dtype}")
print(f"Min pixel value: {img.min()}")
print(f"Max pixel value: {img.max()}")
print(f"Mean pixel value: {img.mean():.2f}")
plt.figure(figsize=(6, 6))
plt.imshow(img, cmap='gray')
plt.title(f"{selected_image} ({img.shape[0]}x{img.shape[1]})")
plt.axis('off')
plt.tight_layout()
plt.show()
# === SELECT 4 IMAGES TO COMPARE ===
image_names = [
"Fig0222(b)(cameraman).tif",
"Fig0221(a)(ctskull-256).tif",
"Fig0230(a)(dental_xray).tif",
"Fig0226(galaxy_pair_original).tif"
]
fig, axes = plt.subplots(2, 2, figsize=(10, 10))
for ax, name in zip(axes.flatten(), image_names):
image = cv2.imread(os.path.join(DATASET_PATH, name), cv2.IMREAD_GRAYSCALE)
ax.imshow(image, cmap='gray')
ax.set_title(f"{name.split('(')[-1].replace(').tif','')}\n{image.shape[0]}x{image.shape[1]}")
ax.axis('off')
plt.suptitle("Multiple Images from Dataset", fontsize=14, fontweight='bold')
plt.tight_layout()
plt.show()
# Detailed properties
print(f"{'Property':<20} {'Value'}")
print("-" * 40)
print(f"{'Filename':<20} {selected_image}")
print(f"{'Dimensions':<20} {img.shape[0]} x {img.shape[1]}")
print(f"{'Total pixels':<20} {img.size}")
print(f"{'Data type':<20} {img.dtype}")
print(f"{'Min intensity':<20} {img.min()}")
print(f"{'Max intensity':<20} {img.max()}")
print(f"{'Mean intensity':<20} {img.mean():.2f}")
print(f"{'Std deviation':<20} {img.std():.2f}")
# Display image alongside its histogram
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 5))
ax1.imshow(img, cmap='gray')
ax1.set_title(f"{selected_image}")
ax1.axis('off')
ax2.hist(img.ravel(), bins=256, range=(0, 256), color='black', alpha=0.7)
ax2.set_title("Pixel Intensity Histogram")
ax2.set_xlabel("Intensity Value (0-255)")
ax2.set_ylabel("Frequency")
ax2.set_xlim(0, 256)
plt.tight_layout()
plt.show()
Part 1: Load and Display a Single Image
Load the selected image in grayscale and display it with its properties.
Part 2: Pixel Intensity Histogram
Visualize the distribution of pixel intensities. The histogram shows how many pixels have each intensity value (0-255).
Part 3: Display Multiple Images
Select up to 4 images from any chapter to compare in a grid.
Analysis Questions
- What does the shape of the image array represent? How do grayscale and color images differ in shape?
- Why do we specify
cmap='gray'when displaying grayscale images? What happens if we don't? - Compare the histogram distributions of two different images. What does a narrow histogram vs a wide histogram indicate about the image?