oleg glenn-jocher commited on
Commit
19c8b2c
1 Parent(s): 0a52ae1

Adding --save-dir and --save-conf options to test.py (#1182)

Browse files

* Adding --output and --save-conf options to test.py

* Update help fields

* Update test.py

* Make arguments and comments uniform with test.py

* Remove previous and print save_dir on finish

Co-authored-by: Glenn Jocher <glenn.jocher@ultralytics.com>

Files changed (2) hide show
  1. detect.py +6 -6
  2. test.py +21 -9
detect.py CHANGED
@@ -19,15 +19,15 @@ from utils.torch_utils import select_device, load_classifier, time_synchronized
19
 
20
  def detect(save_img=False):
21
  out, source, weights, view_img, save_txt, imgsz = \
22
- opt.output, opt.source, opt.weights, opt.view_img, opt.save_txt, opt.img_size
23
  webcam = source.isnumeric() or source.startswith(('rtsp://', 'rtmp://', 'http://')) or source.endswith('.txt')
24
 
25
  # Initialize
26
  set_logging()
27
  device = select_device(opt.device)
28
- if os.path.exists(out):
29
- shutil.rmtree(out) # delete output folder
30
- os.makedirs(out) # make new output folder
31
  half = device.type != 'cpu' # half precision only supported on CUDA
32
 
33
  # Load model
@@ -148,14 +148,14 @@ if __name__ == '__main__':
148
  parser = argparse.ArgumentParser()
149
  parser.add_argument('--weights', nargs='+', type=str, default='yolov5s.pt', help='model.pt path(s)')
150
  parser.add_argument('--source', type=str, default='inference/images', help='source') # file/folder, 0 for webcam
151
- parser.add_argument('--output', type=str, default='inference/output', help='output folder') # output folder
152
  parser.add_argument('--img-size', type=int, default=640, help='inference size (pixels)')
153
  parser.add_argument('--conf-thres', type=float, default=0.25, help='object confidence threshold')
154
  parser.add_argument('--iou-thres', type=float, default=0.45, help='IOU threshold for NMS')
155
  parser.add_argument('--device', default='', help='cuda device, i.e. 0 or 0,1,2,3 or cpu')
156
  parser.add_argument('--view-img', action='store_true', help='display results')
157
  parser.add_argument('--save-txt', action='store_true', help='save results to *.txt')
158
- parser.add_argument('--save-conf', action='store_true', help='output confidences in --save-txt labels')
 
159
  parser.add_argument('--classes', nargs='+', type=int, help='filter by class: --class 0, or --class 0 2 3')
160
  parser.add_argument('--agnostic-nms', action='store_true', help='class-agnostic NMS')
161
  parser.add_argument('--augment', action='store_true', help='augmented inference')
 
19
 
20
  def detect(save_img=False):
21
  out, source, weights, view_img, save_txt, imgsz = \
22
+ opt.save_dir, opt.source, opt.weights, opt.view_img, opt.save_txt, opt.img_size
23
  webcam = source.isnumeric() or source.startswith(('rtsp://', 'rtmp://', 'http://')) or source.endswith('.txt')
24
 
25
  # Initialize
26
  set_logging()
27
  device = select_device(opt.device)
28
+ if os.path.exists(out): # output dir
29
+ shutil.rmtree(out) # delete dir
30
+ os.makedirs(out) # make new dir
31
  half = device.type != 'cpu' # half precision only supported on CUDA
32
 
33
  # Load model
 
148
  parser = argparse.ArgumentParser()
149
  parser.add_argument('--weights', nargs='+', type=str, default='yolov5s.pt', help='model.pt path(s)')
150
  parser.add_argument('--source', type=str, default='inference/images', help='source') # file/folder, 0 for webcam
 
151
  parser.add_argument('--img-size', type=int, default=640, help='inference size (pixels)')
152
  parser.add_argument('--conf-thres', type=float, default=0.25, help='object confidence threshold')
153
  parser.add_argument('--iou-thres', type=float, default=0.45, help='IOU threshold for NMS')
154
  parser.add_argument('--device', default='', help='cuda device, i.e. 0 or 0,1,2,3 or cpu')
155
  parser.add_argument('--view-img', action='store_true', help='display results')
156
  parser.add_argument('--save-txt', action='store_true', help='save results to *.txt')
157
+ parser.add_argument('--save-conf', action='store_true', help='save confidences in --save-txt labels')
158
+ parser.add_argument('--save-dir', type=str, default='inference/output', help='directory to save results')
159
  parser.add_argument('--classes', nargs='+', type=int, help='filter by class: --class 0, or --class 0 2 3')
160
  parser.add_argument('--agnostic-nms', action='store_true', help='class-agnostic NMS')
161
  parser.add_argument('--augment', action='store_true', help='augmented inference')
test.py CHANGED
@@ -32,6 +32,7 @@ def test(data,
32
  dataloader=None,
33
  save_dir=Path(''), # for saving images
34
  save_txt=False, # for auto-labelling
 
35
  plots=True):
36
  # Initialize/load model and set device
37
  training = model is not None
@@ -42,15 +43,17 @@ def test(data,
42
  set_logging()
43
  device = select_device(opt.device, batch_size=batch_size)
44
  save_txt = opt.save_txt # save *.txt labels
45
- if save_txt:
46
- out = Path('inference/output')
47
- if os.path.exists(out):
48
- shutil.rmtree(out) # delete output folder
49
- os.makedirs(out) # make new output folder
50
 
51
  # Remove previous
52
- for f in glob.glob(str(save_dir / 'test_batch*.jpg')):
53
- os.remove(f)
 
 
 
 
 
 
 
54
 
55
  # Load model
56
  model = attempt_load(weights, map_location=device) # load FP32 model
@@ -132,8 +135,9 @@ def test(data,
132
  x[:, :4] = scale_coords(img[si].shape[1:], x[:, :4], shapes[si][0], shapes[si][1]) # to original
133
  for *xyxy, conf, cls in x:
134
  xywh = (xyxy2xywh(torch.tensor(xyxy).view(1, 4)) / gn).view(-1).tolist() # normalized xywh
 
135
  with open(str(out / Path(paths[si]).stem) + '.txt', 'a') as f:
136
- f.write(('%g ' * 5 + '\n') % (cls, *xywh)) # label format
137
 
138
  # Clip boxes to image bounds
139
  clip_coords(pred, (height, width))
@@ -263,6 +267,8 @@ if __name__ == '__main__':
263
  parser.add_argument('--augment', action='store_true', help='augmented inference')
264
  parser.add_argument('--verbose', action='store_true', help='report mAP by class')
265
  parser.add_argument('--save-txt', action='store_true', help='save results to *.txt')
 
 
266
  opt = parser.parse_args()
267
  opt.save_json |= opt.data.endswith('coco.yaml')
268
  opt.data = check_file(opt.data) # check file
@@ -278,7 +284,13 @@ if __name__ == '__main__':
278
  opt.save_json,
279
  opt.single_cls,
280
  opt.augment,
281
- opt.verbose)
 
 
 
 
 
 
282
 
283
  elif opt.task == 'study': # run over a range of settings and save/plot
284
  for weights in ['yolov5s.pt', 'yolov5m.pt', 'yolov5l.pt', 'yolov5x.pt']:
 
32
  dataloader=None,
33
  save_dir=Path(''), # for saving images
34
  save_txt=False, # for auto-labelling
35
+ save_conf=False,
36
  plots=True):
37
  # Initialize/load model and set device
38
  training = model is not None
 
43
  set_logging()
44
  device = select_device(opt.device, batch_size=batch_size)
45
  save_txt = opt.save_txt # save *.txt labels
 
 
 
 
 
46
 
47
  # Remove previous
48
+ if os.path.exists(save_dir):
49
+ shutil.rmtree(save_dir) # delete dir
50
+ os.makedirs(save_dir) # make new dir
51
+
52
+ if save_txt:
53
+ out = save_dir / 'autolabels'
54
+ if os.path.exists(out):
55
+ shutil.rmtree(out) # delete dir
56
+ os.makedirs(out) # make new dir
57
 
58
  # Load model
59
  model = attempt_load(weights, map_location=device) # load FP32 model
 
135
  x[:, :4] = scale_coords(img[si].shape[1:], x[:, :4], shapes[si][0], shapes[si][1]) # to original
136
  for *xyxy, conf, cls in x:
137
  xywh = (xyxy2xywh(torch.tensor(xyxy).view(1, 4)) / gn).view(-1).tolist() # normalized xywh
138
+ line = (cls, conf, *xywh) if save_conf else (cls, *xywh) # label format
139
  with open(str(out / Path(paths[si]).stem) + '.txt', 'a') as f:
140
+ f.write(('%g ' * len(line) + '\n') % line)
141
 
142
  # Clip boxes to image bounds
143
  clip_coords(pred, (height, width))
 
267
  parser.add_argument('--augment', action='store_true', help='augmented inference')
268
  parser.add_argument('--verbose', action='store_true', help='report mAP by class')
269
  parser.add_argument('--save-txt', action='store_true', help='save results to *.txt')
270
+ parser.add_argument('--save-conf', action='store_true', help='save confidences in --save-txt labels')
271
+ parser.add_argument('--save-dir', type=str, default='runs/test', help='directory to save results')
272
  opt = parser.parse_args()
273
  opt.save_json |= opt.data.endswith('coco.yaml')
274
  opt.data = check_file(opt.data) # check file
 
284
  opt.save_json,
285
  opt.single_cls,
286
  opt.augment,
287
+ opt.verbose,
288
+ save_dir=Path(opt.save_dir),
289
+ save_txt=opt.save_txt,
290
+ save_conf=opt.save_conf,
291
+ )
292
+
293
+ print('Results saved to %s' % opt.save_dir)
294
 
295
  elif opt.task == 'study': # run over a range of settings and save/plot
296
  for weights in ['yolov5s.pt', 'yolov5m.pt', 'yolov5l.pt', 'yolov5x.pt']: