Skip to content

Latest commit

 

History

History
357 lines (282 loc) · 10.6 KB

File metadata and controls

357 lines (282 loc) · 10.6 KB

Exploring Color Spaces in OpenCV with Python

Slide 1: Introduction to Color Spaces in OpenCV

Color spaces are different ways of representing colors mathematically. OpenCV supports various color spaces, each with its own advantages for different image processing tasks. In this presentation, we'll explore how to work with different color spaces using OpenCV and Python.

import cv2
import numpy as np
import matplotlib.pyplot as plt

# Load an image
image = cv2.imread('colorful_image.jpg')

# Display the image
plt.imshow(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))
plt.title('Original Image')
plt.axis('off')
plt.show()

Slide 2: RGB Color Space

RGB (Red, Green, Blue) is the most common color space. In OpenCV, images are loaded in BGR format by default. Each pixel is represented by three values, one for each color channel.

# Split the image into its BGR channels
b, g, r = cv2.split(image)

# Display each channel
fig, (ax1, ax2, ax3) = plt.subplots(1, 3, figsize=(15, 5))
ax1.imshow(b, cmap='gray')
ax1.set_title('Blue Channel')
ax1.axis('off')
ax2.imshow(g, cmap='gray')
ax2.set_title('Green Channel')
ax2.axis('off')
ax3.imshow(r, cmap='gray')
ax3.set_title('Red Channel')
ax3.axis('off')
plt.show()

Slide 3: Converting Between Color Spaces

OpenCV provides functions to convert between different color spaces. Here's how to convert from BGR to RGB and grayscale.

# Convert BGR to RGB
rgb_image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)

# Convert BGR to Grayscale
gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

# Display the results
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(10, 5))
ax1.imshow(rgb_image)
ax1.set_title('RGB Image')
ax1.axis('off')
ax2.imshow(gray_image, cmap='gray')
ax2.set_title('Grayscale Image')
ax2.axis('off')
plt.show()

Slide 4: HSV Color Space

HSV (Hue, Saturation, Value) is often used for color-based segmentation. Hue represents the color, saturation the intensity, and value the brightness.

# Convert BGR to HSV
hsv_image = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)

# Split the HSV image into its channels
h, s, v = cv2.split(hsv_image)

# Display each channel
fig, (ax1, ax2, ax3) = plt.subplots(1, 3, figsize=(15, 5))
ax1.imshow(h, cmap='hsv')
ax1.set_title('Hue Channel')
ax1.axis('off')
ax2.imshow(s, cmap='gray')
ax2.set_title('Saturation Channel')
ax2.axis('off')
ax3.imshow(v, cmap='gray')
ax3.set_title('Value Channel')
ax3.axis('off')
plt.show()

Slide 5: Color Thresholding in HSV Space

HSV is particularly useful for color-based object detection. Let's detect red objects in an image.

# Define range of red color in HSV
lower_red = np.array([0, 120, 70])
upper_red = np.array([10, 255, 255])

# Threshold the HSV image to get only red colors
mask = cv2.inRange(hsv_image, lower_red, upper_red)

# Bitwise-AND mask and original image
result = cv2.bitwise_and(image, image, mask=mask)

# Display the results
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(10, 5))
ax1.imshow(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))
ax1.set_title('Original Image')
ax1.axis('off')
ax2.imshow(cv2.cvtColor(result, cv2.COLOR_BGR2RGB))
ax2.set_title('Red Object Detection')
ax2.axis('off')
plt.show()

Slide 6: Lab Color Space

Lab color space is designed to approximate human vision. It consists of a luminance component (L) and two color components (a and b).

# Convert BGR to Lab
lab_image = cv2.cvtColor(image, cv2.COLOR_BGR2LAB)

# Split the Lab image into its channels
l, a, b = cv2.split(lab_image)

# Display each channel
fig, (ax1, ax2, ax3) = plt.subplots(1, 3, figsize=(15, 5))
ax1.imshow(l, cmap='gray')
ax1.set_title('L Channel')
ax1.axis('off')
ax2.imshow(a, cmap='gray')
ax2.set_title('A Channel')
ax2.axis('off')
ax3.imshow(b, cmap='gray')
ax3.set_title('B Channel')
ax3.axis('off')
plt.show()

Slide 7: YCrCb Color Space

YCrCb separates luminance (Y) from chrominance (Cr and Cb). It's often used in video compression.

# Convert BGR to YCrCb
ycrcb_image = cv2.cvtColor(image, cv2.COLOR_BGR2YCrCb)

# Split the YCrCb image into its channels
y, cr, cb = cv2.split(ycrcb_image)

# Display each channel
fig, (ax1, ax2, ax3) = plt.subplots(1, 3, figsize=(15, 5))
ax1.imshow(y, cmap='gray')
ax1.set_title('Y Channel')
ax1.axis('off')
ax2.imshow(cr, cmap='gray')
ax2.set_title('Cr Channel')
ax2.axis('off')
ax3.imshow(cb, cmap='gray')
ax3.set_title('Cb Channel')
ax3.axis('off')
plt.show()

Slide 8: Skin Detection using YCrCb

YCrCb is effective for skin detection because skin colors cluster well in this space.

# Define range for skin color in YCrCb
lower_skin = np.array([0, 133, 77])
upper_skin = np.array([255, 173, 127])

# Threshold the YCrCb image to get only skin colors
mask = cv2.inRange(ycrcb_image, lower_skin, upper_skin)

# Bitwise-AND mask and original image
result = cv2.bitwise_and(image, image, mask=mask)

# Display the results
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(10, 5))
ax1.imshow(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))
ax1.set_title('Original Image')
ax1.axis('off')
ax2.imshow(cv2.cvtColor(result, cv2.COLOR_BGR2RGB))
ax2.set_title('Skin Detection')
ax2.axis('off')
plt.show()

Slide 9: Color Space Comparison

Different color spaces can yield different results for the same task. Let's compare edge detection in RGB, Lab, and YCrCb spaces.

def detect_edges(img):
    return cv2.Canny(img, 100, 200)

# Detect edges in different color spaces
rgb_edges = detect_edges(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))
lab_edges = detect_edges(lab_image)
ycrcb_edges = detect_edges(ycrcb_image)

# Display the results
fig, (ax1, ax2, ax3) = plt.subplots(1, 3, figsize=(15, 5))
ax1.imshow(rgb_edges, cmap='gray')
ax1.set_title('RGB Edges')
ax1.axis('off')
ax2.imshow(lab_edges, cmap='gray')
ax2.set_title('Lab Edges')
ax2.axis('off')
ax3.imshow(ycrcb_edges, cmap='gray')
ax3.set_title('YCrCb Edges')
ax3.axis('off')
plt.show()

Slide 10: Real-life Example: Traffic Light Detection

Using HSV color space to detect traffic lights in an image.

# Load a traffic light image
traffic_light = cv2.imread('traffic_light.jpg')
hsv_traffic = cv2.cvtColor(traffic_light, cv2.COLOR_BGR2HSV)

# Define color ranges for red, yellow, and green
lower_red = np.array([0, 120, 70])
upper_red = np.array([10, 255, 255])
lower_yellow = np.array([20, 100, 100])
upper_yellow = np.array([30, 255, 255])
lower_green = np.array([40, 50, 50])
upper_green = np.array([90, 255, 255])

# Create masks for each color
red_mask = cv2.inRange(hsv_traffic, lower_red, upper_red)
yellow_mask = cv2.inRange(hsv_traffic, lower_yellow, upper_yellow)
green_mask = cv2.inRange(hsv_traffic, lower_green, upper_green)

# Combine masks
combined_mask = red_mask + yellow_mask + green_mask

# Apply mask to original image
result = cv2.bitwise_and(traffic_light, traffic_light, mask=combined_mask)

# Display results
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(10, 5))
ax1.imshow(cv2.cvtColor(traffic_light, cv2.COLOR_BGR2RGB))
ax1.set_title('Original Traffic Light')
ax1.axis('off')
ax2.imshow(cv2.cvtColor(result, cv2.COLOR_BGR2RGB))
ax2.set_title('Detected Lights')
ax2.axis('off')
plt.show()

Slide 11: Real-life Example: Fruit Ripeness Detection

Using Lab color space to detect the ripeness of bananas.

# Load a banana image
banana = cv2.imread('banana.jpg')
lab_banana = cv2.cvtColor(banana, cv2.COLOR_BGR2LAB)

# Extract the a-channel
a_channel = lab_banana[:,:,1]

# Define thresholds for ripeness
unripe_threshold = 120
ripe_threshold = 130
overripe_threshold = 140

# Create masks for different ripeness levels
unripe_mask = cv2.inRange(a_channel, 0, unripe_threshold)
ripe_mask = cv2.inRange(a_channel, unripe_threshold, ripe_threshold)
overripe_mask = cv2.inRange(a_channel, ripe_threshold, 255)

# Apply masks to original image
unripe = cv2.bitwise_and(banana, banana, mask=unripe_mask)
ripe = cv2.bitwise_and(banana, banana, mask=ripe_mask)
overripe = cv2.bitwise_and(banana, banana, mask=overripe_mask)

# Display results
fig, ((ax1, ax2), (ax3, ax4)) = plt.subplots(2, 2, figsize=(10, 10))
ax1.imshow(cv2.cvtColor(banana, cv2.COLOR_BGR2RGB))
ax1.set_title('Original Banana')
ax1.axis('off')
ax2.imshow(cv2.cvtColor(unripe, cv2.COLOR_BGR2RGB))
ax2.set_title('Unripe Areas')
ax2.axis('off')
ax3.imshow(cv2.cvtColor(ripe, cv2.COLOR_BGR2RGB))
ax3.set_title('Ripe Areas')
ax3.axis('off')
ax4.imshow(cv2.cvtColor(overripe, cv2.COLOR_BGR2RGB))
ax4.set_title('Overripe Areas')
ax4.axis('off')
plt.show()

Slide 12: Color Space Conversion Performance

Different color space conversions have different computational costs. Let's compare the time taken for various conversions.

import time

def measure_conversion_time(conversion):
    start_time = time.time()
    for _ in range(1000):
        cv2.cvtColor(image, conversion)
    end_time = time.time()
    return end_time - start_time

conversions = [
    ('BGR to RGB', cv2.COLOR_BGR2RGB),
    ('BGR to Gray', cv2.COLOR_BGR2GRAY),
    ('BGR to HSV', cv2.COLOR_BGR2HSV),
    ('BGR to Lab', cv2.COLOR_BGR2LAB),
    ('BGR to YCrCb', cv2.COLOR_BGR2YCrCb)
]

times = [measure_conversion_time(conv[1]) for conv in conversions]

plt.figure(figsize=(10, 5))
plt.bar([conv[0] for conv in conversions], times)
plt.title('Color Space Conversion Performance')
plt.xlabel('Conversion Type')
plt.ylabel('Time (seconds)')
plt.xticks(rotation=45)
plt.tight_layout()
plt.show()

Slide 13: Conclusion and Best Practices

We've explored various color spaces in OpenCV and their applications. Here are some key takeaways:

  1. Choose the right color space for your task:
    • RGB for general purpose
    • HSV for color-based segmentation
    • Lab for tasks requiring perceptual uniformity
    • YCrCb for skin detection and video compression
  2. Consider performance implications when converting between color spaces.
  3. Experiment with different color spaces to find the best solution for your specific problem.
  4. Remember that lighting conditions can greatly affect color-based algorithms, so consider preprocessing steps like histogram equalization or adaptive thresholding.

Slide 14: Additional Resources

For more information on color spaces and image processing with OpenCV, consider exploring these resources:

  1. OpenCV Documentation: https://docs.opencv.org/
  2. "Color image segmentation: Advances and prospects" by H. D. Cheng et al. (2001): https://arxiv.org/abs/cs/0509071
  3. "A Survey of Recent Advances in CNN-based Single Image Crowd Counting and Density Estimation" by V. A. Sindagi and V. M. Patel (2017): https://arxiv.org/abs/1707.01202

These resources provide in-depth information on color space theory and advanced image processing techniques using OpenCV.