Zengyf-CVer commited on
Commit
4c39af6
1 Parent(s): 6c056e2

v02 update

Browse files
Files changed (3) hide show
  1. app.py +82 -31
  2. util/fonts_opt.py +7 -4
  3. 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
- model_path = "ultralytics/yolov5"
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", "-dev", default="cpu", type=str, help="cuda or cpu",
 
 
 
 
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
- model_path, model_name, force_reload=True, device=device, _verbose=False
 
 
 
 
 
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(img, device, model_name, inference_size, conf, iou, label_opt, model_cls):
 
 
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.ttc"), size=FONTSIZE)
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
- return det_img, det_json
209
-
210
-
211
- # yaml文件解析
212
- def yaml_parse(file_path):
213
- return yaml.safe_load(open(file_path, encoding="utf-8").read())
214
-
215
 
216
- # yaml csv 文件解析
217
- def yaml_csv(file_path, file_tag):
218
- file_suffix = Path(file_path).suffix
219
- if file_suffix == suffix_list[0]:
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
- print(f"{file_path}格式不正确!程序退出!")
227
- sys.exit()
228
 
229
- return file_names
 
 
 
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
- outputs = gr.outputs.Image(type="pil", label="检测图片")
293
- outputs02 = gr.outputs.JSON(label="检测信息")
 
 
 
294
 
295
  # 标题
296
- title = "基于Gradio的YOLOv5通用目标检测系统v2"
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
- ["./img_example/bus.jpg", "cpu", "yolov5s", 640, 0.6, 0.5, True, ["人", "公交车"],],
 
 
 
 
 
 
 
 
 
 
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=[outputs, outputs02],
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.ttc"] # 字体列表
15
  fonts_suffix = ["ttc", "ttf", "otf"] # 字体后缀
16
 
17
- data_url_dict = {"SimSun.ttc": "https://gitee.com/CV_Lab/opencv_webcam/attach_files/959173/download/SimSun.ttc"}
 
 
18
 
19
  console = Console()
20
 
@@ -40,7 +42,9 @@ def add_fronts(font_diff):
40
  sys.exit()
41
  else:
42
  print()
43
- console.print(f"{font_name} [bold green]字体文件下载完成![/bold green] 已保存至:{file_path}")
 
 
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)