1
- # --- ФАЙЛ: python_src/analytics.py (финальная версия с выбором провайдера ) ---
1
+ # --- ФАЙЛ: python_src/analytics.py (ВЕРСИЯ С ВРЕМЕННЫМИ ФАЙЛАМИ ) ---
2
2
3
3
import sys
4
4
import os
5
5
import json
6
6
import time
7
- import base64
7
+ import tempfile # <-- Импортируем модуль для работы с временными файлами
8
8
import threading
9
+ import numpy as np
9
10
11
+ # Проверяем, запущено ли приложение как .exe (frozen) или как .py скрипт
10
12
if getattr (sys , 'frozen' , False ):
11
13
application_path = sys ._MEIPASS
12
14
else :
13
15
application_path = os .path .dirname (os .path .abspath (__file__ ))
14
16
17
+ # Импортируем основные библиотеки
15
18
try :
16
19
import cv2
17
- import numpy as np
18
20
import onnxruntime as ort
19
21
except Exception as e :
20
22
error_message = f"Fatal error during library import: { str (e )} "
@@ -104,7 +106,6 @@ def run_analytics(rtsp_url, config_str, provider_choice='auto'):
104
106
try :
105
107
model_path = os .path .join (application_path , 'yolov8n.onnx' )
106
108
session = None
107
-
108
109
available_providers = ort .get_available_providers ()
109
110
110
111
def try_provider (provider_name ):
@@ -114,7 +115,6 @@ def try_provider(provider_name):
114
115
provider_options = {}
115
116
if provider_name == 'DmlExecutionProvider' :
116
117
provider_options = {'device_id' : '0' }
117
-
118
118
session = ort .InferenceSession (model_path , providers = [(provider_name , provider_options ), 'CPUExecutionProvider' ])
119
119
print (json .dumps ({"status" : "info" , "provider" : provider_name }), flush = True )
120
120
return True
@@ -154,6 +154,9 @@ def try_provider(provider_name):
154
154
frame_skip = int (config .get ('frame_skip' , 5 )) or 1
155
155
frame_grabber = None
156
156
157
+ # Получаем системную папку для временных файлов
158
+ temp_dir = tempfile .gettempdir ()
159
+
157
160
while True :
158
161
if frame_grabber is None or frame_grabber .stopped :
159
162
try :
@@ -164,6 +167,7 @@ def try_provider(provider_name):
164
167
print (json .dumps ({"status" : "error" , "message" : str (e )}), flush = True )
165
168
time .sleep (5 )
166
169
continue
170
+
167
171
frame_count = 0
168
172
while not frame_grabber .stopped :
169
173
ret , frame = frame_grabber .read ()
@@ -175,18 +179,37 @@ def try_provider(provider_name):
175
179
frame_count += 1
176
180
if frame_count % frame_skip != 0 :
177
181
continue
182
+
183
+ original_height , original_width = frame .shape [:2 ]
178
184
input_tensor , ratio , pad = preprocess (frame , input_width , input_height )
179
185
outputs = session .run ([output_name ], {input_name : input_tensor })
180
186
detections = postprocess (outputs [0 ], ratio , pad , confidence_threshold )
181
187
182
188
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
+ # ^^^^^^ --- КОНЕЦ ИЗМЕНЕНИЯ --- ^^^^^^
183
211
184
212
if len (filtered_objects ) > 0 :
185
- result = {
186
- "status" : "objects_detected" ,
187
- "timestamp" : time .time (),
188
- "objects" : filtered_objects
189
- }
190
213
print (json .dumps (result ), flush = True )
191
214
192
215
except Exception as e :
0 commit comments