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 <[email protected]>
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.
|
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
|
30 |
-
os.makedirs(out) # make new
|
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='
|
|
|
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 |
-
|
53 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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 ' *
|
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']:
|