Spaces:
Running
Running
import cv2 | |
import numpy as np | |
import gradio as gr | |
# Helper function to detect sky condition and get the HSV range | |
def detect_sky_color(hsv_image): | |
# Crop the image to the upper half, because we assume the sky is always on the upper half of the image | |
height = hsv_image.shape[0] | |
upper_half_image = hsv_image[:height//2, :] | |
# Define color ranges in HSV | |
blue_lower = np.array([46, 17, 148], np.uint8) | |
blue_upper = np.array([154, 185, 249], np.uint8) | |
orange_lower = np.array([10, 100, 100], np.uint8) | |
orange_upper = np.array([25, 183, 254], np.uint8) | |
pale_lower = np.array([0, 0, 129], np.uint8) | |
pale_upper = np.array([171, 64, 225], np.uint8) | |
# Create masks for colors | |
blue_mask = cv2.inRange(upper_half_image, blue_lower, blue_upper) | |
orange_mask = cv2.inRange(upper_half_image, orange_lower, orange_upper) | |
pale_mask = cv2.inRange(upper_half_image, pale_lower, pale_upper) | |
# Calculate the percentage of cropped image covered by each color | |
blue_percentage = np.sum(blue_mask > 0) / (upper_half_image.shape[0] * upper_half_image.shape[1]) * 100 | |
orange_percentage = np.sum(orange_mask > 0) / (upper_half_image.shape[0] * upper_half_image.shape[1]) * 100 | |
pale_percentage = np.sum(pale_mask > 0) / (upper_half_image.shape[0] * upper_half_image.shape[1]) * 100 | |
# Determine the predominant color in the upper half | |
max_color = max(blue_percentage, orange_percentage, pale_percentage) | |
if max_color == blue_percentage: | |
return blue_lower, blue_upper | |
elif max_color == orange_percentage: | |
return orange_lower, orange_upper | |
else: | |
return pale_lower, pale_upper | |
# Main function to process image and display sky masks | |
def sky_segmentation(uploaded_image): | |
# Read the image | |
image = cv2.imread(uploaded_image) | |
# Convert to HSV image | |
hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV) | |
# Determine HSV range based on helper function | |
(hsv_lower, hsv_upper) = detect_sky_color(hsv) | |
# Use hsv_lower and hsv_upper to create a mask, which isolates the sky region | |
mask_initial = cv2.inRange(hsv, hsv_lower, hsv_upper) | |
# Apply morphological operations to fine-tune the mask | |
kernel = np.ones((3,3), np.uint8) | |
mask_fine_tuned = cv2.erode(mask_initial, kernel, iterations=1) | |
mask_fine_tuned = cv2.dilate(mask_fine_tuned, kernel, iterations=1) | |
# Perform connected component analysis | |
num_labels, labels_im = cv2.connectedComponents(mask_fine_tuned) | |
# Create an array to hold the size of each component | |
sizes = np.bincount(labels_im.flatten()) | |
# Set the size of the background (label 0) to zero | |
sizes[0] = 0 | |
# Find the largest component | |
max_label = np.argmax(sizes) | |
# Create a mask with only the largest component | |
sky_mask = np.zeros_like(mask_fine_tuned) | |
sky_mask[labels_im == max_label] = 255 | |
return sky_mask | |
# Create a Gradio demo | |
demo = gr.Interface( | |
fn=sky_segmentation, | |
inputs= gr.Image(type='filepath'), | |
outputs="image", | |
title='Sky Segmentation', | |
description='Sky Pixel Identification in Images using Traditional Computer Vision Techniques', | |
examples=["blue1.jpeg", "pink1.jpeg", "pale1.jpeg"] | |
) | |
demo.launch() | |