CS559 Notes

Edge Detection in Color Images: A Short Report

Introduction

The aim is to develop a robust edge detection algorithm that works on color images, focusing on identifying the boundaries of objects of a particular color. The algorithm should not only accurately delineate the edges but should also be general enough to be applied to various types of images.

Considerations

Color Isolation: The program uses HSV color space for more accurate color isolation. It allows for flexibility in specifying a range of hues for targeted objects.
Morphological Refinement: Apart from using the Canny edge detection algorithm, the program employs morphological operations to refine the detected edges, thereby enhancing the accuracy and visual clarity.
User-Centric Design: The program allows for visual overlays of the detected edges on the original images, enhancing user interpretability. Additionally, it allows for adjustable line thickness for better visibility.
Foundational Algorithms and Architectures
Canny Edge Detection: For accurate edge detection.
HSV Color Space: For isolating color channels.
Morphological Operations: For removing noise and false edges.

Strategies Underpinning Success

Multi-stage processing in Canny for robustness.
Color normalization in HSV for better color isolation.

Implementation:

Step 1: Intake Processing
Isolating the color channels for the objects of interest.
Performing edge detection.
Removing false edges and completing partially obstructed boundaries.
import matplotlib.pyplot as plt
import cv2

# Load the images
img_a = cv2.imread('/mnt/data/a.jpg')
img_b = cv2.imread('/mnt/data/b.jpg')
img_c = cv2.imread('/mnt/data/c.jpg')

# Convert from BGR to RGB (OpenCV loads images in BGR format)
img_a_rgb = cv2.cvtColor(img_a, cv2.COLOR_BGR2RGB)
img_b_rgb = cv2.cvtColor(img_b, cv2.COLOR_BGR2RGB)
img_c_rgb = cv2.cvtColor(img_c, cv2.COLOR_BGR2RGB)

# Display the images
fig, axes = plt.subplots(1, 3, figsize=(15, 5))

axes[0].imshow(img_a_rgb)
axes[0].set_title('Fig (a)')
axes[0].axis('off')

axes[1].imshow(img_b_rgb)
axes[1].set_title('Fig (b)')
axes[1].axis('off')

axes[2].imshow(img_c_rgb)
axes[2].set_title('Fig (c)')
axes[2].axis('off')

plt.show()
image.png
Step 2: Isolation
For Fig (a), we'll focus on isolating the green color to target the leaves.
For Fig (b), we'll again focus on green to target the green pepper.
For Fig (c), we'll focus on isolating the orange color to target the orange fruit.
import numpy as np

def isolate_color(img_rgb, lower_bound, upper_bound):
# Convert the image to HSV color space
img_hsv = cv2.cvtColor(img_rgb, cv2.COLOR_RGB2HSV)
# Create a binary mask where the color is in the range
mask = cv2.inRange(img_hsv, lower_bound, upper_bound)
# Use the mask to extract the object from the original image
isolated_img = cv2.bitwise_and(img_rgb, img_rgb, mask=mask)
return isolated_img, mask

# Define color bounds for each object of interest
lower_green = np.array([35, 50, 50])
upper_green = np.array([90, 255, 255])

lower_orange = np.array([5, 50, 50])
upper_orange = np.array([20, 255, 255])

# Isolate colors in the images
isolated_a, mask_a = isolate_color(img_a_rgb, lower_green, upper_green)
isolated_b, mask_b = isolate_color(img_b_rgb, lower_green, upper_green)
isolated_c, mask_c = isolate_color(img_c_rgb, lower_orange, upper_orange)

# Display the isolated images
fig, axes = plt.subplots(1, 3, figsize=(15, 5))

axes[0].imshow(isolated_a)
axes[0].set_title('Isolated Fig (a)')
axes[0].axis('off')

axes[1].imshow(isolated_b)
axes[1].set_title('Isolated Fig (b)')
axes[1].axis('off')

axes[2].imshow(isolated_c)
axes[2].set_title('Isolated Fig (c)')
axes[2].axis('off')

plt.show()
image.png
Step 3: Edge Detection and outline
Convert the isolated color images to grayscale, as edge detection typically works on single-channel images.
Apply the Canny edge detection algorithm.
Overlay the detected edges on the original images to see the results.
def apply_canny(img_rgb):
# Convert to grayscale
gray = cv2.cvtColor(img_rgb, cv2.COLOR_RGB2GRAY)
# Apply Canny edge detection
edges = cv2.Canny(gray, 100, 200)
# Create an RGB version of the edge-detected image
edges_colored = cv2.merge([edges, edges, edges])
# Overlay the edges on the original image
overlay = cv2.addWeighted(img_rgb, 0.8, edges_colored, 0.2, 0)
return edges, overlay

# Apply Canny edge detection to the isolated images
edges_a, overlay_a = apply_canny(isolated_a)
edges_b, overlay_b = apply_canny(isolated_b)
edges_c, overlay_c = apply_canny(isolated_c)

# Display the results
fig, axes = plt.subplots(2, 3, figsize=(15, 10))

axes[0, 0].imshow(edges_a, cmap='gray')
axes[0, 0].set_title('Edges Fig (a)')
axes[0, 0].axis('off')

axes[0, 1].imshow(edges_b, cmap='gray')
axes[0, 1].set_title('Edges Fig (b)')
axes[0, 1].axis('off')

axes[0, 2].imshow(edges_c, cmap='gray')
axes[0, 2].set_title('Edges Fig (c)')
axes[0, 2].axis('off')

axes[1, 0].imshow(overlay_a)
axes[1, 0].set_title('Overlay Fig (a)')
axes[1, 0].axis('off')

axes[1, 1].imshow(overlay_b)
axes[1, 1].set_title('Overlay Fig (b)')
axes[1, 1].axis('off')

axes[1, 2].imshow(overlay_c)
axes[1, 2].set_title('Overlay Fig (c)')
axes[1, 2].axis('off')

plt.show()
image.png
Step 4: Color and Overlay
For Fig (a), we'll color the detected leaves as blue.
For Fig (b), we'll remove the false edges and color the boundary of the green pepper as blue.
For Fig (c), we'll complete the boundary of the orange, if obstructed, and color it as blue.
def refine_and_color_edges(edges, img_rgb, color=[0, 0, 255]):
# Perform morphological operations to refine edges
kernel = np.ones((5, 5), np.uint8)
refined_edges = cv2.dilate(edges, kernel, iterations=1)
refined_edges = cv2.erode(refined_edges, kernel, iterations=1)
# Create an RGB version of the refined edges
refined_colored = np.zeros_like(img_rgb)
refined_colored[refined_edges == 255] = color
# Overlay the refined edges on the original image
overlay = cv2.addWeighted(img_rgb, 0.8, refined_colored, 0.2, 0)
return refined_colored, overlay

# Refine and color edges for each image
refined_a, overlay_refined_a = refine_and_color_edges(edges_a, img_a_rgb, [0, 0, 255])
refined_b, overlay_refined_b = refine_and_color_edges(edges_b, img_b_rgb, [0, 0, 255])
refined_c, overlay_refined_c = refine_and_color_edges(edges_c, img_c_rgb, [0, 0, 255])

# Display the results
fig, axes = plt.subplots(2, 3, figsize=(15, 10))

axes[0, 0].imshow(refined_a)
axes[0, 0].axis('off')

axes[0, 1].imshow(refined_b)
axes[0, 1].axis('off')

axes[0, 2].imshow(refined_c)
axes[0, 2].axis('off')

axes[1, 0].imshow(overlay_refined_a)
axes[1, 0].set_title('Overlay Fig (a)')
axes[1, 0].axis('off')

axes[1, 1].imshow(overlay_refined_b)
axes[1, 1].set_title('Overlay Fig (b)')
axes[1, 1].axis('off')

axes[1, 2].imshow(overlay_refined_c)
axes[1, 2].set_title('Overlay Fig (c)')
axes[1, 2].axis('off')

plt.show()
blueedges.png
Want to print your doc?
This is not the way.
Try clicking the ⋯ next to your doc name or using a keyboard shortcut (
CtrlP
) instead.