teslatony commited on
Commit
f2b0c81
·
verified ·
1 Parent(s): 5a32a5d

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +84 -80
app.py CHANGED
@@ -1,82 +1,86 @@
1
- import gradio as gr
2
- from ultralytics import YOLO
3
- import os
4
- import glob
5
- import shutil
6
- import tempfile
7
-
8
- # Загружаем модель один раз (YOLOv8n — лёгкая версия для object detection)
9
- model = YOLO("yolov8n.pt")
10
-
11
- def process_video(video):
12
- """
13
- Обрабатывает видео: обнаруживает объекты на каждом кадре и сохраняет аннотированный ролик.
14
- """
15
- if video is None:
16
- return None, "Пожалуйста, загрузите видео или захватите с веб-камеры."
17
-
18
- # Создаём временную директорию для результатов
19
- temp_dir = "temp_output"
20
- os.makedirs(temp_dir, exist_ok=True)
21
-
22
- # Обработка видео с сохранением аннотаций
23
- results = model.predict(
24
- source=video,
25
- save=True,
26
- project=temp_dir,
27
- name="detect",
28
- exist_ok=True,
29
- imgsz=640, # Размер изображения для обработки
30
- conf=0.25, # Порог уверенности
31
- show=False # Не показывать в окне
32
- )
33
-
34
- # Находим сохранённый аннотированный видео-файл
35
- output_pattern = os.path.join(temp_dir, "detect", "*.mp4")
36
- output_files = glob.glob(output_pattern)
37
-
38
- if output_files:
39
- # Копируем в статическую папку для Gradio (HF Spaces требует)
40
- static_path = "./static"
41
- os.makedirs(static_path, exist_ok=True)
42
- output_file = output_files[0]
43
- shutil.copy2(output_file, os.path.join(static_path, "annotated_video.mp4"))
44
- return os.path.join(static_path, "annotated_video.mp4"), "Обработка завершена! Объекты (люди, машины и т.д.) отмечены боксами."
45
- else:
46
- return None, "Ошибка: видео не обработано. Попробуйте другой файл или короче клип."
47
-
48
- # Создаём интерфейс на русском
49
- with gr.Blocks(title="Обнаружение объектов в видео") as demo:
50
- gr.Markdown("# Обнаружение объектов в видео")
51
- gr.Markdown("Загрузите видео-файл (MP4, AVI и т.д.) **или** захватите с веб-камеры. Приложение автоматически обнаружит объекты с помощью модели YOLOv8. Результат — видео с bounding boxes вокруг объектов.")
52
-
53
- with gr.Row():
54
- input_video = gr.Video(
55
- label="Видео: загрузите файл или захватите с веб-камеры",
56
- sources=["upload", "webcam"], # Поддержка обоих источников
57
- format="mp4" # Авто-конверт в MP4
58
- )
59
- output_video = gr.Video(
60
- label="Аннотированное видео",
61
- interactive=False, # Только просмотр
62
- format="mp4" # Формат вывода
63
- )
64
-
65
- output_text = gr.Textbox(label="Статус", interactive=False)
66
-
67
- process_btn = gr.Button("Запустить обнаружение", variant="primary")
68
-
69
- process_btn.click(
70
- fn=process_video,
71
- inputs=[input_video],
72
- outputs=[output_video, output_text]
73
- )
74
-
75
- gr.Examples(
76
- examples=[],
77
- inputs=[input_video],
78
- label="Примеры: добавьте свои видео для демонстрации"
79
- )
 
 
80
 
81
  if __name__ == "__main__":
82
- demo.launch()
 
 
 
1
+ """Gradio приложение: распознавание объектов с веб-камеры в реальном времени
2
+ ultralytics модель работает с RGB или PIL, но результаты.plot() возвращает BGR (cv2-style).
3
+ """
4
+ if img is None:
5
+ raise ValueError("Пустое изображение на входе")
6
+ # Если image в формате PIL -> конвертируем в numpy
7
+ if not isinstance(img, np.ndarray):
8
+ img = np.array(img)
9
+ # Gradio возвращает изображение в RGB (H,W,3)
10
+ return img
11
+
12
+
13
+
14
+
15
+ def detect_and_annotate(frame: np.ndarray) -> np.ndarray:
16
+ """Выполняет обнаружение объектов и возвращает аннотированный кадр (RGB numpy array).
17
+
18
+
19
+ Функция специально проектирована, чтобы быть быстрым и устойчивым для демонстрации в реальном времени.
20
+ """
21
+ # Подготовка
22
+ img = preprocess_image(frame)
23
+
24
+
25
+ # Выполнить инференс (возвращает Results object)
26
+ try:
27
+ results = model(img, imgsz=640, conf=0.25, half=False) # conf и imgsz можно настроить
28
+ except Exception as e:
29
+ # В случае ошибки возвращаем исходный кадр
30
+ print(f"Inference error: {e}")
31
+ return img
32
+
33
+
34
+ # results может содержать батч; берем первый
35
+ r = results[0]
36
+
37
+
38
+ # Получить аннотированное изображение. results.plot() возвращает изображение в формате BGR (OpenCV)
39
+ annotated = r.plot()
40
+
41
+
42
+ # Если annotated - None, вернем исходный RGB
43
+ if annotated is None:
44
+ return img
45
+
46
+
47
+ # Конвертируем BGR->RGB для корректного отображения в Gradio
48
+ try:
49
+ annotated_rgb = cv2.cvtColor(annotated, cv2.COLOR_BGR2RGB)
50
+ except Exception:
51
+ # Если распознавание возвращает RGB сразу
52
+ annotated_rgb = annotated
53
+
54
+
55
+ return annotated_rgb
56
+
57
+
58
+
59
+
60
+ # Gradio интерфейс
61
+
62
+
63
+ def build_interface():
64
+ with gr.Blocks(title="Realtime Object Detection — YOLOv8") as demo:
65
+ gr.Markdown("## Распознавание объектов с веб-камеры (реальное время)")
66
+ with gr.Row():
67
+ webcam = gr.Image(source="webcam", type="numpy", tool="editor", label="Веб-камера", streaming=True)
68
+ out_img = gr.Image(label="Результат", type="numpy")
69
+
70
+
71
+ # Кнопка не нужна — каждый кадр будет обрабатываться при обновлении благодаря streaming=True
72
+ webcam.change(fn=detect_and_annotate, inputs=webcam, outputs=out_img)
73
+
74
+
75
+ gr.Markdown("---\nНастройки: модель yolov8n (скачивается автоматически при первом запуске).\nНастройте conf или imgsz в вызове model(...) при необходимости.")
76
+
77
+
78
+ return demo
79
+
80
+
81
+
82
 
83
  if __name__ == "__main__":
84
+ demo = build_interface()
85
+ # Для портфолио и локального запуска: share=False, server_name и server_port можно изменить
86
+ demo.launch(server_name="0.0.0.0", server_port=7860, share=False)