File size: 4,508 Bytes
451d0ea
 
 
 
 
 
 
 
 
 
 
e33de4f
451d0ea
bf54062
 
 
 
7ade6df
e33de4f
451d0ea
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
55c75ec
 
 
 
 
 
 
 
451d0ea
8accc44
451d0ea
 
ad5a6e2
451d0ea
 
 
 
 
bf54062
451d0ea
 
 
 
 
 
ad5a6e2
451d0ea
 
 
 
 
 
 
 
 
 
ad5a6e2
 
 
 
f42aab1
ad5a6e2
 
451d0ea
 
 
 
 
 
 
 
 
 
ad5a6e2
451d0ea
 
 
 
7973cf2
7ade6df
7973cf2
 
 
 
 
451d0ea
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
124
125
import os
from pathlib import Path
from typing import Dict
from PIL import Image, ImageDraw, ImageFont

import numpy as np
import torch
import torchvision.transforms.functional as F
from ultralytics import YOLO
import gradio as gr
from huggingface_hub import hf_hub_download
from datasets import load_dataset

model_path_1 = hf_hub_download("Axpo/yolov8x-without-insulators", "yolov8x-without-insulators.pt", use_auth_token=os.environ["TOKEN"])
model_path_2 = hf_hub_download("Axpo/yolov8x-with-insulators", "yolov8x-with-insulators.pt", use_auth_token=os.environ["TOKEN"])
model_paths = [model_path_1, model_path_2]

dataset = load_dataset("Axpo/example_pole_images", use_auth_token=os.environ["TOKEN"])

def draw_bboxes_yolo(
        image: torch.Tensor, 
        bboxes: torch.Tensor, 
        labels: list[str],
        color_mapping: Dict,
        scores = [],
        width: int = 2,) -> np.ndarray:
        """
        Draws predicted bboxes with class names and scores on images.
        
        Args:
        - image: image of torch.tensor dtype uint8
        - bboxes: torch.tensor with shape [N, 4] for N bboxes per image
        - labels: list of length N with class names, e.g. ["Gittermast", "Gitterausleger", ...]
        - scores: torch.tensor of length N with scores for all bbox predictions
        - width: width of the bounding boxes
        
        Returns: np.array with the image and bboxes / text / scores included
        """
        img_to_draw = Image.fromarray(image.permute(1, 2, 0).numpy())
        draw = ImageDraw.Draw(img_to_draw)
        bboxes_list = bboxes.tolist()
        if len(scores)==0:
            scores_list = len(labels) * [1]
        else:
            scores_list = scores.tolist()
        margin = width + 1
        # font_txt = ImageFont.truetype("arial.ttf", size=15)
        font_txt = ImageFont.load_default()
        
        # Predictions
        for bbox, label, score in zip(bboxes_list, labels, scores_list):
            color = color_mapping[label]
            draw.rectangle(bbox, width=width, outline=color)
            draw.text((bbox[0] + margin, bbox[1] + margin), f"{label} | {str(round(score, 2))}", font=font_txt)
        
        return np.array(img_to_draw)
        
class BigComponentsCFG:
    id2label: Dict[int, str] = {
      0: "Betonausleger",
      1: "Betonmast",
      2: "Flugwarnkugel",
      3: "Fundament",
      4: "Gitterausleger",
      5: "Gittermast",
      6: "Isolator",
      7: "Mastspitz",
    }
    colors: list[str] = ["#FF0000", "#00FF00", "#0000FF", "#00FFFF", "#FF00FF", "#FFFF00", "#FFA500", "#000000"]


def predict_big_components(image, threshold: float, model_idx: int):
    
    id2label = BigComponentsCFG.id2label
    colors = BigComponentsCFG.colors
    color_mapping = {k: v for k, v in zip(id2label.values(), colors)}

    model_path = model_paths[model_idx]
    model = YOLO(model_path)
    results = model.predict([image])
    
    boxes = results[0].boxes.xyxy
    labels = results[0].boxes.cls
    scores = results[0].boxes.conf
    mask = scores > threshold
    labels_str = [id2label[label.item()] for label in labels[mask]]
    
    # Create image
    img_t = F.pil_to_tensor(image)
    img_arr = draw_bboxes_yolo(img_t, boxes[mask], labels_str, color_mapping, scores[mask])
    img = F.to_pil_image(img_arr)
    return img

with gr.Blocks() as demo:
    with gr.Row():
        with gr.Column():
            slider = gr.Slider(minimum=0.0, maximum=1.0, default=0.0, step=0.05, label="Confidence Threshold")
        with gr.Column():
            model = gr.Dropdown(choices=["Axpo/yolov8x-without-insulators", "Axpo/yolov8x-with-insulators"],
                                value="Axpo/yolov8x-with-insulators",
                                type="index",
                                label="Model")
    with gr.Row().style(full_width=True):
        with gr.Column():
            input_img = gr.Image(type="pil", label="Input").style(height=600, width=600)
        with gr.Column():
            output_img = gr.Image(type="pil", label="Output").style(height=600, width=600)
        
    with gr.Row():
        image_button = gr.Button("Detect Components")
    image_button.click(
        fn=predict_big_components, 
        inputs=[input_img, slider, model], 
        outputs=output_img,
        api_name="big-component-detection"
            )

    gr.Examples(
        dataset["train"]["image"],
        input_img,
        output_img,
        predict_big_components
    )

demo.launch()