File size: 4,078 Bytes
8c38d83
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
82d82cc
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
import cv2
import numpy as np


def calculate_deforestation_metrics(mask, threshold=0.5):
    """

    Calculate deforestation metrics from the predicted mask



    Args:

        mask: Predicted mask (numpy array)

        threshold: Threshold to binarize the mask (default is 0.5)



    Returns:

        Dictionary containing deforestation metrics

    """
    # Binarize the mask
    binary_mask = (mask > threshold).astype(np.uint8)

    # Calculate pixel counts
    total_pixels = binary_mask.size
    forest_pixels = np.sum(binary_mask)
    deforested_pixels = total_pixels - forest_pixels

    # Calculate percentages
    forest_percentage = (forest_pixels / total_pixels) * 100
    deforested_percentage = (deforested_pixels / total_pixels) * 100

    # Determine deforestation level
    if deforested_percentage < 20:
        level = "Low"
    elif deforested_percentage < 50:
        level = "Medium"
    else:
        level = "High"

    return {
        "forest_pixels": forest_pixels,
        "deforested_pixels": deforested_pixels,
        "forest_percentage": forest_percentage,
        "deforested_percentage": deforested_percentage,
        "deforestation_level": level,
    }


def create_overlay(original_image, mask, threshold=0.5, alpha=0.5):
    """

    Create a visualization by overlaying the mask on the original image



    Args:

        original_image: Original RGB image

        mask: Predicted mask

        threshold: Threshold to binarize the mask

        alpha: Opacity of the overlay



    Returns:

        Overlay image

    """
    # Resize mask to match original image if needed
    if original_image.shape[:2] != mask.shape[:2]:
        mask = cv2.resize(mask, (original_image.shape[1], original_image.shape[0]))

    # Create binary mask
    binary_mask = (mask > threshold).astype(np.uint8) * 255

    # Create a colored mask (green for forest, red for deforested)
    colored_mask = np.zeros_like(original_image)
    colored_mask[binary_mask == 255] = [0, 255, 0]  # Green for forest
    colored_mask[binary_mask == 0] = [150, 75, 0]  # Brown for deforested

    # Create overlay
    overlay = cv2.addWeighted(original_image, 1 - alpha, colored_mask, alpha, 0)

    return overlay


CLASS_NAMES = ['bike-bicycle', 'bus-truck', 'car', 'fire', 'human', 'smoke']
COLORS = np.random.uniform(0, 255, size=(len(CLASS_NAMES), 3))

def preprocess(image, img_size=640):
    image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
    image = cv2.resize(image, (img_size, img_size))
    image = image.transpose((2, 0, 1))  # HWC to CHW
    image = np.ascontiguousarray(image, dtype=np.float32) / 255.0
    return image[np.newaxis, ...]

def postprocess(outputs, conf_thresh=0.5, iou_thresh=0.5):
    outputs = outputs[0].transpose()
    boxes, scores, class_ids = [], [], []
    
    for row in outputs:
        cls_scores = row[4:4+len(CLASS_NAMES)]
        class_id = np.argmax(cls_scores)
        max_score = cls_scores[class_id]
        
        if max_score >= conf_thresh:
            cx, cy, w, h = row[:4]
            x = (cx - w/2).item()  # Convert to Python float
            y = (cy - h/2).item()
            width = w.item()
            height = h.item()
            boxes.append([x, y, width, height])
            scores.append(float(max_score))
            class_ids.append(int(class_id))

    if len(boxes) > 0:
        # Convert to list of lists with native Python floats
        boxes = [[float(x) for x in box] for box in boxes]
        scores = [float(score) for score in scores]
        
        indices = cv2.dnn.NMSBoxes(
            bboxes=boxes,
            scores=scores,
            score_threshold=conf_thresh,
            nms_threshold=iou_thresh
        )
        
        if len(indices) > 0:
            boxes = [boxes[i] for i in indices.flatten()]
            scores = [scores[i] for i in indices.flatten()]
            class_ids = [class_ids[i] for i in indices.flatten()]

    return boxes, scores, class_ids