Spaces:
Runtime error
Runtime error
Upload 2 files
Browse files- app.py +31 -28
- model_list.txt +5 -0
app.py
CHANGED
|
@@ -2,24 +2,24 @@ from ultralytics import YOLO #行人识别,采用YoloV8模型
|
|
| 2 |
import math #用于四舍五入取整
|
| 3 |
import cv2 #opencv图像处理库
|
| 4 |
import cvzone #在图像上绘画
|
| 5 |
-
|
| 6 |
import gradio as gr #GUI界面
|
| 7 |
from sort import * #运动检测,采用sort算法
|
| 8 |
-
#from deep_sort_realtime.deepsort_tracker import DeepSort #不会用QAQ
|
| 9 |
import tempfile #创建输出临时文件夹
|
| 10 |
import os
|
| 11 |
from detectMotion import * #单独的运动检测
|
| 12 |
import time
|
| 13 |
-
#from matplotlib.pyplot import MultipleLocator
|
| 14 |
|
| 15 |
|
| 16 |
-
#导入YoloV8模型,
|
| 17 |
-
|
| 18 |
-
|
| 19 |
-
|
| 20 |
-
flag = False
|
| 21 |
|
| 22 |
-
#
|
|
|
|
|
|
|
|
|
|
| 23 |
classNames=['person', 'bicycle', 'car', 'motorcycle', 'airplane', 'bus', 'train', 'truck', 'boat', 'traffic light',
|
| 24 |
'fire hydrant',
|
| 25 |
'stop sign', 'parking meter', 'bench', 'bird', 'cat', 'dog', 'horse', 'sheep', 'cow', 'elephant', 'bear', 'zebra',
|
|
@@ -36,16 +36,19 @@ classNames=['person', 'bicycle', 'car', 'motorcycle', 'airplane', 'bus', 'train'
|
|
| 36 |
#运动检测算法参数
|
| 37 |
tracker=Sort(max_age=20,min_hits=3,iou_threshold=0.3)
|
| 38 |
|
|
|
|
| 39 |
def plot_number():
|
| 40 |
-
global number_of_people_in_one_frame_list
|
| 41 |
-
if flag == False:
|
| 42 |
-
time.sleep(15)
|
| 43 |
-
flag = True
|
| 44 |
plt.close()
|
| 45 |
fig = plt.figure()
|
| 46 |
plt.xlabel('Second')
|
| 47 |
plt.ylabel('Traffic')
|
| 48 |
plt.grid(linestyle='--', alpha=0.3, linewidth=2)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 49 |
plt.plot(number_of_people_in_one_frame_list)
|
| 50 |
return fig
|
| 51 |
|
|
@@ -95,9 +98,11 @@ def processImg(img,sigma,median_filter,ISR):
|
|
| 95 |
return res1, fig1, fig2
|
| 96 |
|
| 97 |
#视频处理
|
| 98 |
-
def processVideo(inputPath,codec):
|
| 99 |
-
global number_of_people_in_one_frame_list
|
| 100 |
-
|
|
|
|
|
|
|
| 101 |
number_of_people_in_one_frame = 0
|
| 102 |
number_of_people_in_one_frame_list = []
|
| 103 |
number_of_people = 0
|
|
@@ -112,10 +117,10 @@ def processVideo(inputPath,codec):
|
|
| 112 |
#输出格式
|
| 113 |
if codec == "mp4":
|
| 114 |
#h264:avc1,此处为了兼容性换成mp4v
|
| 115 |
-
fourcc = cv2.VideoWriter_fourcc('m','p','4','v')#视频编码:
|
| 116 |
video_save_path = os.path.join(outputPath,"output.mp4")#创建输出视频路径
|
| 117 |
elif codec == "avi":
|
| 118 |
-
fourcc = cv2.VideoWriter_fourcc('h','2','6','4')#视频编码:h264,只能保存为avi格式
|
| 119 |
video_save_path = os.path.join(outputPath,"output.avi")#创建输出视频路径
|
| 120 |
elif codec == "mkv":
|
| 121 |
fourcc = cv2.VideoWriter_fourcc('X','V','I','D')#视频编码:XVID,此编码不需要openh264-1.8.0-win64.dll
|
|
@@ -125,14 +130,14 @@ def processVideo(inputPath,codec):
|
|
| 125 |
video_save_path = os.path.join(outputPath,"output.wmv")#创建输出视频路径
|
| 126 |
elif codec == "mp4(h264)":
|
| 127 |
#h264:avc1, 在本地运行时可以在浏览器播放
|
| 128 |
-
fourcc = cv2.VideoWriter_fourcc('a','v','c','1')#视频编码:h264,
|
| 129 |
-
video_save_path = os.path.join(outputPath,"
|
| 130 |
|
| 131 |
output_viedo.open(video_save_path , fourcc, fps, size, True)
|
| 132 |
#对每一帧图片进行读取和处理
|
| 133 |
while True:
|
| 134 |
ret, img = cap.read()#将每一帧图片读取到img当中
|
| 135 |
-
results=model(img,stream=True)#使用YoloV8模型进行推理
|
| 136 |
detections=np.empty((0, 5))#初始化运动检测
|
| 137 |
if not(ret):#当视频全部读完,ret返回false,终止循环,视频帧读取和写入结束
|
| 138 |
break
|
|
@@ -157,7 +162,6 @@ def processVideo(inputPath,codec):
|
|
| 157 |
sum_of_frame += 1
|
| 158 |
if sum_of_frame % fps == 0:
|
| 159 |
number_of_people_in_one_frame_list.append(number_of_people_in_one_frame)
|
| 160 |
-
#print(type(number_of_people_in_one_frame_list))
|
| 161 |
number_of_people_in_one_frame = 0
|
| 162 |
#运动检测
|
| 163 |
resultsTracker=tracker.update(detections)
|
|
@@ -165,13 +169,11 @@ def processVideo(inputPath,codec):
|
|
| 165 |
x1,y1,x2,y2,Id=result
|
| 166 |
number_of_people=max(str(int(Id)),str(number_of_people))
|
| 167 |
x1,y1,x2,y2=int(x1),int(y1),int(x2),int(y2)#将浮点数转变为整型
|
| 168 |
-
#print(result)
|
| 169 |
cvzone.putTextRect(img,f'{int(Id)}',(max(0,x1),max(30,y1)),scale=0.7,thickness=1)
|
| 170 |
#image_np = np.squeeze(img.render())#用np.squeeze将输出结果降维
|
| 171 |
output_viedo.write(img)#将处理后的图像写入视频
|
| 172 |
output_viedo.release()#释放
|
| 173 |
cap.release()#释放
|
| 174 |
-
flag = False
|
| 175 |
return video_save_path,video_save_path
|
| 176 |
|
| 177 |
|
|
@@ -198,6 +200,7 @@ with gr.Blocks() as demo:
|
|
| 198 |
text_inputPath = gr.Video()
|
| 199 |
codec = gr.Radio(["mp4","avi","mkv","wmv",'mp4(h264)'], label="输出视频格式",
|
| 200 |
value="mp4")
|
|
|
|
| 201 |
videoProcess_button = gr.Button("处理")
|
| 202 |
with gr.Column():
|
| 203 |
text_output = gr.Video()
|
|
@@ -205,7 +208,6 @@ with gr.Blocks() as demo:
|
|
| 205 |
with gr.Row():
|
| 206 |
with gr.Column():
|
| 207 |
figure_number_output = gr.Plot(label="人流量")
|
| 208 |
-
#plotProcess_button = gr.Button("人流量显示")
|
| 209 |
with gr.Tab("图像增强"):
|
| 210 |
with gr.Row():
|
| 211 |
with gr.Column():
|
|
@@ -226,14 +228,15 @@ with gr.Blocks() as demo:
|
|
| 226 |
motionProcess_button = gr.Button("处理")
|
| 227 |
motion_output_frame = gr.Video()
|
| 228 |
motion_output_fmask = gr.Video()
|
| 229 |
-
|
| 230 |
-
|
|
|
|
| 231 |
with gr.Accordion("算法:"):
|
| 232 |
gr.Markdown("高斯混合模型(GMM)")
|
| 233 |
|
| 234 |
|
| 235 |
|
| 236 |
-
videoProcess_button.click(processVideo, inputs=[text_inputPath,codec],
|
| 237 |
outputs=[text_output,text_output_path])
|
| 238 |
image_button.click(processImg, inputs=[image_input,image_sigma,median_filter,Add_ISR],
|
| 239 |
outputs=[image_output,figure_pre_output,figure_post_output])
|
|
|
|
| 2 |
import math #用于四舍五入取整
|
| 3 |
import cv2 #opencv图像处理库
|
| 4 |
import cvzone #在图像上绘画
|
| 5 |
+
import numpy as np
|
| 6 |
import gradio as gr #GUI界面
|
| 7 |
from sort import * #运动检测,采用sort算法
|
|
|
|
| 8 |
import tempfile #创建输出临时文件夹
|
| 9 |
import os
|
| 10 |
from detectMotion import * #单独的运动检测
|
| 11 |
import time
|
|
|
|
| 12 |
|
| 13 |
|
| 14 |
+
#导入YoloV8模型,模型名称存储在model_list.txt中
|
| 15 |
+
with open("model_list.txt") as file:
|
| 16 |
+
lines = file.readlines()
|
| 17 |
+
model_list = [line.rstrip() for line in lines] #逐行导入
|
|
|
|
| 18 |
|
| 19 |
+
#用于人流量统计
|
| 20 |
+
number_of_people_in_one_frame_list = []
|
| 21 |
+
|
| 22 |
+
#YoloV8官方模型标签数据,本次项目只使用了'person'
|
| 23 |
classNames=['person', 'bicycle', 'car', 'motorcycle', 'airplane', 'bus', 'train', 'truck', 'boat', 'traffic light',
|
| 24 |
'fire hydrant',
|
| 25 |
'stop sign', 'parking meter', 'bench', 'bird', 'cat', 'dog', 'horse', 'sheep', 'cow', 'elephant', 'bear', 'zebra',
|
|
|
|
| 36 |
#运动检测算法参数
|
| 37 |
tracker=Sort(max_age=20,min_hits=3,iou_threshold=0.3)
|
| 38 |
|
| 39 |
+
#实时显示人流量统计图表
|
| 40 |
def plot_number():
|
| 41 |
+
global number_of_people_in_one_frame_list
|
|
|
|
|
|
|
|
|
|
| 42 |
plt.close()
|
| 43 |
fig = plt.figure()
|
| 44 |
plt.xlabel('Second')
|
| 45 |
plt.ylabel('Traffic')
|
| 46 |
plt.grid(linestyle='--', alpha=0.3, linewidth=2)
|
| 47 |
+
#若函数在YOLO模型生成bounding box前运行,则返回空图表
|
| 48 |
+
if number_of_people_in_one_frame_list == []:
|
| 49 |
+
time.sleep(3) #延迟3秒
|
| 50 |
+
plt.plot([])
|
| 51 |
+
return fig
|
| 52 |
plt.plot(number_of_people_in_one_frame_list)
|
| 53 |
return fig
|
| 54 |
|
|
|
|
| 98 |
return res1, fig1, fig2
|
| 99 |
|
| 100 |
#视频处理
|
| 101 |
+
def processVideo(inputPath, codec, model):
|
| 102 |
+
global number_of_people_in_one_frame_list
|
| 103 |
+
if inputPath == None:
|
| 104 |
+
raise gr.Error("请先上传视频")
|
| 105 |
+
model=YOLO(model)
|
| 106 |
number_of_people_in_one_frame = 0
|
| 107 |
number_of_people_in_one_frame_list = []
|
| 108 |
number_of_people = 0
|
|
|
|
| 117 |
#输出格式
|
| 118 |
if codec == "mp4":
|
| 119 |
#h264:avc1,此处为了兼容性换成mp4v
|
| 120 |
+
fourcc = cv2.VideoWriter_fourcc('m','p','4','v')#视频编码:mp4v,此编码不需要openh264-1.8.0-win64.dll
|
| 121 |
video_save_path = os.path.join(outputPath,"output.mp4")#创建输出视频路径
|
| 122 |
elif codec == "avi":
|
| 123 |
+
fourcc = cv2.VideoWriter_fourcc('h','2','6','4')#视频编码:h264,只能保存为avi格式,本地运行时不能在浏览器播放
|
| 124 |
video_save_path = os.path.join(outputPath,"output.avi")#创建输出视频路径
|
| 125 |
elif codec == "mkv":
|
| 126 |
fourcc = cv2.VideoWriter_fourcc('X','V','I','D')#视频编码:XVID,此编码不需要openh264-1.8.0-win64.dll
|
|
|
|
| 130 |
video_save_path = os.path.join(outputPath,"output.wmv")#创建输出视频路径
|
| 131 |
elif codec == "mp4(h264)":
|
| 132 |
#h264:avc1, 在本地运行时可以在浏览器播放
|
| 133 |
+
fourcc = cv2.VideoWriter_fourcc('a','v','c','1')#视频编码:h264,本地运行时可直接在浏览器播放
|
| 134 |
+
video_save_path = os.path.join(outputPath,"output_h264.mp4")#创建输出视频路径
|
| 135 |
|
| 136 |
output_viedo.open(video_save_path , fourcc, fps, size, True)
|
| 137 |
#对每一帧图片进行读取和处理
|
| 138 |
while True:
|
| 139 |
ret, img = cap.read()#将每一帧图片读取到img当中
|
| 140 |
+
results=model(img,stream=True)#使用YoloV8模型进行推理
|
| 141 |
detections=np.empty((0, 5))#初始化运动检测
|
| 142 |
if not(ret):#当视频全部读完,ret返回false,终止循环,视频帧读取和写入结束
|
| 143 |
break
|
|
|
|
| 162 |
sum_of_frame += 1
|
| 163 |
if sum_of_frame % fps == 0:
|
| 164 |
number_of_people_in_one_frame_list.append(number_of_people_in_one_frame)
|
|
|
|
| 165 |
number_of_people_in_one_frame = 0
|
| 166 |
#运动检测
|
| 167 |
resultsTracker=tracker.update(detections)
|
|
|
|
| 169 |
x1,y1,x2,y2,Id=result
|
| 170 |
number_of_people=max(str(int(Id)),str(number_of_people))
|
| 171 |
x1,y1,x2,y2=int(x1),int(y1),int(x2),int(y2)#将浮点数转变为整型
|
|
|
|
| 172 |
cvzone.putTextRect(img,f'{int(Id)}',(max(0,x1),max(30,y1)),scale=0.7,thickness=1)
|
| 173 |
#image_np = np.squeeze(img.render())#用np.squeeze将输出结果降维
|
| 174 |
output_viedo.write(img)#将处理后的图像写入视频
|
| 175 |
output_viedo.release()#释放
|
| 176 |
cap.release()#释放
|
|
|
|
| 177 |
return video_save_path,video_save_path
|
| 178 |
|
| 179 |
|
|
|
|
| 200 |
text_inputPath = gr.Video()
|
| 201 |
codec = gr.Radio(["mp4","avi","mkv","wmv",'mp4(h264)'], label="输出视频格式",
|
| 202 |
value="mp4")
|
| 203 |
+
model = gr.Dropdown(model_list, value="yolov8n.pt", label="模型", info="模型列表存储在model_list.txt中")
|
| 204 |
videoProcess_button = gr.Button("处理")
|
| 205 |
with gr.Column():
|
| 206 |
text_output = gr.Video()
|
|
|
|
| 208 |
with gr.Row():
|
| 209 |
with gr.Column():
|
| 210 |
figure_number_output = gr.Plot(label="人流量")
|
|
|
|
| 211 |
with gr.Tab("图像增强"):
|
| 212 |
with gr.Row():
|
| 213 |
with gr.Column():
|
|
|
|
| 228 |
motionProcess_button = gr.Button("处理")
|
| 229 |
motion_output_frame = gr.Video()
|
| 230 |
motion_output_fmask = gr.Video()
|
| 231 |
+
with gr.Column():
|
| 232 |
+
frame_output_path = gr.Text(label="frame输出路径")
|
| 233 |
+
fmask_output_path = gr.Text(label="mask输出路径")
|
| 234 |
with gr.Accordion("算法:"):
|
| 235 |
gr.Markdown("高斯混合模型(GMM)")
|
| 236 |
|
| 237 |
|
| 238 |
|
| 239 |
+
videoProcess_button.click(processVideo, inputs=[text_inputPath, codec, model],
|
| 240 |
outputs=[text_output,text_output_path])
|
| 241 |
image_button.click(processImg, inputs=[image_input,image_sigma,median_filter,Add_ISR],
|
| 242 |
outputs=[image_output,figure_pre_output,figure_post_output])
|
model_list.txt
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
yolov8n.pt
|
| 2 |
+
yolov8s.pt
|
| 3 |
+
yolov8m.pt
|
| 4 |
+
yolov8l.pt
|
| 5 |
+
yolov8x.pt
|