1- # --- ФАЙЛ: python_src/analytics.py (финальная версия с выбором провайдера ) ---
1+ # --- ФАЙЛ: python_src/analytics.py (ВЕРСИЯ С ВРЕМЕННЫМИ ФАЙЛАМИ ) ---
22
33import sys
44import os
55import json
66import time
7- import base64
7+ import tempfile # <-- Импортируем модуль для работы с временными файлами
88import threading
9+ import numpy as np
910
11+ # Проверяем, запущено ли приложение как .exe (frozen) или как .py скрипт
1012if getattr (sys , 'frozen' , False ):
1113 application_path = sys ._MEIPASS
1214else :
1315 application_path = os .path .dirname (os .path .abspath (__file__ ))
1416
17+ # Импортируем основные библиотеки
1518try :
1619 import cv2
17- import numpy as np
1820 import onnxruntime as ort
1921except Exception as e :
2022 error_message = f"Fatal error during library import: { str (e )} "
@@ -104,7 +106,6 @@ def run_analytics(rtsp_url, config_str, provider_choice='auto'):
104106 try :
105107 model_path = os .path .join (application_path , 'yolov8n.onnx' )
106108 session = None
107-
108109 available_providers = ort .get_available_providers ()
109110
110111 def try_provider (provider_name ):
@@ -114,7 +115,6 @@ def try_provider(provider_name):
114115 provider_options = {}
115116 if provider_name == 'DmlExecutionProvider' :
116117 provider_options = {'device_id' : '0' }
117-
118118 session = ort .InferenceSession (model_path , providers = [(provider_name , provider_options ), 'CPUExecutionProvider' ])
119119 print (json .dumps ({"status" : "info" , "provider" : provider_name }), flush = True )
120120 return True
@@ -154,6 +154,9 @@ def try_provider(provider_name):
154154 frame_skip = int (config .get ('frame_skip' , 5 )) or 1
155155 frame_grabber = None
156156
157+ # Получаем системную папку для временных файлов
158+ temp_dir = tempfile .gettempdir ()
159+
157160 while True :
158161 if frame_grabber is None or frame_grabber .stopped :
159162 try :
@@ -164,6 +167,7 @@ def try_provider(provider_name):
164167 print (json .dumps ({"status" : "error" , "message" : str (e )}), flush = True )
165168 time .sleep (5 )
166169 continue
170+
167171 frame_count = 0
168172 while not frame_grabber .stopped :
169173 ret , frame = frame_grabber .read ()
@@ -175,18 +179,37 @@ def try_provider(provider_name):
175179 frame_count += 1
176180 if frame_count % frame_skip != 0 :
177181 continue
182+
183+ original_height , original_width = frame .shape [:2 ]
178184 input_tensor , ratio , pad = preprocess (frame , input_width , input_height )
179185 outputs = session .run ([output_name ], {input_name : input_tensor })
180186 detections = postprocess (outputs [0 ], ratio , pad , confidence_threshold )
181187
182188 filtered_objects = [obj for obj in detections if obj ['label' ] in objects_to_detect ] if objects_to_detect else detections
189+ persons_found = any (obj ['label' ] == 'person' for obj in filtered_objects )
190+
191+ result = {
192+ "status" : "objects_detected" ,
193+ "timestamp" : time .time (),
194+ "objects" : filtered_objects ,
195+ "frame_width" : original_width ,
196+ "frame_height" : original_height
197+ }
198+
199+ # VVVVVV --- ИЗМЕНЕНИЕ: СОХРАНЯЕМ КАДР В ФАЙЛ ВМЕСТО BASE64 --- VVVVVV
200+ if persons_found :
201+ # Создаем уникальное имя для временного файла
202+ temp_filename = f"dashboard_frame_{ time .time ()} _{ os .getpid ()} .jpg"
203+ temp_filepath = os .path .join (temp_dir , temp_filename )
204+
205+ # Сохраняем кадр в этот файл с высоким качеством
206+ cv2 .imwrite (temp_filepath , frame , [cv2 .IMWRITE_JPEG_QUALITY , 95 ])
207+
208+ # Добавляем в JSON не сам кадр, а ТОЛЬКО ПУТЬ к нему
209+ result ['frame_path' ] = temp_filepath
210+ # ^^^^^^ --- КОНЕЦ ИЗМЕНЕНИЯ --- ^^^^^^
183211
184212 if len (filtered_objects ) > 0 :
185- result = {
186- "status" : "objects_detected" ,
187- "timestamp" : time .time (),
188- "objects" : filtered_objects
189- }
190213 print (json .dumps (result ), flush = True )
191214
192215 except Exception as e :
0 commit comments