Spaces:
Sleeping
Sleeping
Upload app.py
Browse files
app.py
ADDED
@@ -0,0 +1,80 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import cv2
|
2 |
+
import numpy as np
|
3 |
+
import gradio as gr
|
4 |
+
|
5 |
+
# Helper function to detect sky condition and get the HSV range
|
6 |
+
def detect_sky_color(hsv_image):
|
7 |
+
# Crop the image to the upper half, because we assume the sky is always on the upper half of the image
|
8 |
+
height = hsv_image.shape[0]
|
9 |
+
upper_half_image = hsv_image[:height//2, :]
|
10 |
+
|
11 |
+
# Define color ranges in HSV
|
12 |
+
blue_lower = np.array([46, 17, 148], np.uint8)
|
13 |
+
blue_upper = np.array([154, 185, 249], np.uint8)
|
14 |
+
orange_lower = np.array([10, 100, 100], np.uint8)
|
15 |
+
orange_upper = np.array([25, 183, 254], np.uint8)
|
16 |
+
pale_lower = np.array([0, 0, 129], np.uint8)
|
17 |
+
pale_upper = np.array([171, 64, 225], np.uint8)
|
18 |
+
|
19 |
+
# Create masks for colors
|
20 |
+
blue_mask = cv2.inRange(upper_half_image, blue_lower, blue_upper)
|
21 |
+
orange_mask = cv2.inRange(upper_half_image, orange_lower, orange_upper)
|
22 |
+
pale_mask = cv2.inRange(upper_half_image, pale_lower, pale_upper)
|
23 |
+
|
24 |
+
# Calculate the percentage of cropped image covered by each color
|
25 |
+
blue_percentage = np.sum(blue_mask > 0) / (upper_half_image.shape[0] * upper_half_image.shape[1]) * 100
|
26 |
+
orange_percentage = np.sum(orange_mask > 0) / (upper_half_image.shape[0] * upper_half_image.shape[1]) * 100
|
27 |
+
pale_percentage = np.sum(pale_mask > 0) / (upper_half_image.shape[0] * upper_half_image.shape[1]) * 100
|
28 |
+
|
29 |
+
# Determine the predominant color in the upper half
|
30 |
+
max_color = max(blue_percentage, orange_percentage, pale_percentage)
|
31 |
+
if max_color == blue_percentage:
|
32 |
+
return blue_lower, blue_upper
|
33 |
+
elif max_color == orange_percentage:
|
34 |
+
return orange_lower, orange_upper
|
35 |
+
else:
|
36 |
+
return pale_lower, pale_upper
|
37 |
+
|
38 |
+
|
39 |
+
# Main function to process image and display sky masks
|
40 |
+
def sky_segmentation(uploaded_image):
|
41 |
+
# Read the image
|
42 |
+
image = cv2.imread(uploaded_image)
|
43 |
+
|
44 |
+
# Convert to HSV image
|
45 |
+
hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
|
46 |
+
|
47 |
+
# Determine HSV range based on helper function
|
48 |
+
(hsv_lower, hsv_upper) = detect_sky_color(hsv)
|
49 |
+
|
50 |
+
# Use hsv_lower and hsv_upper to create a mask, which isolates the sky region
|
51 |
+
mask_initial = cv2.inRange(hsv, hsv_lower, hsv_upper)
|
52 |
+
|
53 |
+
# Apply morphological operations to fine-tune the mask
|
54 |
+
kernel = np.ones((3,3), np.uint8)
|
55 |
+
mask_fine_tuned = cv2.erode(mask_initial, kernel, iterations=1)
|
56 |
+
mask_fine_tuned = cv2.dilate(mask_fine_tuned, kernel, iterations=1)
|
57 |
+
|
58 |
+
# Perform connected component analysis
|
59 |
+
num_labels, labels_im = cv2.connectedComponents(mask_fine_tuned)
|
60 |
+
|
61 |
+
# Create an array to hold the size of each component
|
62 |
+
sizes = np.bincount(labels_im.flatten())
|
63 |
+
|
64 |
+
# Set the size of the background (label 0) to zero
|
65 |
+
sizes[0] = 0
|
66 |
+
|
67 |
+
# Find the largest component
|
68 |
+
max_label = np.argmax(sizes)
|
69 |
+
|
70 |
+
# Create a mask with only the largest component
|
71 |
+
sky_mask = np.zeros_like(mask_fine_tuned)
|
72 |
+
sky_mask[labels_im == max_label] = 255
|
73 |
+
|
74 |
+
return sky_mask
|
75 |
+
|
76 |
+
|
77 |
+
# Create a Gradio demo
|
78 |
+
demo = gr.Interface(sky_segmentation, gr.Image(type='filepath'), "image")
|
79 |
+
if __name__ == "__main__":
|
80 |
+
demo.launch(share=True)
|