Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -9,6 +9,7 @@ import numpy as np
|
|
9 |
import cv2
|
10 |
from pathlib import Path
|
11 |
import tempfile
|
|
|
12 |
|
13 |
# 从环境变量获取密码
|
14 |
APP_USERNAME = "admin" # 用户名保持固定
|
@@ -295,13 +296,66 @@ def process_video(video_path, process_seconds=20, conf_threshold=0.2, max_det=8)
|
|
295 |
alpha = 0.7
|
296 |
heatmap_colored = cv2.addWeighted(heatmap_colored, alpha, np.full_like(heatmap_colored, 255), 1-alpha, 0)
|
297 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
298 |
# 保存图像
|
299 |
trajectory_path = output_path.replace('.mp4', '_trajectory.png')
|
300 |
heatmap_path = output_path.replace('.mp4', '_heatmap.png')
|
301 |
cv2.imwrite(trajectory_path, trajectory_img)
|
302 |
cv2.imwrite(heatmap_path, heatmap_colored)
|
303 |
|
304 |
-
return output_path, trajectory_path, heatmap_path, report
|
305 |
|
306 |
# 创建 Gradio 界面
|
307 |
with gr.Blocks() as demo:
|
@@ -347,14 +401,17 @@ with gr.Blocks() as demo:
|
|
347 |
video_output = gr.Video(label="检测结果")
|
348 |
with gr.Row():
|
349 |
trajectory_output = gr.Image(label="运动轨迹")
|
|
|
|
|
350 |
heatmap_output = gr.Image(label="热力图")
|
|
|
351 |
report_output = gr.Textbox(label="分析报告")
|
352 |
|
353 |
gr.Markdown("""
|
354 |
### 使用说明
|
355 |
1. 上传视频文件
|
356 |
2. 设置处理参数:
|
357 |
-
-
|
358 |
- 置信度阈值:检测的置信度要求(越高越严格)
|
359 |
- 最大检测数量:每帧最多检测的目标数量
|
360 |
3. 等待处理完成
|
@@ -378,7 +435,8 @@ with gr.Blocks() as demo:
|
|
378 |
process_btn.click(
|
379 |
fn=process_video,
|
380 |
inputs=[video_input, process_seconds, conf_threshold, max_det],
|
381 |
-
outputs=[video_output, trajectory_output, heatmap_output,
|
|
|
382 |
)
|
383 |
|
384 |
if __name__ == "__main__":
|
|
|
9 |
import cv2
|
10 |
from pathlib import Path
|
11 |
import tempfile
|
12 |
+
import imageio
|
13 |
|
14 |
# 从环境变量获取密码
|
15 |
APP_USERNAME = "admin" # 用户名保持固定
|
|
|
296 |
alpha = 0.7
|
297 |
heatmap_colored = cv2.addWeighted(heatmap_colored, alpha, np.full_like(heatmap_colored, 255), 1-alpha, 0)
|
298 |
|
299 |
+
# 准备GIF动画帧
|
300 |
+
trajectory_frames = []
|
301 |
+
heatmap_frames = []
|
302 |
+
|
303 |
+
# 创建基础图像
|
304 |
+
base_trajectory = np.zeros((height, width, 3), dtype=np.uint8) + 255
|
305 |
+
base_heatmap = np.zeros((height, width), dtype=np.float32)
|
306 |
+
|
307 |
+
# 每N帧生成一个动画帧
|
308 |
+
frame_interval = max(1, len(filtered_points) // 50) # 控制GIF帧数
|
309 |
+
|
310 |
+
for i in range(0, len(filtered_points), frame_interval):
|
311 |
+
current_points = filtered_points[:i+1]
|
312 |
+
|
313 |
+
# 轨迹动画帧
|
314 |
+
frame_trajectory = base_trajectory.copy()
|
315 |
+
if len(current_points) > 1:
|
316 |
+
points = np.array(current_points, dtype=np.int32)
|
317 |
+
for j in range(len(points) - 1):
|
318 |
+
ratio = j / (len(points) - 1)
|
319 |
+
color = (
|
320 |
+
int((1 - ratio) * 255), # B
|
321 |
+
50, # G
|
322 |
+
int(ratio * 255) # R
|
323 |
+
)
|
324 |
+
cv2.line(frame_trajectory, tuple(points[j]), tuple(points[j + 1]), color, 2)
|
325 |
+
|
326 |
+
# 绘制当前位置点
|
327 |
+
cv2.circle(frame_trajectory, tuple(points[-1]), 8, (0, 0, 255), -1)
|
328 |
+
trajectory_frames.append(frame_trajectory)
|
329 |
+
|
330 |
+
# 热图动画帧
|
331 |
+
frame_heatmap = base_heatmap.copy()
|
332 |
+
for x, y in current_points:
|
333 |
+
if 0 <= x < width and 0 <= y < height:
|
334 |
+
temp_heatmap = np.zeros((height, width), dtype=np.float32)
|
335 |
+
temp_heatmap[y, x] = 1
|
336 |
+
temp_heatmap = cv2.GaussianBlur(temp_heatmap, (31, 31), 10)
|
337 |
+
frame_heatmap += temp_heatmap
|
338 |
+
|
339 |
+
if np.max(frame_heatmap) > 0:
|
340 |
+
frame_heatmap_norm = cv2.normalize(frame_heatmap, None, 0, 255, cv2.NORM_MINMAX)
|
341 |
+
frame_heatmap_color = cv2.applyColorMap(frame_heatmap_norm.astype(np.uint8), cv2.COLORMAP_JET)
|
342 |
+
frame_heatmap_color = cv2.addWeighted(frame_heatmap_color, 0.7, np.full_like(frame_heatmap_color, 255), 0.3, 0)
|
343 |
+
heatmap_frames.append(frame_heatmap_color)
|
344 |
+
|
345 |
+
# 保存GIF动画
|
346 |
+
trajectory_gif_path = output_path.replace('.mp4', '_trajectory_animation.jpg') # 实际是GIF但用jpg后缀
|
347 |
+
heatmap_gif_path = output_path.replace('.mp4', '_heatmap_animation.jpg') # 实际是GIF但用jpg后缀
|
348 |
+
|
349 |
+
imageio.mimsave(trajectory_gif_path, trajectory_frames, duration=50) # 50ms per frame
|
350 |
+
imageio.mimsave(heatmap_gif_path, heatmap_frames, duration=50)
|
351 |
+
|
352 |
# 保存图像
|
353 |
trajectory_path = output_path.replace('.mp4', '_trajectory.png')
|
354 |
heatmap_path = output_path.replace('.mp4', '_heatmap.png')
|
355 |
cv2.imwrite(trajectory_path, trajectory_img)
|
356 |
cv2.imwrite(heatmap_path, heatmap_colored)
|
357 |
|
358 |
+
return output_path, trajectory_path, heatmap_path, trajectory_gif_path, heatmap_gif_path, report
|
359 |
|
360 |
# 创建 Gradio 界面
|
361 |
with gr.Blocks() as demo:
|
|
|
401 |
video_output = gr.Video(label="检测结果")
|
402 |
with gr.Row():
|
403 |
trajectory_output = gr.Image(label="运动轨迹")
|
404 |
+
trajectory_gif_output = gr.Image(label="轨迹动画")
|
405 |
+
with gr.Row():
|
406 |
heatmap_output = gr.Image(label="热力图")
|
407 |
+
heatmap_gif_output = gr.Image(label="热力图动画")
|
408 |
report_output = gr.Textbox(label="分析报告")
|
409 |
|
410 |
gr.Markdown("""
|
411 |
### 使用说明
|
412 |
1. 上传视频文件
|
413 |
2. 设置处理参数:
|
414 |
+
- 处理时长:需要分析的视频时长(秒
|
415 |
- 置信度阈值:检测的置信度要求(越高越严格)
|
416 |
- 最大检测数量:每帧最多检测的目标数量
|
417 |
3. 等待处理完成
|
|
|
435 |
process_btn.click(
|
436 |
fn=process_video,
|
437 |
inputs=[video_input, process_seconds, conf_threshold, max_det],
|
438 |
+
outputs=[video_output, trajectory_output, heatmap_output,
|
439 |
+
trajectory_gif_output, heatmap_gif_output, report_output]
|
440 |
)
|
441 |
|
442 |
if __name__ == "__main__":
|