Zengyf-CVer commited on
Commit
0931150
1 Parent(s): 788db9a

init update

Browse files
.gitignore ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # 图片格式
2
+ *.jpg
3
+ *.jpeg
4
+ *.png
5
+ *.svg
6
+ *.gif
7
+
8
+ # 视频格式
9
+ *.mp4
10
+ *.avi
11
+ .ipynb_checkpoints
12
+ */__pycache__
13
+
14
+ # 日志格式
15
+ *.log
16
+ *.data
17
+ *.txt
18
+ *.csv
19
+
20
+ # 参数文件
21
+ *.yaml
22
+ *.json
23
+
24
+ # 压缩文件格式
25
+ *.zip
26
+ *.tar
27
+ *.tar.gz
28
+ *.rar
29
+
30
+ # 字体格式
31
+ *.ttc
32
+ *.ttf
33
+ *.otf
34
+
35
+ *.pt
36
+ *.db
37
+
38
+ /flagged
39
+ /run
40
+ !requirements.txt
41
+ !cls_name/*
42
+ !model_config/*
43
+ !img_example/*
44
+
45
+ app copy.py
README.md CHANGED
@@ -11,3 +11,5 @@ license: gpl-3.0
11
  ---
12
 
13
  Check out the configuration reference at https://huggingface.co/docs/hub/spaces#reference
 
 
 
11
  ---
12
 
13
  Check out the configuration reference at https://huggingface.co/docs/hub/spaces#reference
14
+
15
+ 🚀 项目主页:https://gitee.com/CV_Lab/gradio_yolov5_det
__init__.py ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ __author__ = "曾逸夫(Zeng Yifu)"
2
+ __email__ = "zyfiy1314@163.com"
app.py ADDED
@@ -0,0 +1,387 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Gradio YOLOv5 Det v0.2
2
+ # 创建人:曾逸夫
3
+ # 创建时间:2022-05-01
4
+ # email:zyfiy1314@163.com
5
+ # 项目主页:https://gitee.com/CV_Lab/gradio_yolov5_det
6
+
7
+ import argparse
8
+ import csv
9
+ import json
10
+ import sys
11
+ from pathlib import Path
12
+
13
+ import gradio as gr
14
+ import torch
15
+ import yaml
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
+ model_path = "ultralytics/yolov5"
25
+
26
+ # 模型名称临时变量
27
+ model_name_tmp = ""
28
+
29
+ # 设备临时变量
30
+ device_tmp = ""
31
+
32
+ # 文件后缀
33
+ suffix_list = [".csv", ".yaml"]
34
+
35
+ # 字体大小
36
+ FONTSIZE = 25
37
+
38
+
39
+ def parse_args(known=False):
40
+ parser = argparse.ArgumentParser(description="Gradio YOLOv5 Det v0.2")
41
+ parser.add_argument(
42
+ "--model_name", "-mn", default="yolov5s", type=str, help="model name"
43
+ )
44
+ parser.add_argument(
45
+ "--model_cfg",
46
+ "-mc",
47
+ default="./model_config/model_name_p5_all.yaml",
48
+ type=str,
49
+ help="model config",
50
+ )
51
+ parser.add_argument(
52
+ "--cls_name",
53
+ "-cls",
54
+ default="./cls_name/cls_name.yaml",
55
+ type=str,
56
+ help="cls name",
57
+ )
58
+ parser.add_argument(
59
+ "--nms_conf",
60
+ "-conf",
61
+ default=0.5,
62
+ type=float,
63
+ help="model NMS confidence threshold",
64
+ )
65
+ parser.add_argument(
66
+ "--nms_iou", "-iou", default=0.45, type=float, help="model NMS IoU threshold"
67
+ )
68
+
69
+ parser.add_argument(
70
+ "--label_dnt_show",
71
+ "-lds",
72
+ action="store_true",
73
+ default=False,
74
+ help="label show",
75
+ )
76
+ parser.add_argument(
77
+ "--device", "-dev", default="cpu", type=str, help="cuda or cpu",
78
+ )
79
+ parser.add_argument(
80
+ "--inference_size", "-isz", default=640, type=int, help="model inference size"
81
+ )
82
+
83
+ args = parser.parse_known_args()[0] if known else parser.parse_args()
84
+ return args
85
+
86
+
87
+ # yaml文件解析
88
+ def yaml_parse(file_path):
89
+ return yaml.safe_load(open(file_path, encoding="utf-8").read())
90
+
91
+
92
+ # yaml csv 文件解析
93
+ def yaml_csv(file_path, file_tag):
94
+ file_suffix = Path(file_path).suffix
95
+ if file_suffix == suffix_list[0]:
96
+ # 模型名称
97
+ file_names = [i[0] for i in list(csv.reader(open(file_path)))] # csv版
98
+ elif file_suffix == suffix_list[1]:
99
+ # 模型名称
100
+ file_names = yaml_parse(file_path).get(file_tag) # yaml版
101
+ else:
102
+ print(f"{file_path}格式不正确!程序退出!")
103
+ sys.exit()
104
+
105
+ return file_names
106
+
107
+
108
+ # 模型加载
109
+ def model_loading(model_name, device):
110
+
111
+ # 加载模型
112
+ model = torch.hub.load(
113
+ model_path, model_name, force_reload=True, device=device, _verbose=False
114
+ )
115
+
116
+ return model
117
+
118
+
119
+ # 检测信息
120
+ def export_json(results, model, img_size):
121
+
122
+ return [
123
+ [
124
+ {
125
+ "id": i,
126
+ "class": int(result[i][5]),
127
+ # "class_name": model.model.names[int(result[i][5])],
128
+ "class_name": model_cls_name_cp[int(result[i][5])],
129
+ "normalized_box": {
130
+ "x0": round(result[i][:4].tolist()[0], 6),
131
+ "y0": round(result[i][:4].tolist()[1], 6),
132
+ "x1": round(result[i][:4].tolist()[2], 6),
133
+ "y1": round(result[i][:4].tolist()[3], 6),
134
+ },
135
+ "confidence": round(float(result[i][4]), 2),
136
+ "fps": round(1000 / float(results.t[1]), 2),
137
+ "width": img_size[0],
138
+ "height": img_size[1],
139
+ }
140
+ for i in range(len(result))
141
+ ]
142
+ for result in results.xyxyn
143
+ ]
144
+
145
+
146
+ # 帧转换
147
+ def pil_draw(img, countdown_msg, textFont, xyxy, font_size, label_opt):
148
+
149
+ img_pil = ImageDraw.Draw(img)
150
+
151
+ img_pil.rectangle(xyxy, fill=None, outline="green") # 边界框
152
+
153
+ if label_opt:
154
+ text_w, text_h = textFont.getsize(countdown_msg) # 标签尺寸
155
+ img_pil.rectangle(
156
+ (xyxy[0], xyxy[1], xyxy[0] + text_w, xyxy[1] + text_h),
157
+ fill="green",
158
+ outline="green",
159
+ ) # 标签背景
160
+ img_pil.multiline_text(
161
+ (xyxy[0], xyxy[1]),
162
+ countdown_msg,
163
+ fill=(205, 250, 255),
164
+ font=textFont,
165
+ align="center",
166
+ )
167
+
168
+ return img
169
+
170
+
171
+ # YOLOv5图片检测函数
172
+ def yolo_det(
173
+ img, device, model_name, inference_size, conf, iou, label_opt, model_cls, opt
174
+ ):
175
+
176
+ global model, model_name_tmp, device_tmp
177
+
178
+ if model_name_tmp != model_name:
179
+ # 模型判断,避免反复加载
180
+ model_name_tmp = model_name
181
+ model = model_loading(model_name_tmp, device)
182
+ elif device_tmp != device:
183
+ device_tmp = device
184
+ model = model_loading(model_name_tmp, device)
185
+
186
+ # -----------模型调参-----------
187
+ model.conf = conf # NMS 置信度阈值
188
+ model.iou = iou # NMS IOU阈值
189
+ model.max_det = 1000 # 最大检测框数
190
+ model.classes = model_cls # 模型类别
191
+
192
+ results = model(img, size=inference_size) # 检测
193
+
194
+ img_size = img.size # 帧尺寸
195
+
196
+ # 加载字体
197
+ textFont = ImageFont.truetype(str(f"{ROOT_PATH}/fonts/SimSun.ttf"), size=FONTSIZE)
198
+
199
+ det_img = img.copy()
200
+
201
+ for result in results.xyxyn:
202
+ for i in range(len(result)):
203
+ id = int(i) # 实例ID
204
+ obj_cls_index = int(result[i][5]) # 类别索引
205
+ obj_cls = model_cls_name_cp[obj_cls_index] # 类别
206
+
207
+ # ------------边框坐标------------
208
+ x0 = float(result[i][:4].tolist()[0])
209
+ y0 = float(result[i][:4].tolist()[1])
210
+ x1 = float(result[i][:4].tolist()[2])
211
+ y1 = float(result[i][:4].tolist()[3])
212
+
213
+ # ------------边框实际坐标------------
214
+ x0 = int(img_size[0] * x0)
215
+ y0 = int(img_size[1] * y0)
216
+ x1 = int(img_size[0] * x1)
217
+ y1 = int(img_size[1] * y1)
218
+
219
+ conf = float(result[i][4]) # 置信度
220
+ # fps = f"{(1000 / float(results.t[1])):.2f}" # FPS
221
+
222
+ det_img = pil_draw(
223
+ img,
224
+ f"{id}-{obj_cls}:{conf:.2f}",
225
+ textFont,
226
+ [x0, y0, x1, y1],
227
+ FONTSIZE,
228
+ label_opt,
229
+ )
230
+
231
+ det_json = export_json(results, model, img.size)[0] # 检测信息
232
+
233
+ # JSON格式化
234
+ det_json_format = json.dumps(
235
+ det_json, sort_keys=True, indent=4, separators=(",", ":"), ensure_ascii=False
236
+ )
237
+
238
+ # -------pdf-------
239
+ report = "./Det_Report.pdf"
240
+ if "pdf" in opt:
241
+ pdf_generate(f"{det_json_format}", report)
242
+ else:
243
+ report = None
244
+
245
+ if "json" not in opt:
246
+ det_json = None
247
+
248
+ return det_img, det_json, report
249
+
250
+
251
+ def main(args):
252
+ gr.close_all()
253
+
254
+ global model, model_cls_name_cp
255
+
256
+ slider_step = 0.05 # 滑动步长
257
+
258
+ nms_conf = args.nms_conf
259
+ nms_iou = args.nms_iou
260
+ label_opt = args.label_dnt_show
261
+ model_name = args.model_name
262
+ model_cfg = args.model_cfg
263
+ cls_name = args.cls_name
264
+ device = args.device
265
+ inference_size = args.inference_size
266
+
267
+ is_fonts(f"{ROOT_PATH}/fonts") # 检查字体文件
268
+
269
+ # 模型加载
270
+ model = model_loading(model_name, device)
271
+
272
+ model_names = yaml_csv(model_cfg, "model_names")
273
+ model_cls_name = yaml_csv(cls_name, "model_cls_name")
274
+
275
+ model_cls_name_cp = model_cls_name.copy() # 类别名称
276
+
277
+ # -------------------输入组件-------------------
278
+ inputs_img = gr.inputs.Image(type="pil", label="原始图片")
279
+ inputs_device = gr.inputs.Dropdown(
280
+ choices=["0", "cpu"], default=device, type="value", label="设备"
281
+ )
282
+ inputs_model = gr.inputs.Dropdown(
283
+ choices=model_names, default=model_name, type="value", label="模型"
284
+ )
285
+ inputs_size = gr.inputs.Radio(
286
+ choices=[320, 640], default=inference_size, label="推理尺寸"
287
+ )
288
+ input_conf = gr.inputs.Slider(
289
+ 0, 1, step=slider_step, default=nms_conf, label="置信度阈值"
290
+ )
291
+ inputs_iou = gr.inputs.Slider(
292
+ 0, 1, step=slider_step, default=nms_iou, label="IoU 阈值"
293
+ )
294
+ inputs_label = gr.inputs.Checkbox(default=(not label_opt), label="标签显示")
295
+ inputs_clsName = gr.inputs.CheckboxGroup(
296
+ choices=model_cls_name, default=model_cls_name, type="index", label="类别"
297
+ )
298
+ inputs_opt = gr.inputs.CheckboxGroup(
299
+ choices=["pdf", "json"], default=["pdf"], type="value", label="操作"
300
+ )
301
+
302
+ # 输入参数
303
+ inputs = [
304
+ inputs_img, # 输入图片
305
+ inputs_device, # 设备
306
+ inputs_model, # 模型
307
+ inputs_size, # 推理尺寸
308
+ input_conf, # 置信度阈值
309
+ inputs_iou, # IoU阈值
310
+ inputs_label, # 标签显示
311
+ inputs_clsName, # 类别
312
+ inputs_opt, # 检测操作
313
+ ]
314
+
315
+ # 输出参数
316
+ outputs_img = gr.outputs.Image(type="pil", label="检测图片")
317
+ outputs02_json = gr.outputs.JSON(label="检测信息")
318
+ outputs03_pdf = gr.outputs.File(label="下载检测报告")
319
+
320
+ outputs = [outputs_img, outputs02_json, outputs03_pdf]
321
+
322
+ # 标题
323
+ title = "基于Gradio的YOLOv5通用目标检测系统v0.2"
324
+ # 描述
325
+ description = "<div align='center'>可自定义目标检测模型、安装简单、使用方便</div><div align='center'>Customizable object detection model, easy to install and easy to use</div>"
326
+
327
+ # 示例图片
328
+ examples = [
329
+ [
330
+ "./img_example/bus.jpg",
331
+ "cpu",
332
+ "yolov5s",
333
+ 640,
334
+ 0.6,
335
+ 0.5,
336
+ True,
337
+ ["人", "公交车"],
338
+ ["pdf"],
339
+ ],
340
+ [
341
+ "./img_example/Millenial-at-work.jpg",
342
+ "cpu",
343
+ "yolov5l",
344
+ 320,
345
+ 0.5,
346
+ 0.45,
347
+ True,
348
+ ["人", "椅子", "杯子", "笔记本电脑"],
349
+ ["json"],
350
+ ],
351
+ [
352
+ "./img_example/zidane.jpg",
353
+ "cpu",
354
+ "yolov5m",
355
+ 640,
356
+ 0.25,
357
+ 0.5,
358
+ False,
359
+ ["人", "领带"],
360
+ ["pdf", "json"],
361
+ ],
362
+ ]
363
+
364
+ # 接口
365
+ gr.Interface(
366
+ fn=yolo_det,
367
+ inputs=inputs,
368
+ outputs=outputs,
369
+ title=title,
370
+ description=description,
371
+ examples=examples,
372
+ theme="seafoam",
373
+ # live=True, # 实时变更输出
374
+ flagging_dir="run", # 输出目录
375
+ # flagging_options=["good", "generally", "bad"],
376
+ # allow_flagging="auto",
377
+ # ).launch(inbrowser=True, auth=['admin', 'admin'])
378
+ ).launch(
379
+ inbrowser=True, # 自动打开默认浏览器
380
+ show_tips=True, # 自动显示gradio最新功能
381
+ # favicon_path="./icon/logo.ico",
382
+ )
383
+
384
+
385
+ if __name__ == "__main__":
386
+ args = parse_args()
387
+ main(args)
cls_name/cls_name.csv ADDED
@@ -0,0 +1,80 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ 自行车
3
+ 汽车
4
+ 摩托车
5
+ 飞机
6
+ 公交车
7
+ 火车
8
+ 卡车
9
+
10
+ 红绿灯
11
+ 消防栓
12
+ 停止标志
13
+ 停车收费表
14
+ 长凳
15
+
16
+
17
+
18
+
19
+
20
+
21
+
22
+
23
+ 斑马
24
+ 长颈鹿
25
+ 背包
26
+ 雨伞
27
+ 手提包
28
+ 领带
29
+ 手提箱
30
+ 飞盘
31
+ 滑雪板
32
+ 单板滑雪
33
+ 运动球
34
+ 风筝
35
+ 棒球棒
36
+ 棒球手套
37
+ 滑板
38
+ 冲浪板
39
+ 网球拍
40
+ 瓶子
41
+ 红酒杯
42
+ 杯子
43
+ 叉子
44
+
45
+
46
+
47
+ 香蕉
48
+ 苹果
49
+ 三明治
50
+ 橙子
51
+ 西兰花
52
+ 胡萝卜
53
+ 热狗
54
+ 比萨
55
+ 甜甜圈
56
+ 蛋糕
57
+ 椅子
58
+ 长椅
59
+ 盆栽
60
+
61
+ 餐桌
62
+ 马桶
63
+ 电视
64
+ 笔记本电脑
65
+ 鼠标
66
+ 遥控器
67
+ 键盘
68
+ 手机
69
+ 微波炉
70
+ 烤箱
71
+ 烤面包机
72
+ 洗碗槽
73
+ 冰箱
74
+
75
+ 时钟
76
+ 花瓶
77
+ 剪刀
78
+ 泰迪熊
79
+ 吹风机
80
+ 牙刷
cls_name/cls_name.yaml ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ model_cls_name: ['人', '自行车', '汽车', '摩托车', '飞机', '公交车', '火车', '卡车', '船', '红绿灯', '消防栓', '停止标志',
2
+ '停车收费表', '长凳', '鸟', '猫', '狗', '马', '羊', '牛', '象', '熊', '斑马', '长颈鹿', '背包', '雨伞', '手提包', '领带',
3
+ '手提箱', '飞盘', '滑雪板', '单板滑雪', '运动球', '风筝', '棒球棒', '棒球手套', '滑板', '冲浪板', '网球拍', '瓶子', '红酒杯',
4
+ '杯子', '叉子', '刀', '勺', '碗', '香蕉', '苹果', '三明治', '橙子', '西兰花', '胡萝卜', '热狗', '比萨', '甜甜圈', '蛋糕',
5
+ '椅子', '长椅', '盆栽', '床', '餐桌', '马桶', '电视', '笔记本电脑', '鼠标', '遥控器', '键盘', '手机', '微波炉', '烤箱',
6
+ '烤面包机', '洗碗槽', '冰箱', '书', '时钟', '花瓶', '剪刀', '泰迪熊', '吹风机', '牙刷'
7
+ ]
icon/logo.ico ADDED
img_example/Millenial-at-work.jpg ADDED
img_example/bus.jpg ADDED
img_example/zidane.jpg ADDED
model_config/model_name_p5_all.csv ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ yolov5n
2
+ yolov5s
3
+ yolov5m
4
+ yolov5l
5
+ yolov5x
model_config/model_name_p5_all.yaml ADDED
@@ -0,0 +1 @@
 
 
1
+ model_names: ["yolov5n", "yolov5s", "yolov5m", "yolov5l", "yolov5x"]
model_config/model_name_p5_n.csv ADDED
@@ -0,0 +1 @@
 
 
1
+ yolov5n
model_config/model_name_p5_n.yaml ADDED
@@ -0,0 +1 @@
 
 
1
+ model_names: ["yolov5n"]
model_config/model_name_p6_all.csv ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ yolov5n6
2
+ yolov5s6
3
+ yolov5m6
4
+ yolov5l6
5
+ yolov5x6
model_config/model_name_p6_all.yaml ADDED
@@ -0,0 +1 @@
 
 
1
+ model_names: ["yolov5n6", "yolov5s6", "yolov5m6", "yolov5l6", "yolov5x6"]
model_download/yolov5_model_p5_all.sh ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ cd ./yolov5
2
+
3
+ # 下载YOLOv5模型
4
+ wget -c -t 0 https://github.com/ultralytics/yolov5/releases/download/v6.1/yolov5n.pt
5
+ wget -c -t 0 https://github.com/ultralytics/yolov5/releases/download/v6.1/yolov5s.pt
6
+ wget -c -t 0 https://github.com/ultralytics/yolov5/releases/download/v6.1/yolov5m.pt
7
+ wget -c -t 0 https://github.com/ultralytics/yolov5/releases/download/v6.1/yolov5l.pt
8
+ wget -c -t 0 https://github.com/ultralytics/yolov5/releases/download/v6.1/yolov5x.pt
model_download/yolov5_model_p5_n.sh ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ cd ./yolov5
2
+
3
+ # 下载YOLOv5模型
4
+ wget -c -t 0 https://github.com/ultralytics/yolov5/releases/download/v6.1/yolov5n.pt
model_download/yolov5_model_p6_all.sh ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ cd ./yolov5
2
+
3
+ # 下载YOLOv5模型
4
+ wget -c -t 0 https://github.com/ultralytics/yolov5/releases/download/v6.1/yolov5n6.pt
5
+ wget -c -t 0 https://github.com/ultralytics/yolov5/releases/download/v6.1/yolov5s6.pt
6
+ wget -c -t 0 https://github.com/ultralytics/yolov5/releases/download/v6.1/yolov5m6.pt
7
+ wget -c -t 0 https://github.com/ultralytics/yolov5/releases/download/v6.1/yolov5l6.pt
8
+ wget -c -t 0 https://github.com/ultralytics/yolov5/releases/download/v6.1/yolov5x6.pt
requirements.txt ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Base ----------------------------------------
2
+ matplotlib>=3.2.2
3
+ numpy>=1.18.5
4
+ opencv-python-headless>=4.5.5.64
5
+ Pillow>=7.1.2
6
+ PyYAML>=5.3.1
7
+ requests>=2.23.0
8
+ scipy>=1.4.1
9
+ torch>=1.7.0
10
+ torchvision>=0.8.1
11
+ gradio==2.9b40
12
+ tqdm>=4.41.0
13
+ wget>=3.2
14
+ rich>=12.2.0
15
+ fpdf>=1.7.2
16
+
17
+ # Logging -------------------------------------
18
+ tensorboard>=2.4.1
19
+ # wandb
20
+
21
+ # Plotting ------------------------------------
22
+ pandas>=1.1.4
23
+ seaborn>=0.11.0
24
+
25
+ # Export --------------------------------------
26
+ # coremltools>=4.1 # CoreML export
27
+ # onnx>=1.9.0 # ONNX export
28
+ # onnx-simplifier>=0.3.6 # ONNX simplifier
29
+ # scikit-learn==0.19.2 # CoreML quantization
30
+ # tensorflow>=2.4.1 # TFLite export
31
+ # tensorflowjs>=3.9.0 # TF.js export
32
+ # openvino-dev # OpenVINO export
33
+
34
+ # Extras --------------------------------------
35
+ # albumentations>=1.0.3
36
+ # Cython # for pycocotools https://github.com/cocodataset/cocoapi/issues/172
37
+ # pycocotools>=2.0 # COCO mAP
38
+ # roboflow
39
+ thop # FLOPs computation
util/fonts_opt.py ADDED
@@ -0,0 +1,67 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # 字体管理
2
+ # 创建人:曾逸夫
3
+ # 创建时间:2022-05-01
4
+
5
+ import os
6
+ import sys
7
+ from pathlib import Path
8
+
9
+ import wget
10
+ from rich.console import Console
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/1053539/download/SimSun.ttf"
19
+ }
20
+
21
+ console = Console()
22
+
23
+
24
+ # 创建字体库
25
+ def add_fronts(font_diff):
26
+
27
+ global font_name
28
+
29
+ for k, v in data_url_dict.items():
30
+ if k in font_diff:
31
+ font_name = v.split("/")[-1] # 字体名称
32
+ Path(f"{ROOT_PATH}/fonts").mkdir(parents=True, exist_ok=True) # 创建目录
33
+
34
+ file_path = f"{ROOT_PATH}/fonts/{font_name}" # 字体路径
35
+
36
+ try:
37
+ # 下载字体文件
38
+ wget.download(v, file_path)
39
+ except Exception as e:
40
+ print("路径错误!程序结束!")
41
+ print(e)
42
+ sys.exit()
43
+ else:
44
+ print()
45
+ console.print(
46
+ f"{font_name} [bold green]字体文件下载完成![/bold green] 已保存至:{file_path}"
47
+ )
48
+
49
+
50
+ # 判断字体文件
51
+ def is_fonts(fonts_dir):
52
+ if os.path.isdir(fonts_dir):
53
+ # 如果字体库存在
54
+ f_list = os.listdir(fonts_dir) # 本地字体库
55
+
56
+ font_diff = list(set(fonts_list).difference(set(f_list)))
57
+
58
+ if font_diff != []:
59
+ # 字体不存在
60
+ console.print("[bold red]字体不存在,正在加载。。。[/bold red]")
61
+ add_fronts(font_diff) # 创建字体库
62
+ else:
63
+ console.print(f"{fonts_list}[bold green]字体已存在![/bold green]")
64
+ else:
65
+ # 字体库不存在,创建字体库
66
+ console.print("[bold red]字体库不存在,正在创建。。。[/bold red]")
67
+ add_fronts(fonts_list) # 创建字体库
util/pdf_opt.py ADDED
@@ -0,0 +1,77 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # PDF管理
2
+ # 创建人:曾逸夫
3
+ # 创建时间:2022-05-05
4
+
5
+ from fpdf import FPDF
6
+
7
+
8
+ title = "Gradio YOLOv5 Det v0.2"
9
+
10
+
11
+ class PDF(FPDF):
12
+ # 参考:https://pyfpdf.readthedocs.io/en/latest/Tutorial/index.html
13
+ def header(self):
14
+ # 设置中文字体
15
+ self.add_font("SimSun", "", "./fonts/SimSun.ttf", uni=True)
16
+ self.set_font("SimSun", "", 16)
17
+ # Calculate width of title and position
18
+ w = self.get_string_width(title) + 6
19
+ self.set_x((210 - w) / 2)
20
+ # Colors of frame, background and text
21
+ self.set_draw_color(255, 255, 255)
22
+ self.set_fill_color(255, 255, 255)
23
+ self.set_text_color(0, 0, 0)
24
+ # Thickness of frame (1 mm)
25
+ # self.set_line_width(1)
26
+ # Title
27
+ self.cell(w, 9, title, 1, 1, "C", 1)
28
+ # Line break
29
+ self.ln(10)
30
+
31
+ def footer(self):
32
+ # Position at 1.5 cm from bottom
33
+ self.set_y(-15)
34
+ # 设置中文字体
35
+ self.add_font("SimSun", "", "./fonts/SimSun.ttf", uni=True)
36
+ self.set_font("SimSun", "", 12)
37
+ # Text color in gray
38
+ self.set_text_color(128)
39
+ # Page number
40
+ self.cell(0, 10, "Page " + str(self.page_no()), 0, 0, "C")
41
+
42
+ def chapter_title(self, num, label):
43
+ # 设置中文字体
44
+ self.add_font("SimSun", "", "./fonts/SimSun.ttf", uni=True)
45
+ self.set_font("SimSun", "", 12)
46
+ # Background color
47
+ self.set_fill_color(200, 220, 255)
48
+ # Title
49
+ # self.cell(0, 6, 'Chapter %d : %s' % (num, label), 0, 1, 'L', 1)
50
+ self.cell(0, 6, f"检测结果:", 0, 1, "L", 1)
51
+ # Line break
52
+ self.ln(4)
53
+
54
+ def chapter_body(self, name):
55
+
56
+ # 设置中文字体
57
+ self.add_font("SimSun", "", "./fonts/SimSun.ttf", uni=True)
58
+ self.set_font("SimSun", "", 12)
59
+ # Output justified text
60
+ self.multi_cell(0, 5, name)
61
+ # Line break
62
+ self.ln()
63
+ self.cell(0, 5, "--------------------------------------")
64
+
65
+ def print_chapter(self, num, title, name):
66
+ self.add_page()
67
+ self.chapter_title(num, title)
68
+ self.chapter_body(name)
69
+
70
+
71
+ # pdf生成函数
72
+ def pdf_generate(input_file, output_file):
73
+ pdf = PDF()
74
+ pdf.set_title(title)
75
+ pdf.set_author("Zeng Yifu")
76
+ pdf.print_chapter(1, "A RUNAWAY REEF", input_file)
77
+ pdf.output(output_file)