File size: 4,561 Bytes
d2ab6f5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import os
import cv2
import numpy as np
import gradio as gr
from ultralytics import YOLO

def simplify_polygon(points, tol_ratio=0.02):
    """
    Упрощает полигон с помощью аппроксимации по Перу.
    
    Параметры:
        points (np.ndarray): Исходный набор точек полигона (Nx2).
        tol_ratio (float): Коэффициент допуска для аппроксимации.
        
    Возвращает:
        np.ndarray: Упрощённый набор точек полигона.
    """
    pts = points.reshape((-1, 1, 2)).astype(np.float32)
    perimeter = cv2.arcLength(pts, True)
    epsilon = tol_ratio * perimeter
    approx = cv2.approxPolyDP(pts, epsilon, True)
    return approx.reshape(-1, 2)

# Загружаем модель YOLO (файл model.pt должен находиться в корневой директории Space)
model_path = os.path.join(os.getcwd(), "model.pt")
model12 = YOLO(model_path)

def process_image(image):
    """
    Обрабатывает изображение:
      - Выполняет предсказание модели YOLO для детекции комнат.
      - Рисует упрощённые полигоны (с углами) для объектов класса 'room' (id = 2).
      - Формирует текст со списком координат углов.
      
    Параметры:
        image (np.ndarray): Исходное изображение.
        
    Возвращает:
        annotated_img (np.ndarray): Изображение с нанесёнными аннотациями.
        coord_text (str): Текст с координатами углов.
    """
    pred_results = list(model12.predict(source=image, imgsz=640))
    if len(pred_results) == 0:
        return image, "Ошибка: предсказания не получены."
    
    pred = pred_results[0]
    if pred.masks is None or pred.boxes is None:
        return image, "На изображении объекты не обнаружены."
    
    # Преобразуем исходное изображение в RGB для корректного отображения
    orig_img = pred.orig_img
    if orig_img.shape[2] == 3:
        original_rgb = cv2.cvtColor(orig_img.copy(), cv2.COLOR_BGR2RGB)
    else:
        original_rgb = orig_img.copy()
    annotated_img = original_rgb.copy()
    
    # Извлекаем полигоны и классы
    polygons = pred.masks.xy
    class_ids = pred.boxes.cls.cpu().numpy()
    
    coordinates_list = []
    for idx, polygon in enumerate(polygons):
        class_id = int(class_ids[idx])
        if class_id == 2:  # Обрабатываем только объекты класса "room"
            poly_np = np.array(polygon, dtype=np.float32)
            simplified_poly = simplify_polygon(poly_np, tol_ratio=0.005)
            coordinates_list.append({
                "object": idx + 1,
                "class": class_id,
                "coordinates": [(float(pt[0]), float(pt[1])) for pt in simplified_poly]
            })
            cv2.polylines(annotated_img, [simplified_poly.astype(np.int32)], isClosed=True, color=(0, 255, 0), thickness=2)
            for point in simplified_poly:
                cv2.circle(annotated_img, (int(point[0]), int(point[1])), 3, (255, 0, 0), -1)
    
    if coordinates_list:
        coord_text = ""
        for item in coordinates_list:
            coord_text += f"Координаты углов в комнате №: {item['object']}\n"
            for coord in item['coordinates']:
                coord_text += f"({coord[0]:.2f}, {coord[1]:.2f})\n"
            coord_text += "-" * 30 + "\n"
    else:
        coord_text = "На изображении не обнаружены комнаты."
    
    return annotated_img, coord_text

# Создаем Gradio-интерфейс
iface = gr.Interface(
    fn=process_image,
    inputs=gr.Image(type="numpy", label="Исходное изображение"),
    outputs=[
        gr.Image(type="numpy", label="Изображение с обнаруженными комнатами"),
        gr.Textbox(label="Координаты углов комнат", lines=10)
    ],
    title="Детекция комнат с использованием YOLO и Gradio",
    description="Загрузите изображение для детекции комнат и отображения углов."
)

iface.launch()