Zengyf-CVer commited on
Commit
28ce5bd
1 Parent(s): 1c15062

v01 update

Browse files
.gitignore ADDED
@@ -0,0 +1,51 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ *.datas
17
+ *.txt
18
+
19
+ # 生成文件
20
+ *.pdf
21
+ *.xlsx
22
+ *.csv
23
+
24
+ # 参数文件
25
+ *.yaml
26
+ *.json
27
+
28
+ # 压缩文件格式
29
+ *.zip
30
+ *.tar
31
+ *.tar.gz
32
+ *.rar
33
+
34
+ # 字体格式
35
+ *.ttc
36
+ *.ttf
37
+ *.otf
38
+
39
+ # 模型文件
40
+ *.pt
41
+ *.db
42
+
43
+ /flagged
44
+ /run
45
+ !requirements.txt
46
+ !cls_name/*
47
+ !model_config/*
48
+ !img_examples/*
49
+ !packages.txt
50
+
51
+ app copy.py
README.md CHANGED
@@ -1,12 +1,12 @@
1
  ---
2
  title: Gradio YOLOv8 Det
3
  emoji: 🚀
4
- colorFrom: green
5
- colorTo: green
6
  sdk: gradio
7
  sdk_version: 3.16.1
8
  app_file: app.py
9
- pinned: false
10
  license: gpl-3.0
11
  ---
12
 
 
1
  ---
2
  title: Gradio YOLOv8 Det
3
  emoji: 🚀
4
+ colorFrom: red
5
+ colorTo: red
6
  sdk: gradio
7
  sdk_version: 3.16.1
8
  app_file: app.py
9
+ pinned: true
10
  license: gpl-3.0
11
  ---
12
 
__init__.py ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ __author__ = "曾逸夫(Zeng Yifu)"
2
+ __email__ = "[email protected]"
app.py ADDED
@@ -0,0 +1,441 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Gradio YOLOv8 Det v0.1
2
+ # 创建人:曾逸夫
3
+ # 创建时间:2023-01-13
4
+
5
+ import os
6
+
7
+ import argparse
8
+ import csv
9
+ import sys
10
+
11
+ from ultralytics import YOLO
12
+ import gc
13
+ import json
14
+ import random
15
+ import shutil
16
+ from collections import Counter
17
+ from pathlib import Path
18
+
19
+ import cv2
20
+ import gradio as gr
21
+ import matplotlib.pyplot as plt
22
+ import numpy as np
23
+ import pandas as pd
24
+ import plotly.express as px
25
+ from matplotlib import font_manager
26
+
27
+ ROOT_PATH = sys.path[0] # 项目根目录
28
+
29
+ # --------------------- 字体库 ---------------------
30
+ SimSun_path = f"{ROOT_PATH}/fonts/SimSun.ttf" # 宋体文件路径
31
+ TimesNesRoman_path = f"{ROOT_PATH}/fonts/TimesNewRoman.ttf" # 新罗马字体文件路径
32
+ # 宋体
33
+ SimSun = font_manager.FontProperties(fname=SimSun_path, size=12)
34
+ # 新罗马字体
35
+ TimesNesRoman = font_manager.FontProperties(fname=TimesNesRoman_path, size=12)
36
+
37
+ import yaml
38
+ from PIL import Image, ImageDraw, ImageFont
39
+
40
+ from util.fonts_opt import is_fonts
41
+ from util.pdf_opt import pdf_generate
42
+
43
+ ROOT_PATH = sys.path[0] # 根目录
44
+
45
+ # 本地模型路径
46
+ local_model_path = f"{ROOT_PATH}/models"
47
+ local_model_path_02 = f"{ROOT_PATH}/yolov5"
48
+
49
+ # Gradio YOLOv8 Det版本
50
+ GYD_VERSION = "Gradio YOLOv8 Det v0.1"
51
+
52
+ # 文件后缀
53
+ suffix_list = [".csv", ".yaml"]
54
+
55
+ # 字体大小
56
+ FONTSIZE = 25
57
+
58
+ # 目标尺寸
59
+ obj_style = ["小目标", "中目标", "大目标"]
60
+
61
+
62
+ def parse_args(known=False):
63
+ parser = argparse.ArgumentParser(description="Gradio YOLOv8 Det v0.1")
64
+ parser.add_argument("--model_type", "-mt", default="online", type=str, help="model type")
65
+ parser.add_argument("--source", "-src", default="upload", type=str, help="image input source")
66
+ parser.add_argument("--source_video", "-src_v", default="upload", type=str, help="video input source")
67
+ parser.add_argument("--img_tool", "-it", default="editor", type=str, help="input image tool")
68
+ parser.add_argument("--model_name", "-mn", default="yolov8s", type=str, help="model name")
69
+ parser.add_argument(
70
+ "--model_cfg",
71
+ "-mc",
72
+ default="./model_config/model_name_p5_all.yaml",
73
+ type=str,
74
+ help="model config",
75
+ )
76
+ parser.add_argument(
77
+ "--cls_name",
78
+ "-cls",
79
+ default="./cls_name/cls_name_zh.yaml",
80
+ type=str,
81
+ help="cls name",
82
+ )
83
+ parser.add_argument(
84
+ "--nms_conf",
85
+ "-conf",
86
+ default=0.5,
87
+ type=float,
88
+ help="model NMS confidence threshold",
89
+ )
90
+ parser.add_argument("--nms_iou", "-iou", default=0.45, type=float, help="model NMS IoU threshold")
91
+ parser.add_argument(
92
+ "--device",
93
+ "-dev",
94
+ default="cuda:0",
95
+ type=str,
96
+ help="cuda or cpu",
97
+ )
98
+ parser.add_argument("--inference_size", "-isz", default=640, type=int, help="model inference size")
99
+ parser.add_argument("--max_detnum", "-mdn", default=50, type=float, help="model max det num")
100
+ parser.add_argument("--slider_step", "-ss", default=0.05, type=float, help="slider step")
101
+ parser.add_argument(
102
+ "--is_login",
103
+ "-isl",
104
+ action="store_true",
105
+ default=False,
106
+ help="is login",
107
+ )
108
+ parser.add_argument('--usr_pwd',
109
+ "-up",
110
+ nargs='+',
111
+ type=str,
112
+ default=["admin", "admin"],
113
+ help="user & password for login")
114
+ parser.add_argument(
115
+ "--is_share",
116
+ "-is",
117
+ action="store_true",
118
+ default=False,
119
+ help="is login",
120
+ )
121
+ parser.add_argument("--server_port", "-sp", default=7861, type=int, help="server port")
122
+
123
+ args = parser.parse_known_args()[0] if known else parser.parse_args()
124
+ return args
125
+
126
+
127
+ # yaml文件解析
128
+ def yaml_parse(file_path):
129
+ return yaml.safe_load(open(file_path, encoding="utf-8").read())
130
+
131
+
132
+ # yaml csv 文件解析
133
+ def yaml_csv(file_path, file_tag):
134
+ file_suffix = Path(file_path).suffix
135
+ if file_suffix == suffix_list[0]:
136
+ # 模型名称
137
+ file_names = [i[0] for i in list(csv.reader(open(file_path)))] # csv版
138
+ elif file_suffix == suffix_list[1]:
139
+ # 模型名称
140
+ file_names = yaml_parse(file_path).get(file_tag) # yaml版
141
+ else:
142
+ print(f"{file_path}格式不正确!程序退出!")
143
+ sys.exit()
144
+
145
+ return file_names
146
+
147
+
148
+ # 检查网络连接
149
+ def check_online():
150
+ # 参考:https://github.com/ultralytics/yolov5/blob/master/utils/general.py
151
+ # Check internet connectivity
152
+ import socket
153
+ try:
154
+ socket.create_connection(("1.1.1.1", 443), 5) # check host accessibility
155
+ return True
156
+ except OSError:
157
+ return False
158
+
159
+
160
+ # 模型加载
161
+ def model_loading(img_path, conf, iou, infer_size, yolo_model="yolov8n.pt"):
162
+ model = YOLO(yolo_model)
163
+
164
+ results = model(img_path, imgsz=infer_size, conf=conf, iou=iou)
165
+ return results[0].tolist()
166
+
167
+
168
+ # 检测信息
169
+ def export_json(results, img_size):
170
+
171
+ return [[{
172
+ "ID": i,
173
+ "CLASS": int(result[i][5]),
174
+ "CLASS_NAME": model_cls_name_cp[int(result[i][5])],
175
+ "BOUNDING_BOX": {
176
+ "XMIN": round(result[i][:4].tolist()[0], 6),
177
+ "YMIN": round(result[i][:4].tolist()[1], 6),
178
+ "XMAX": round(result[i][:4].tolist()[2], 6),
179
+ "YMAX": round(result[i][:4].tolist()[3], 6),},
180
+ "CONF": round(float(result[i][4]), 2),
181
+ "FPS": round(1000 / float(results.t[1]), 2),
182
+ "IMG_WIDTH": img_size[0],
183
+ "IMG_HEIGHT": img_size[1],} for i in range(len(result))] for result in results.xyxyn]
184
+
185
+
186
+ # 标签和边界框颜色设置
187
+ def color_set(cls_num):
188
+ color_list = []
189
+ for i in range(cls_num):
190
+ color = tuple(np.random.choice(range(256), size=3))
191
+ # color = ["#"+''.join([random.choice('0123456789ABCDEF') for j in range(6)])]
192
+ color_list.append(color)
193
+
194
+ return color_list
195
+
196
+
197
+ # 随机生成浅色系或者深色系
198
+ def random_color(cls_num, is_light=True):
199
+ color_list = []
200
+ for i in range(cls_num):
201
+ color = (
202
+ random.randint(0, 127) + int(is_light) * 128,
203
+ random.randint(0, 127) + int(is_light) * 128,
204
+ random.randint(0, 127) + int(is_light) * 128,
205
+ )
206
+ color_list.append(color)
207
+
208
+ return color_list
209
+
210
+
211
+ # 检测绘制
212
+ def pil_draw(img_path, score_l, bbox_l, cls_l, cls_index_l, textFont, color_list):
213
+ img = Image.open(img_path)
214
+ img_pil = ImageDraw.Draw(img)
215
+ id = 0
216
+
217
+ for score, (xmin, ymin, xmax, ymax), label, cls_index in zip(score_l, bbox_l, cls_l, cls_index_l):
218
+
219
+ img_pil.rectangle([xmin, ymin, xmax, ymax], fill=None, outline=color_list[cls_index], width=2) # 边界框
220
+ countdown_msg = f"{id}-{label} {score:.2f}"
221
+ text_w, text_h = textFont.getsize(countdown_msg) # 标签尺寸
222
+
223
+ # 标签背景
224
+ img_pil.rectangle(
225
+ (xmin, ymin, xmin + text_w, ymin + text_h),
226
+ fill=color_list[cls_index],
227
+ outline=color_list[cls_index],
228
+ )
229
+
230
+ # 标签
231
+ img_pil.multiline_text(
232
+ (xmin, ymin),
233
+ countdown_msg,
234
+ fill=(0, 0, 0),
235
+ font=textFont,
236
+ align="center",
237
+ )
238
+
239
+ id += 1
240
+
241
+ return img
242
+
243
+
244
+ # YOLOv5图片检测函数
245
+ def yolo_det_img(img_path, model_name, infer_size, conf, iou):
246
+
247
+ global model, model_name_tmp, device_tmp
248
+
249
+ s_obj, m_obj, l_obj = 0, 0, 0
250
+
251
+ area_obj_all = [] # 目标面积
252
+
253
+ score_det_stat = [] # 置信度统计
254
+ bbox_det_stat = [] # 边界框统计
255
+ cls_det_stat = [] # 类别数量统计
256
+ cls_index_det_stat = [] # 类别索引统计
257
+
258
+ # 模型加载
259
+ predict_list = model_loading(img_path, conf, iou, infer_size, yolo_model=f"{model_name}.pt")
260
+
261
+ color_list = random_color(len(model_cls_name_cp), True)
262
+
263
+ # 判断检测对象是否为空
264
+ if (predict_list != []):
265
+
266
+ # ---------------- 加载字体 ----------------
267
+ yaml_index = cls_name.index(".yaml")
268
+ cls_name_lang = cls_name[yaml_index - 2:yaml_index]
269
+
270
+ if cls_name_lang == "zh":
271
+ # 中文
272
+ textFont = ImageFont.truetype(str(f"{ROOT_PATH}/fonts/SimSun.ttf"), size=FONTSIZE)
273
+ elif cls_name_lang in ["en", "ru", "es", "ar"]:
274
+ # 英文、俄语、西班牙语、阿拉伯语
275
+ textFont = ImageFont.truetype(str(f"{ROOT_PATH}/fonts/TimesNewRoman.ttf"), size=FONTSIZE)
276
+ elif cls_name_lang == "ko":
277
+ # 韩语
278
+ textFont = ImageFont.truetype(str(f"{ROOT_PATH}/fonts/malgun.ttf"), size=FONTSIZE)
279
+
280
+ for i in range(len(predict_list)):
281
+ # id = int(i) # 实例ID
282
+ obj_cls_index = int(predict_list[i][5]) # 类别索引
283
+ cls_index_det_stat.append(obj_cls_index)
284
+
285
+ obj_cls = model_cls_name_cp[obj_cls_index] # 类别
286
+ cls_det_stat.append(obj_cls)
287
+
288
+ # ------------ 边框坐标 ------------
289
+ x0 = int(predict_list[i][0])
290
+ y0 = int(predict_list[i][1])
291
+ x1 = int(predict_list[i][2])
292
+ y1 = int(predict_list[i][3])
293
+
294
+ bbox_det_stat.append((x0, y0, x1, y1))
295
+
296
+ conf = float(predict_list[i][4]) # 置信度
297
+ score_det_stat.append(conf)
298
+
299
+ # fps = f"{(1000 / float(results.t[1])):.2f}" # FPS
300
+
301
+ # ---------- 加入目标尺寸 ----------
302
+ w_obj = x1 - x0
303
+ h_obj = y1 - y0
304
+ area_obj = w_obj * h_obj
305
+ area_obj_all.append(area_obj)
306
+
307
+ det_img = pil_draw(img_path, score_det_stat, bbox_det_stat, cls_det_stat, cls_index_det_stat, textFont,
308
+ color_list)
309
+
310
+ # -------------- 目标尺寸计算 --------------
311
+ for i in range(len(area_obj_all)):
312
+ if (0 < area_obj_all[i] <= 32 ** 2):
313
+ s_obj = s_obj + 1
314
+ elif (32 ** 2 < area_obj_all[i] <= 96 ** 2):
315
+ m_obj = m_obj + 1
316
+ elif (area_obj_all[i] > 96 ** 2):
317
+ l_obj = l_obj + 1
318
+
319
+ sml_obj_total = s_obj + m_obj + l_obj
320
+ objSize_dict = {}
321
+ objSize_dict = {obj_style[i]: [s_obj, m_obj, l_obj][i] / sml_obj_total for i in range(3)}
322
+
323
+ # ------------ 类别统计 ------------
324
+ clsRatio_dict = {}
325
+ clsDet_dict = Counter(cls_det_stat)
326
+ clsDet_dict_sum = sum(clsDet_dict.values())
327
+ for k, v in clsDet_dict.items():
328
+ clsRatio_dict[k] = v / clsDet_dict_sum
329
+
330
+ return det_img, objSize_dict, clsRatio_dict
331
+ else:
332
+ print("图片目标不存在!")
333
+ return None, None, None
334
+
335
+
336
+ def main(args):
337
+ gr.close_all()
338
+
339
+ global model_cls_name_cp, cls_name
340
+
341
+ source = args.source
342
+ img_tool = args.img_tool
343
+ nms_conf = args.nms_conf
344
+ nms_iou = args.nms_iou
345
+ model_name = args.model_name
346
+ model_cfg = args.model_cfg
347
+ cls_name = args.cls_name
348
+ inference_size = args.inference_size
349
+ slider_step = args.slider_step
350
+ is_share = args.is_share
351
+
352
+ is_fonts(f"{ROOT_PATH}/fonts") # 检查字体文件
353
+
354
+ model_names = yaml_csv(model_cfg, "model_names") # 模型名称
355
+ model_cls_name = yaml_csv(cls_name, "model_cls_name") # 类别名称
356
+
357
+ model_cls_name_cp = model_cls_name.copy() # 类别名称
358
+
359
+ # ------------------- 图片模式输入组件 -------------------
360
+ inputs_img = gr.Image(image_mode="RGB", source=source, tool=img_tool, type="filepath", label="原始图片")
361
+ inputs_model01 = gr.Dropdown(choices=model_names, value=model_name, type="value", label="模型")
362
+ inputs_size01 = gr.Slider(384, 1536, step=128, value=inference_size, label="推理尺寸")
363
+ input_conf01 = gr.Slider(0, 1, step=slider_step, value=nms_conf, label="置信度阈值")
364
+ inputs_iou01 = gr.Slider(0, 1, step=slider_step, value=nms_iou, label="IoU 阈值")
365
+
366
+ # ------------------- 图片模式输入参数 -------------------
367
+ inputs_img_list = [
368
+ inputs_img, # 输入图片
369
+ inputs_model01, # 模型
370
+ inputs_size01, # 推理尺寸
371
+ input_conf01, # 置信度阈值
372
+ inputs_iou01, # IoU阈值
373
+ ]
374
+
375
+ # ------------------- 图片模式输出组件 -------------------
376
+ outputs_img = gr.Image(type="pil", label="检测图片")
377
+ outputs_objSize = gr.Label(label="目标尺寸占比统计")
378
+ outputs_clsSize = gr.Label(label="类别检测占比统计")
379
+
380
+ # ------------------- 图片模式输出参数 -------------------
381
+ outputs_img_list = [outputs_img, outputs_objSize, outputs_clsSize]
382
+
383
+ # 标题
384
+ title = "Gradio YOLOv8 Det"
385
+
386
+ # 描述
387
+ description = "<div align='center'>可自定义目标检测模型、安装简单、使用方便</div>"
388
+
389
+ # 示例图片
390
+ examples_imgs = [
391
+ [
392
+ "./img_examples/bus.jpg",
393
+ "yolov8s",
394
+ 640,
395
+ 0.6,
396
+ 0.5,],
397
+ [
398
+ "./img_examples/giraffe.jpg",
399
+ "yolov8l",
400
+ 320,
401
+ 0.5,
402
+ 0.45,],
403
+ [
404
+ "./img_examples/zidane.jpg",
405
+ "yolov8m",
406
+ 640,
407
+ 0.6,
408
+ 0.5,],
409
+ [
410
+ "./img_examples/Millenial-at-work.jpg",
411
+ "yolov8x",
412
+ 1280,
413
+ 0.5,
414
+ 0.5,],]
415
+
416
+ # 接口
417
+ gyd_img = gr.Interface(
418
+ fn=yolo_det_img,
419
+ inputs=inputs_img_list,
420
+ outputs=outputs_img_list,
421
+ title=title,
422
+ description=description,
423
+ examples=examples_imgs,
424
+ flagging_dir="run", # 输出目录
425
+ allow_flagging="manual",
426
+ flagging_options=["good", "generally", "bad"],
427
+ )
428
+
429
+ gyd_img.launch(
430
+ inbrowser=True, # 自动打开默认浏览器
431
+ show_tips=True, # 自动显示gradio最新功能
432
+ share=is_share, # 项目共享,其他设备可以访问
433
+ favicon_path="./icon/logo.ico", # 网页图标
434
+ show_error=True, # 在浏览器控制台中显示错误信息
435
+ quiet=True, # 禁止大多数打印语句
436
+ )
437
+
438
+
439
+ if __name__ == "__main__":
440
+ args = parse_args()
441
+ 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
+ ]
cls_name/cls_name_ar.yaml ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ model_cls_name: [" الناس " , " الدراجات " , " السيارات " , " الدراجات النارية " , " الطائرات " , " الحافلات " , " القطارات " , " الشاحنات " , " السفن " , " إشارات المرور " ,
2
+ " صنبور " , " علامة " , " موقف سيارات " , " الجدول " , " مقعد " , " الطيور " , " القط " , " الكلب " , " الحصان " , " الأغنام " , " الثور " , " الفيل " ,
3
+ " الدب " , " حمار وحشي " , " الزرافة " , " حقيبة " , " مظلة " , " حقيبة يد " , " ربطة عنق " , " حقيبة " , " الفريسبي " , " الزلاجات " , " الزلاجات " ,
4
+ " الكرة الرياضية " , " طائرة ورقية " , " مضرب بيسبول " , " قفازات البيسبول " , " لوح التزلج " , " ركوب الأمواج " , " مضرب تنس " , " زجاجة " ,
5
+ " كأس " , " كأس " , " شوكة " , " سكين " , " ملعقة " , " وعاء " , " الموز " , " التفاح " , " ساندويتش " , " البرتقال " , " القرنبيط " ,
6
+ " الجزر " , " الكلاب الساخنة " , " البيتزا " , " دونات " , " كعكة " , " كرسي " , " أريكة " , " بوعاء " , " السرير " , " طاولة الطعام " , " المرحاض " ,
7
+ التلفزيون , الكمبيوتر المحمول , الفأرة , وحدة تحكم عن بعد , لوحة المفاتيح , الهاتف المحمول , فرن الميكروويف , محمصة خبز كهربائية , بالوعة , ثلاجة ,
8
+ " كتاب " , " ساعة " , " زهرية " , " مقص " , " دمية دب " , " مجفف الشعر " , " فرشاة الأسنان "
9
+ ]
cls_name/cls_name_custom.yaml ADDED
@@ -0,0 +1 @@
 
 
1
+ model_cls_name: ['face']
cls_name/cls_name_en.yaml ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ model_cls_name: ['person', 'bicycle', 'car', 'motorcycle', 'airplane', 'bus', 'train', 'truck', 'boat', 'traffic light',
2
+ 'fire hydrant', 'stop sign', 'parking meter', 'bench', 'bird', 'cat', 'dog', 'horse', 'sheep', 'cow', 'elephant',
3
+ 'bear', 'zebra', 'giraffe', 'backpack', 'umbrella', 'handbag', 'tie', 'suitcase', 'frisbee', 'skis', 'snowboard',
4
+ 'sports ball', 'kite', 'baseball bat', 'baseball glove', 'skateboard', 'surfboard', 'tennis racket', 'bottle',
5
+ 'wine glass', 'cup', 'fork', 'knife', 'spoon', 'bowl', 'banana', 'apple', 'sandwich', 'orange', 'broccoli',
6
+ 'carrot', 'hot dog', 'pizza', 'donut', 'cake', 'chair', 'couch', 'potted plant', 'bed', 'dining table', 'toilet',
7
+ 'tv', 'laptop', 'mouse', 'remote', 'keyboard', 'cell phone', 'microwave', 'oven', 'toaster', 'sink', 'refrigerator',
8
+ 'book', 'clock', 'vase', 'scissors', 'teddy bear', 'hair drier', 'toothbrush'
9
+ ]
cls_name/cls_name_es.yaml ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ model_cls_name: ['persona', 'bicicleta', 'coche', 'motocicleta', 'avión', 'autobús', 'tren', 'camión', 'barco', 'semáforo',
2
+ 'boca de incendios', 'señal de alto', 'parquímetro', 'banco', 'pájaro', 'gato', 'perro', 'caballo', 'oveja', 'vaca', 'elefante',
3
+ 'oso', 'cebra', 'jirafa', 'mochila', 'paraguas', 'bolso', 'corbata', 'maleta', 'frisbee', 'esquís', 'snowboard',
4
+ 'pelota deportiva', 'cometa', 'bate de béisbol', 'guante de béisbol', 'monopatín', 'tabla de surf', 'raqueta de tenis', 'botella',
5
+ 'copa de vino', 'taza', 'tenedor', 'cuchillo', 'cuchara', 'tazón', 'plátano', 'manzana', 'sándwich', 'naranja', 'brócoli',
6
+ 'zanahoria', 'perrito caliente', 'pizza', 'rosquilla', 'pastel', 'silla', 'sofá', 'planta en maceta', 'cama', 'mesa de comedor', 'inodoro',
7
+ 'tv', 'laptop', 'ratón', 'control remoto', 'teclado', 'celular', 'microondas', 'horno', 'tostadora', 'fregadero', 'nevera',
8
+ 'libro', 'reloj', 'jarrón', 'tijeras', 'oso de peluche', 'secador de pelo', 'cepillo de dientes'
9
+ ]
cls_name/cls_name_ko.yaml ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ model_cls_name: ['사람', '자전거', '자동차', '오토바이', '비행기', '버스', '기차', '트럭', '보트', '신호등',
2
+ '소화전', '정지 신호', '주차 미터기', '벤치', '새', '고양이', '개', '말', '양', '소', '코끼리',
3
+ '곰', '얼룩말', '기린', '배낭', '우산', '핸드백', '타이', '여행가방', '프리스비', '스키', '스노우보드',
4
+ '스포츠 공', '연', '야구 방망이', '야구 글러브', '스케이트보드', '서프보드', '테니스 라켓', '병',
5
+ '와인잔', '컵', '포크', '나이프', '숟가락', '그릇', '바나나', '사과', '샌드위치', '오렌지', '브로콜리',
6
+ '당근', '핫도그', '피자', '도넛', '케이크', '의자', '소파', '화분', '침대', '식탁', '화장실',
7
+ 'tv', '노트북', '마우스', '리모컨', '키보드', '휴대전화', '전자레인지', '오븐', '토스터', '싱크대', '냉장고',
8
+ '책', '시계', '꽃병', '가위', '테디베어', '드라이기', '칫솔'
9
+ ]
cls_name/cls_name_ru.yaml ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ model_cls_name: ['человек', 'велосипед', 'автомобиль', 'мотоцикл', 'самолет', 'автобус', 'поезд', 'грузовик', 'лодка', 'светофор',
2
+ 'пожарный гидрант', 'стоп', 'паркомат', 'скамейка', 'птица', 'кошка', 'собака', 'лошадь', 'овца', 'корова', 'слон',
3
+ 'медведь', 'зебра', 'жираф', 'рюкзак', 'зонт', 'сумочка', 'галстук', 'чемодан', 'фрисби', 'лыжи', 'сноуборд',
4
+ 'спортивный мяч', 'воздушный змей', 'бейсбольная бита', 'бейсбольная перчатка', 'скейтборд', 'доска для серфинга', 'теннисная ракетка', 'бутылка',
5
+ 'бокал', 'чашка', 'вилка', 'нож', 'ложка', 'миска', 'банан', 'яблоко', 'бутерброд', 'апельсин', 'брокколи',
6
+ 'морковь', 'хот-дог', 'пицца', 'пончик', 'торт', 'стул', 'диван', 'растение в горшке', 'кровать', 'обеденный стол', 'туалет',
7
+ 'телевизор', 'ноутбук', 'мышь', 'пульт', 'клавиатура', 'мобильный телефон', 'микроволновая печь', 'духовка', 'тостер', 'раковина', 'холодильник',
8
+ 'книга', 'часы', 'ваза', 'ножницы', 'плюшевый мишка', 'фен', 'зубная щетка'
9
+ ]
cls_name/cls_name_zh.yaml ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ model_cls_name: ['人', '自行车', '汽车', '摩托车', '飞机', '公交车', '火车', '卡车', '船', '红绿灯', '消防栓', '停止标志',
2
+ '停车收费表', '长凳', '鸟', '猫', '狗', '马', '羊', '牛', '象', '熊', '斑马', '长颈鹿', '背包', '雨伞', '手提包', '领带',
3
+ '手提箱', '飞盘', '滑雪板', '单板滑雪', '运动球', '风筝', '棒球棒', '棒球手套', '滑板', '冲浪板', '网球拍', '瓶子', '红酒杯',
4
+ '杯子', '叉子', '刀', '勺', '碗', '香蕉', '苹果', '三明治', '橙子', '西兰花', '胡萝卜', '热狗', '比萨', '甜甜圈', '蛋糕',
5
+ '椅子', '长椅', '盆栽', '床', '餐桌', '马桶', '电视', '笔记本电脑', '鼠标', '遥控器', '键盘', '手机', '微波炉', '烤箱',
6
+ '烤面包机', '洗碗槽', '冰箱', '书', '时钟', '花瓶', '剪刀', '泰迪熊', '吹风机', '牙刷'
7
+ ]
img_examples/read.txt ADDED
File without changes
model_config/model_name_custom.yaml ADDED
@@ -0,0 +1 @@
 
 
1
+ model_names: ["widerface-m"]
model_config/model_name_p5_all.csv ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ yolov8n
2
+ yolov8s
3
+ yolov8m
4
+ yolov8l
5
+ yolov8x
model_config/model_name_p5_all.yaml ADDED
@@ -0,0 +1 @@
 
 
1
+ model_names: ["yolov8n", "yolov8s", "yolov8m", "yolov8l", "yolov8x"]
requirements.txt ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ultralytics
2
+ opencv-python
3
+ matplotlib
4
+ numpy
5
+ pandas
6
+ pyyaml
7
+ pillow
8
+ wget>=3.2
9
+ rich>=12.2.0
10
+ fpdf>=1.7.2
11
+ plotly>=5.7.0
12
+ bokeh>=2.4.2
13
+ openpyxl>=3.0.10
14
+
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
+ # 中文、英文、俄语、西班牙语、阿拉伯语、韩语
15
+ fonts_list = ["SimSun.ttf", "TimesNewRoman.ttf", "malgun.ttf"] # 字体列表
16
+ fonts_suffix = ["ttc", "ttf", "otf"] # 字体后缀
17
+
18
+ data_url_dict = {
19
+ "SimSun.ttf": "https://gitee.com/CV_Lab/gradio_yolov5_det/attach_files/1053539/download/SimSun.ttf",
20
+ "TimesNewRoman.ttf": "https://gitee.com/CV_Lab/gradio_yolov5_det/attach_files/1053537/download/TimesNewRoman.ttf",
21
+ "malgun.ttf": "https://gitee.com/CV_Lab/gradio_yolov5_det/attach_files/1053538/download/malgun.ttf",}
22
+
23
+ console = Console()
24
+
25
+
26
+ # 创建字体库
27
+ def add_fronts(font_diff):
28
+
29
+ global font_name
30
+
31
+ for k, v in data_url_dict.items():
32
+ if k in font_diff:
33
+ font_name = v.split("/")[-1] # 字体名称
34
+ Path(f"{ROOT_PATH}/fonts").mkdir(parents=True, exist_ok=True) # 创建目录
35
+
36
+ file_path = f"{ROOT_PATH}/fonts/{font_name}" # 字体路径
37
+
38
+ try:
39
+ # 下载字体文件
40
+ wget.download(v, file_path)
41
+ except Exception as e:
42
+ print("路径错误!程序结束!")
43
+ print(e)
44
+ sys.exit()
45
+ else:
46
+ print()
47
+ console.print(f"{font_name} [bold green]字体文件下载完成![/bold green] 已保存至:{file_path}")
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,84 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # PDF管理
2
+ # 创建人:曾逸夫
3
+ # 创建时间:2022-05-05
4
+
5
+ from fpdf import FPDF
6
+
7
+
8
+ # PDF生成类
9
+ class PDF(FPDF):
10
+ # 参考:https://pyfpdf.readthedocs.io/en/latest/Tutorial/index.html
11
+ def header(self):
12
+ # 设置中文字体
13
+ self.add_font("SimSun", "", "./fonts/SimSun.ttf", uni=True)
14
+ self.set_font("SimSun", "", 16)
15
+ # Calculate width of title and position
16
+ w = self.get_string_width(title) + 6
17
+ self.set_x((210 - w) / 2)
18
+ # Colors of frame, background and text
19
+ self.set_draw_color(255, 255, 255)
20
+ self.set_fill_color(255, 255, 255)
21
+ self.set_text_color(0, 0, 0)
22
+ # Thickness of frame (1 mm)
23
+ # self.set_line_width(1)
24
+ # Title
25
+ self.cell(w, 9, title, 1, 1, "C", 1)
26
+ # Line break
27
+ self.ln(10)
28
+
29
+ def footer(self):
30
+ # Position at 1.5 cm from bottom
31
+ self.set_y(-15)
32
+ # 设置中文字体
33
+ self.add_font("SimSun", "", "./fonts/SimSun.ttf", uni=True)
34
+ self.set_font("SimSun", "", 12)
35
+ # Text color in gray
36
+ self.set_text_color(128)
37
+ # Page number
38
+ self.cell(0, 10, "Page " + str(self.page_no()), 0, 0, "C")
39
+
40
+ def chapter_title(self, num, label):
41
+ # 设置中文字体
42
+ self.add_font("SimSun", "", "./fonts/SimSun.ttf", uni=True)
43
+ self.set_font("SimSun", "", 12)
44
+ # Background color
45
+ self.set_fill_color(200, 220, 255)
46
+ # Title
47
+ # self.cell(0, 6, 'Chapter %d : %s' % (num, label), 0, 1, 'L', 1)
48
+ self.cell(0, 6, "检测结果:", 0, 1, "L", 1)
49
+ # Line break
50
+ self.ln(4)
51
+
52
+ def chapter_body(self, name):
53
+
54
+ # 设置中文字体
55
+ self.add_font("SimSun", "", "./fonts/SimSun.ttf", uni=True)
56
+ self.set_font("SimSun", "", 12)
57
+ # Output justified text
58
+ self.multi_cell(0, 5, name)
59
+ # Line break
60
+ self.ln()
61
+ self.cell(0, 5, "--------------------------------------")
62
+
63
+ def print_chapter(self, num, title, name):
64
+ self.add_page()
65
+ self.chapter_title(num, title)
66
+ self.chapter_body(name)
67
+
68
+ def print_img(self, name, x, y, width):
69
+ self.add_page()
70
+ self.image(name, x, y, width)
71
+
72
+
73
+ # pdf生成函数
74
+ def pdf_generate(input_file, origin_det_imgs, output_file, title_):
75
+ global title
76
+
77
+ title = title_
78
+ pdf = PDF()
79
+ pdf.set_title(title)
80
+ pdf.set_author("Zeng Yifu")
81
+ pdf.print_img(origin_det_imgs[0], 10, 30, 150)
82
+ pdf.print_img(origin_det_imgs[1], 10, 30, 150)
83
+ pdf.print_chapter(1, "A RUNAWAY REEF", input_file)
84
+ pdf.output(output_file)