We will explore how to manipulate local regions within an image, adjust brightness and contrast, apply curve adjustments to enhance specific image features, use thresholding to create binary images, and implement indexed color to reduce the number of colors in an image. Each of these operations serves as a building block for creating powerful and flexible image processing pipelines. Whether you're a beginner or looking to refine your skills, this tutorial will provide a solid grounding in the essential techniques needed to manipulate and enhance digital images effectively.

Selecting and Manipulating Local Regions

Manipulating a local region means modifying a specific part of the image while leaving the rest untouched.

Example: Changing a Local Region to a Specific Color

Let's say we have an image, and we want to change a rectangular region in the center of the image to a solid blue color.

image_mod = image.clone()
# Define the region of interest (ROI)
x_start, y_start, x_end, y_end = 100, 100, 200, 200  # Example coordinates

# Change the color of the region to blue (RGB format)
image[y_start:y_end, x_start:x_end] = [0, 0, 255]  # Red color in RGB

Result

The specified region of the image will change to a solid blue color, while the rest of the image remains unchanged.

image.png

Criterial-based Regions Selection

In some cases, we need to select pixels based on simple criteria. Rather than handling complex conditions like connected areas, we will focus on straightforward examples. For instance, we can select a pixel if it appears more red than green and blue, or if the average RGB value of the pixel exceeds 127. These selections create masks that highlight the areas of interest in the image.

# Mask 1: Select pixels that are reddish (red > green and red > blue)
red_mask = (image[:, :, 0] > image[:, :, 1]) & (image[:, :, 0] > image[:, :, 2])

# Mask 2: Select pixels where the average RGB value is greater than 64
avg_rgb_mask = np.mean(image, axis=2) > 192

Result: White denotes True mask, and black denotes False mask.

image.png

The figure shows three images:

  1. Reddish Pixels Mask: Highlights the pixels where the red channel is stronger than both the green and blue channels. The white regions correspond to "reddish" pixels, while black areas indicate where this condition isn't met.
  2. Average RGB > 192 Mask: Displays a mask where the average of the RGB values for each pixel is greater than 192. White regions represent pixels with bright colors (where the average RGB value exceeds 192), while dark areas represent pixels with lower intensity.

Brightness Adjustment

Brightness adjustment involves increasing or decreasing the intensity of all pixels in an image by adding or subtracting a constant value, making it appear lighter or darker, and is often used to correct underexposed or overexposed images.

# Increase brightness by adding a constant value
brightness_increase = 50
bright_image = np.clip(image.astype(float) + brightness_increase, 0, 255).astype(np.uint8)

# Decrease brightness by subtracting a constant value
brightness_decrease = -50
dark_image = np.clip(image.astype(float) + brightness_decrease, 0, 255).astype(np.uint8)

# Convert back to PIL images for display
bright_image = Image.fromarray(bright_image)
dark_image = Image.fromarray(dark_image)