Spaces:
Runtime error
Runtime error
Zengyf-CVer
commited on
Commit
•
4c39af6
1
Parent(s):
6c056e2
v02 update
Browse files- app.py +82 -31
- util/fonts_opt.py +7 -4
- util/pdf_opt.py +74 -0
app.py
CHANGED
@@ -6,6 +6,7 @@
|
|
6 |
|
7 |
import argparse
|
8 |
import csv
|
|
|
9 |
import sys
|
10 |
from pathlib import Path
|
11 |
|
@@ -15,11 +16,12 @@ import yaml
|
|
15 |
from PIL import Image, ImageDraw, ImageFont
|
16 |
|
17 |
from util.fonts_opt import is_fonts
|
|
|
18 |
|
19 |
ROOT_PATH = sys.path[0] # 根目录
|
20 |
|
21 |
-
#
|
22 |
-
|
23 |
|
24 |
# 模型名称临时变量
|
25 |
model_name_tmp = ""
|
@@ -72,7 +74,11 @@ def parse_args(known=False):
|
|
72 |
help="label show",
|
73 |
)
|
74 |
parser.add_argument(
|
75 |
-
"--device",
|
|
|
|
|
|
|
|
|
76 |
)
|
77 |
parser.add_argument(
|
78 |
"--inference_size", "-isz", default=640, type=int, help="model inference size"
|
@@ -82,12 +88,38 @@ def parse_args(known=False):
|
|
82 |
return args
|
83 |
|
84 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
85 |
# 模型加载
|
86 |
def model_loading(model_name, device):
|
87 |
|
88 |
# 加载本地模型
|
89 |
model = torch.hub.load(
|
90 |
-
|
|
|
|
|
|
|
|
|
|
|
91 |
)
|
92 |
|
93 |
return model
|
@@ -146,7 +178,9 @@ def pil_draw(img, countdown_msg, textFont, xyxy, font_size, label_opt):
|
|
146 |
|
147 |
|
148 |
# YOLOv5图片检测函数
|
149 |
-
def yolo_det(
|
|
|
|
|
150 |
|
151 |
global model, model_name_tmp, device_tmp
|
152 |
|
@@ -169,7 +203,7 @@ def yolo_det(img, device, model_name, inference_size, conf, iou, label_opt, mode
|
|
169 |
img_size = img.size # 帧尺寸
|
170 |
|
171 |
# 加载字体
|
172 |
-
textFont = ImageFont.truetype(str(f"{ROOT_PATH}/fonts/SimSun.
|
173 |
|
174 |
det_img = img.copy()
|
175 |
|
@@ -205,28 +239,22 @@ def yolo_det(img, device, model_name, inference_size, conf, iou, label_opt, mode
|
|
205 |
|
206 |
det_json = export_json(results, model, img.size)[0] # 检测信息
|
207 |
|
208 |
-
|
209 |
-
|
210 |
-
|
211 |
-
|
212 |
-
def yaml_parse(file_path):
|
213 |
-
return yaml.safe_load(open(file_path, encoding="utf-8").read())
|
214 |
-
|
215 |
|
216 |
-
#
|
217 |
-
|
218 |
-
|
219 |
-
|
220 |
-
# 模型名称
|
221 |
-
file_names = [i[0] for i in list(csv.reader(open(file_path)))] # csv版
|
222 |
-
elif file_suffix == suffix_list[1]:
|
223 |
-
# 模型名称
|
224 |
-
file_names = yaml_parse(file_path).get(file_tag) # yaml版
|
225 |
else:
|
226 |
-
|
227 |
-
sys.exit()
|
228 |
|
229 |
-
|
|
|
|
|
|
|
230 |
|
231 |
|
232 |
def main(args):
|
@@ -276,6 +304,9 @@ def main(args):
|
|
276 |
inputs_clsName = gr.inputs.CheckboxGroup(
|
277 |
choices=model_cls_name, default=model_cls_name, type="index", label="类别"
|
278 |
)
|
|
|
|
|
|
|
279 |
|
280 |
# 输入参数
|
281 |
inputs = [
|
@@ -287,19 +318,35 @@ def main(args):
|
|
287 |
inputs_iou, # IoU阈值
|
288 |
inputs_label, # 标签显示
|
289 |
inputs_clsName, # 类别
|
|
|
290 |
]
|
|
|
291 |
# 输出参数
|
292 |
-
|
293 |
-
|
|
|
|
|
|
|
294 |
|
295 |
# 标题
|
296 |
-
title = "基于Gradio的YOLOv5通用目标检测系统
|
297 |
# 描述
|
298 |
description = "<div align='center'>可自定义目标检测模型、���装简单、使用方便</div><div align='center'>Customizable target detection model, easy to install and easy to use</div>"
|
299 |
|
|
|
300 |
# 示例图片
|
301 |
examples = [
|
302 |
-
[
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
303 |
[
|
304 |
"./img_example/Millenial-at-work.jpg",
|
305 |
"cpu",
|
@@ -309,6 +356,7 @@ def main(args):
|
|
309 |
0.45,
|
310 |
True,
|
311 |
["人", "椅子", "杯子", "笔记本电脑"],
|
|
|
312 |
],
|
313 |
[
|
314 |
"./img_example/zidane.jpg",
|
@@ -319,6 +367,7 @@ def main(args):
|
|
319 |
0.5,
|
320 |
False,
|
321 |
["人", "领带"],
|
|
|
322 |
],
|
323 |
]
|
324 |
|
@@ -326,13 +375,15 @@ def main(args):
|
|
326 |
gr.Interface(
|
327 |
fn=yolo_det,
|
328 |
inputs=inputs,
|
329 |
-
outputs=
|
330 |
title=title,
|
331 |
description=description,
|
332 |
examples=examples,
|
333 |
theme="seafoam",
|
334 |
# live=True, # 实时变更输出
|
335 |
-
flagging_dir="run" # 输出目录
|
|
|
|
|
336 |
# ).launch(inbrowser=True, auth=['admin', 'admin'])
|
337 |
).launch(
|
338 |
inbrowser=True, # 自动打开默认浏览器
|
|
|
6 |
|
7 |
import argparse
|
8 |
import csv
|
9 |
+
import json
|
10 |
import sys
|
11 |
from pathlib import Path
|
12 |
|
|
|
16 |
from PIL import Image, ImageDraw, ImageFont
|
17 |
|
18 |
from util.fonts_opt import is_fonts
|
19 |
+
from util.pdf_opt import pdf_generate
|
20 |
|
21 |
ROOT_PATH = sys.path[0] # 根目录
|
22 |
|
23 |
+
# 本地模型路径
|
24 |
+
local_model_path = f"{ROOT_PATH}/yolov5"
|
25 |
|
26 |
# 模型名称临时变量
|
27 |
model_name_tmp = ""
|
|
|
74 |
help="label show",
|
75 |
)
|
76 |
parser.add_argument(
|
77 |
+
"--device",
|
78 |
+
"-dev",
|
79 |
+
default="cpu",
|
80 |
+
type=str,
|
81 |
+
help="cuda or cpu",
|
82 |
)
|
83 |
parser.add_argument(
|
84 |
"--inference_size", "-isz", default=640, type=int, help="model inference size"
|
|
|
88 |
return args
|
89 |
|
90 |
|
91 |
+
# yaml文件解析
|
92 |
+
def yaml_parse(file_path):
|
93 |
+
return yaml.safe_load(open(file_path, encoding="utf-8").read())
|
94 |
+
|
95 |
+
|
96 |
+
# yaml csv 文件解析
|
97 |
+
def yaml_csv(file_path, file_tag):
|
98 |
+
file_suffix = Path(file_path).suffix
|
99 |
+
if file_suffix == suffix_list[0]:
|
100 |
+
# 模型名称
|
101 |
+
file_names = [i[0] for i in list(csv.reader(open(file_path)))] # csv版
|
102 |
+
elif file_suffix == suffix_list[1]:
|
103 |
+
# 模型名称
|
104 |
+
file_names = yaml_parse(file_path).get(file_tag) # yaml版
|
105 |
+
else:
|
106 |
+
print(f"{file_path}格式不正确!程序退出!")
|
107 |
+
sys.exit()
|
108 |
+
|
109 |
+
return file_names
|
110 |
+
|
111 |
+
|
112 |
# 模型加载
|
113 |
def model_loading(model_name, device):
|
114 |
|
115 |
# 加载本地模型
|
116 |
model = torch.hub.load(
|
117 |
+
local_model_path,
|
118 |
+
"custom",
|
119 |
+
path=f"{local_model_path}/{model_name}",
|
120 |
+
source="local",
|
121 |
+
device=device,
|
122 |
+
_verbose=False,
|
123 |
)
|
124 |
|
125 |
return model
|
|
|
178 |
|
179 |
|
180 |
# YOLOv5图片检测函数
|
181 |
+
def yolo_det(
|
182 |
+
img, device, model_name, inference_size, conf, iou, label_opt, model_cls, opt
|
183 |
+
):
|
184 |
|
185 |
global model, model_name_tmp, device_tmp
|
186 |
|
|
|
203 |
img_size = img.size # 帧尺寸
|
204 |
|
205 |
# 加载字体
|
206 |
+
textFont = ImageFont.truetype(str(f"{ROOT_PATH}/fonts/SimSun.ttf"), size=FONTSIZE)
|
207 |
|
208 |
det_img = img.copy()
|
209 |
|
|
|
239 |
|
240 |
det_json = export_json(results, model, img.size)[0] # 检测信息
|
241 |
|
242 |
+
# JSON格式化
|
243 |
+
det_json_format = json.dumps(
|
244 |
+
det_json, sort_keys=True, indent=4, separators=(",", ":"), ensure_ascii=False
|
245 |
+
)
|
|
|
|
|
|
|
246 |
|
247 |
+
# -------pdf-------
|
248 |
+
report = "./Det_Report.pdf"
|
249 |
+
if "pdf" in opt:
|
250 |
+
pdf_generate(f"{det_json_format}", report)
|
|
|
|
|
|
|
|
|
|
|
251 |
else:
|
252 |
+
report = None
|
|
|
253 |
|
254 |
+
if "json" not in opt:
|
255 |
+
det_json = None
|
256 |
+
|
257 |
+
return det_img, det_json, report
|
258 |
|
259 |
|
260 |
def main(args):
|
|
|
304 |
inputs_clsName = gr.inputs.CheckboxGroup(
|
305 |
choices=model_cls_name, default=model_cls_name, type="index", label="类别"
|
306 |
)
|
307 |
+
inputs_opt = gr.inputs.CheckboxGroup(
|
308 |
+
choices=["pdf", "json"], default=["pdf"], type="value", label="操作"
|
309 |
+
)
|
310 |
|
311 |
# 输入参数
|
312 |
inputs = [
|
|
|
318 |
inputs_iou, # IoU阈值
|
319 |
inputs_label, # 标签显示
|
320 |
inputs_clsName, # 类别
|
321 |
+
inputs_opt, # 检测操作
|
322 |
]
|
323 |
+
|
324 |
# 输出参数
|
325 |
+
outputs_img = gr.outputs.Image(type="pil", label="检测图片")
|
326 |
+
outputs02_json = gr.outputs.JSON(label="检测信息")
|
327 |
+
outputs03_pdf = gr.outputs.File(label="下载检测报告")
|
328 |
+
|
329 |
+
outputs = [outputs_img, outputs02_json, outputs03_pdf]
|
330 |
|
331 |
# 标题
|
332 |
+
title = "基于Gradio的YOLOv5通用目标检测系统v0.2"
|
333 |
# 描述
|
334 |
description = "<div align='center'>可自定义目标检测模型、���装简单、使用方便</div><div align='center'>Customizable target detection model, easy to install and easy to use</div>"
|
335 |
|
336 |
+
|
337 |
# 示例图片
|
338 |
examples = [
|
339 |
+
[
|
340 |
+
"./img_example/bus.jpg",
|
341 |
+
"cpu",
|
342 |
+
"yolov5s",
|
343 |
+
640,
|
344 |
+
0.6,
|
345 |
+
0.5,
|
346 |
+
True,
|
347 |
+
["人", "公交车"],
|
348 |
+
["pdf"],
|
349 |
+
],
|
350 |
[
|
351 |
"./img_example/Millenial-at-work.jpg",
|
352 |
"cpu",
|
|
|
356 |
0.45,
|
357 |
True,
|
358 |
["人", "椅子", "杯子", "笔记本电脑"],
|
359 |
+
["json"],
|
360 |
],
|
361 |
[
|
362 |
"./img_example/zidane.jpg",
|
|
|
367 |
0.5,
|
368 |
False,
|
369 |
["人", "领带"],
|
370 |
+
["pdf", "json"],
|
371 |
],
|
372 |
]
|
373 |
|
|
|
375 |
gr.Interface(
|
376 |
fn=yolo_det,
|
377 |
inputs=inputs,
|
378 |
+
outputs=outputs,
|
379 |
title=title,
|
380 |
description=description,
|
381 |
examples=examples,
|
382 |
theme="seafoam",
|
383 |
# live=True, # 实时变更输出
|
384 |
+
flagging_dir="run", # 输出目录
|
385 |
+
# flagging_options=["good", "generally", "bad"],
|
386 |
+
allow_flagging="auto",
|
387 |
# ).launch(inbrowser=True, auth=['admin', 'admin'])
|
388 |
).launch(
|
389 |
inbrowser=True, # 自动打开默认浏览器
|
util/fonts_opt.py
CHANGED
@@ -11,10 +11,12 @@ from rich.console import Console
|
|
11 |
|
12 |
ROOT_PATH = sys.path[0] # 项目根目录
|
13 |
|
14 |
-
fonts_list = ["SimSun.
|
15 |
fonts_suffix = ["ttc", "ttf", "otf"] # 字体后缀
|
16 |
|
17 |
-
data_url_dict = {
|
|
|
|
|
18 |
|
19 |
console = Console()
|
20 |
|
@@ -40,7 +42,9 @@ def add_fronts(font_diff):
|
|
40 |
sys.exit()
|
41 |
else:
|
42 |
print()
|
43 |
-
console.print(
|
|
|
|
|
44 |
|
45 |
|
46 |
# 判断字体文件
|
@@ -61,4 +65,3 @@ def is_fonts(fonts_dir):
|
|
61 |
# 字体库不存在,创建字体库
|
62 |
console.print("[bold red]字体库不存在,正在创建。。。[/bold red]")
|
63 |
add_fronts(fonts_list) # 创建字体库
|
64 |
-
|
|
|
11 |
|
12 |
ROOT_PATH = sys.path[0] # 项目根目录
|
13 |
|
14 |
+
fonts_list = ["SimSun.ttf"] # 字体列表
|
15 |
fonts_suffix = ["ttc", "ttf", "otf"] # 字体后缀
|
16 |
|
17 |
+
data_url_dict = {
|
18 |
+
"SimSun.ttf": "https://gitee.com/CV_Lab/gradio_yolov5_det/attach_files/1049109/download/SimSun.ttf"
|
19 |
+
}
|
20 |
|
21 |
console = Console()
|
22 |
|
|
|
42 |
sys.exit()
|
43 |
else:
|
44 |
print()
|
45 |
+
console.print(
|
46 |
+
f"{font_name} [bold green]字体文件下载完成![/bold green] 已保存至:{file_path}"
|
47 |
+
)
|
48 |
|
49 |
|
50 |
# 判断字体文件
|
|
|
65 |
# 字体库不存在,创建字体库
|
66 |
console.print("[bold red]字体库不存在,正在创建。。。[/bold red]")
|
67 |
add_fronts(fonts_list) # 创建字体库
|
|
util/pdf_opt.py
ADDED
@@ -0,0 +1,74 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# 参考:https://pyfpdf.readthedocs.io/en/latest/Tutorial/index.html
|
2 |
+
|
3 |
+
from fpdf import FPDF
|
4 |
+
|
5 |
+
# title = 'Gradio YOLOv5 Det v0.2检测报告'
|
6 |
+
title = "Gradio YOLOv5 Det v0.2"
|
7 |
+
|
8 |
+
|
9 |
+
class PDF(FPDF):
|
10 |
+
def header(self):
|
11 |
+
# 设置中文字体
|
12 |
+
self.add_font("SimSun", "", "./fonts/SimSun.ttf", uni=True)
|
13 |
+
self.set_font("SimSun", "", 16)
|
14 |
+
# Calculate width of title and position
|
15 |
+
w = self.get_string_width(title) + 6
|
16 |
+
self.set_x((210 - w) / 2)
|
17 |
+
# Colors of frame, background and text
|
18 |
+
self.set_draw_color(255, 255, 255)
|
19 |
+
self.set_fill_color(255, 255, 255)
|
20 |
+
self.set_text_color(0, 0, 0)
|
21 |
+
# Thickness of frame (1 mm)
|
22 |
+
# self.set_line_width(1)
|
23 |
+
# Title
|
24 |
+
self.cell(w, 9, title, 1, 1, "C", 1)
|
25 |
+
# Line break
|
26 |
+
self.ln(10)
|
27 |
+
|
28 |
+
def footer(self):
|
29 |
+
# Position at 1.5 cm from bottom
|
30 |
+
self.set_y(-15)
|
31 |
+
# 设置中文字体
|
32 |
+
self.add_font("SimSun", "", "./fonts/SimSun.ttf", uni=True)
|
33 |
+
self.set_font("SimSun", "", 12)
|
34 |
+
# Text color in gray
|
35 |
+
self.set_text_color(128)
|
36 |
+
# Page number
|
37 |
+
self.cell(0, 10, "Page " + str(self.page_no()), 0, 0, "C")
|
38 |
+
|
39 |
+
def chapter_title(self, num, label):
|
40 |
+
# 设置中文字体
|
41 |
+
self.add_font("SimSun", "", "./fonts/SimSun.ttf", uni=True)
|
42 |
+
self.set_font("SimSun", "", 12)
|
43 |
+
# Background color
|
44 |
+
self.set_fill_color(200, 220, 255)
|
45 |
+
# Title
|
46 |
+
# self.cell(0, 6, 'Chapter %d : %s' % (num, label), 0, 1, 'L', 1)
|
47 |
+
self.cell(0, 6, f"检测结果:", 0, 1, "L", 1)
|
48 |
+
# Line break
|
49 |
+
self.ln(4)
|
50 |
+
|
51 |
+
def chapter_body(self, name):
|
52 |
+
|
53 |
+
# 设置中文字体
|
54 |
+
self.add_font("SimSun", "", "./fonts/SimSun.ttf", uni=True)
|
55 |
+
self.set_font("SimSun", "", 12)
|
56 |
+
# Output justified text
|
57 |
+
self.multi_cell(0, 5, name)
|
58 |
+
# Line break
|
59 |
+
self.ln()
|
60 |
+
self.cell(0, 5, "--------------------------------------")
|
61 |
+
|
62 |
+
def print_chapter(self, num, title, name):
|
63 |
+
self.add_page()
|
64 |
+
self.chapter_title(num, title)
|
65 |
+
self.chapter_body(name)
|
66 |
+
|
67 |
+
|
68 |
+
# pdf生成函数
|
69 |
+
def pdf_generate(input_file, output_file):
|
70 |
+
pdf = PDF()
|
71 |
+
pdf.set_title(title)
|
72 |
+
pdf.set_author("Zeng Yifu")
|
73 |
+
pdf.print_chapter(1, "A RUNAWAY REEF", input_file)
|
74 |
+
pdf.output(output_file)
|