File size: 3,059 Bytes
9d46f10
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
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(sky_segmentation, gr.Image(type='filepath'), "image")
if __name__ == "__main__":
    demo.launch(share=True)