glenn-jocher commited on
Commit
95fa653
1 Parent(s): 201bafc

Cat apriori to autolabels (#1484)

Browse files
Files changed (3) hide show
  1. detect.py +2 -1
  2. test.py +7 -6
  3. utils/general.py +11 -1
detect.py CHANGED
@@ -137,7 +137,8 @@ def detect(save_img=False):
137
  vid_writer.write(im0)
138
 
139
  if save_txt or save_img:
140
- print('Results saved to %s' % save_dir)
 
141
 
142
  print('Done. (%.3fs)' % (time.time() - t0))
143
 
 
137
  vid_writer.write(im0)
138
 
139
  if save_txt or save_img:
140
+ s = f"\n{len(list(save_dir.glob('labels/*.txt')))} labels saved to {save_dir / 'labels'}" if save_txt else ''
141
+ print(f"Results saved to {save_dir}{s}")
142
 
143
  print('Done. (%.3fs)' % (time.time() - t0))
144
 
test.py CHANGED
@@ -101,9 +101,8 @@ def test(data,
101
  img /= 255.0 # 0 - 255 to 0.0 - 1.0
102
  targets = targets.to(device)
103
  nb, _, height, width = img.shape # batch size, channels, height, width
104
- whwh = torch.Tensor([width, height, width, height]).to(device)
105
 
106
- # Disable gradients
107
  with torch.no_grad():
108
  # Run model
109
  t = time_synchronized()
@@ -111,12 +110,13 @@ def test(data,
111
  t0 += time_synchronized() - t
112
 
113
  # Compute loss
114
- if training: # if model has loss hyperparameters
115
  loss += compute_loss([x.float() for x in train_out], targets, model)[1][:3] # box, obj, cls
116
 
117
  # Run NMS
118
  t = time_synchronized()
119
- output = non_max_suppression(inf_out, conf_thres=conf_thres, iou_thres=iou_thres)
 
120
  t1 += time_synchronized() - t
121
 
122
  # Statistics per image
@@ -174,7 +174,7 @@ def test(data,
174
  tcls_tensor = labels[:, 0]
175
 
176
  # target boxes
177
- tbox = xywh2xyxy(labels[:, 1:5]) * whwh
178
  scale_coords(img[si].shape[1:], tbox, shapes[si][0], shapes[si][1]) # native-space labels
179
 
180
  # Per target class
@@ -264,7 +264,8 @@ def test(data,
264
 
265
  # Return results
266
  if not training:
267
- print('Results saved to %s' % save_dir)
 
268
  model.float() # for training
269
  maps = np.zeros(nc) + map
270
  for i, c in enumerate(ap_class):
 
101
  img /= 255.0 # 0 - 255 to 0.0 - 1.0
102
  targets = targets.to(device)
103
  nb, _, height, width = img.shape # batch size, channels, height, width
104
+ targets[:, 2:] *= torch.Tensor([width, height, width, height]).to(device)
105
 
 
106
  with torch.no_grad():
107
  # Run model
108
  t = time_synchronized()
 
110
  t0 += time_synchronized() - t
111
 
112
  # Compute loss
113
+ if training:
114
  loss += compute_loss([x.float() for x in train_out], targets, model)[1][:3] # box, obj, cls
115
 
116
  # Run NMS
117
  t = time_synchronized()
118
+ lb = [targets[targets[:, 0] == i, 1:] for i in range(nb)] if save_txt else [] # for autolabelling
119
+ output = non_max_suppression(inf_out, conf_thres=conf_thres, iou_thres=iou_thres, labels=lb)
120
  t1 += time_synchronized() - t
121
 
122
  # Statistics per image
 
174
  tcls_tensor = labels[:, 0]
175
 
176
  # target boxes
177
+ tbox = xywh2xyxy(labels[:, 1:5])
178
  scale_coords(img[si].shape[1:], tbox, shapes[si][0], shapes[si][1]) # native-space labels
179
 
180
  # Per target class
 
264
 
265
  # Return results
266
  if not training:
267
+ s = f"\n{len(list(save_dir.glob('labels/*.txt')))} labels saved to {save_dir / 'labels'}" if save_txt else ''
268
+ print(f"Results saved to {save_dir}{s}")
269
  model.float() # for training
270
  maps = np.zeros(nc) + map
271
  for i, c in enumerate(ap_class):
utils/general.py CHANGED
@@ -263,7 +263,7 @@ def wh_iou(wh1, wh2):
263
  return inter / (wh1.prod(2) + wh2.prod(2) - inter) # iou = inter / (area1 + area2 - inter)
264
 
265
 
266
- def non_max_suppression(prediction, conf_thres=0.1, iou_thres=0.6, merge=False, classes=None, agnostic=False):
267
  """Performs Non-Maximum Suppression (NMS) on inference results
268
 
269
  Returns:
@@ -279,6 +279,7 @@ def non_max_suppression(prediction, conf_thres=0.1, iou_thres=0.6, merge=False,
279
  time_limit = 10.0 # seconds to quit after
280
  redundant = True # require redundant detections
281
  multi_label = nc > 1 # multiple labels per box (adds 0.5ms/img)
 
282
 
283
  t = time.time()
284
  output = [torch.zeros(0, 6)] * prediction.shape[0]
@@ -287,6 +288,15 @@ def non_max_suppression(prediction, conf_thres=0.1, iou_thres=0.6, merge=False,
287
  # x[((x[..., 2:4] < min_wh) | (x[..., 2:4] > max_wh)).any(1), 4] = 0 # width-height
288
  x = x[xc[xi]] # confidence
289
 
 
 
 
 
 
 
 
 
 
290
  # If none remain process next image
291
  if not x.shape[0]:
292
  continue
 
263
  return inter / (wh1.prod(2) + wh2.prod(2) - inter) # iou = inter / (area1 + area2 - inter)
264
 
265
 
266
+ def non_max_suppression(prediction, conf_thres=0.1, iou_thres=0.6, classes=None, agnostic=False, labels=()):
267
  """Performs Non-Maximum Suppression (NMS) on inference results
268
 
269
  Returns:
 
279
  time_limit = 10.0 # seconds to quit after
280
  redundant = True # require redundant detections
281
  multi_label = nc > 1 # multiple labels per box (adds 0.5ms/img)
282
+ merge = False # use merge-NMS
283
 
284
  t = time.time()
285
  output = [torch.zeros(0, 6)] * prediction.shape[0]
 
288
  # x[((x[..., 2:4] < min_wh) | (x[..., 2:4] > max_wh)).any(1), 4] = 0 # width-height
289
  x = x[xc[xi]] # confidence
290
 
291
+ # Cat apriori labels if autolabelling
292
+ if labels and len(labels[xi]):
293
+ l = labels[xi]
294
+ v = torch.zeros((len(l), nc + 5), device=x.device)
295
+ v[:, :4] = l[:, 1:5] # box
296
+ v[:, 4] = 1.0 # conf
297
+ v[range(len(l)), l[:, 0].long() + 5] = 1.0 # cls
298
+ x = torch.cat((x, v), 0)
299
+
300
  # If none remain process next image
301
  if not x.shape[0]:
302
  continue