glenn-jocher commited on
Commit
80299a5
·
unverified ·
1 Parent(s): 443af8b

Numerical stability fix for Albumentations (#3958)

Browse files
Files changed (2) hide show
  1. utils/datasets.py +1 -1
  2. utils/general.py +11 -13
utils/datasets.py CHANGED
@@ -550,7 +550,7 @@ class LoadImagesAndLabels(Dataset): # for training/testing
550
 
551
  nl = len(labels) # number of labels
552
  if nl:
553
- labels[:, 1:5] = xyxy2xywhn(labels[:, 1:5], w=img.shape[1], h=img.shape[0]) # xyxy to xywh normalized
554
 
555
  if self.augment:
556
  # Albumentations
 
550
 
551
  nl = len(labels) # number of labels
552
  if nl:
553
+ labels[:, 1:5] = xyxy2xywhn(labels[:, 1:5], w=img.shape[1], h=img.shape[0], clip=True, eps=1E-3)
554
 
555
  if self.augment:
556
  # Albumentations
utils/general.py CHANGED
@@ -396,10 +396,10 @@ def xywhn2xyxy(x, w=640, h=640, padw=0, padh=0):
396
  return y
397
 
398
 
399
- def xyxy2xywhn(x, w=640, h=640, clip=False):
400
  # Convert nx4 boxes from [x1, y1, x2, y2] to [x, y, w, h] normalized where xy1=top-left, xy2=bottom-right
401
  if clip:
402
- clip_coords(x, (h, w)) # warning: inplace clip
403
  y = x.clone() if isinstance(x, torch.Tensor) else np.copy(x)
404
  y[:, 0] = ((x[:, 0] + x[:, 2]) / 2) / w # x center
405
  y[:, 1] = ((x[:, 1] + x[:, 3]) / 2) / h # y center
@@ -458,18 +458,16 @@ def scale_coords(img1_shape, coords, img0_shape, ratio_pad=None):
458
  return coords
459
 
460
 
461
- def clip_coords(boxes, img_shape):
462
  # Clip bounding xyxy bounding boxes to image shape (height, width)
463
- if isinstance(boxes, torch.Tensor):
464
- boxes[:, 0].clamp_(0, img_shape[1]) # x1
465
- boxes[:, 1].clamp_(0, img_shape[0]) # y1
466
- boxes[:, 2].clamp_(0, img_shape[1]) # x2
467
- boxes[:, 3].clamp_(0, img_shape[0]) # y2
468
- else: # np.array
469
- boxes[:, 0].clip(0, img_shape[1], out=boxes[:, 0]) # x1
470
- boxes[:, 1].clip(0, img_shape[0], out=boxes[:, 1]) # y1
471
- boxes[:, 2].clip(0, img_shape[1], out=boxes[:, 2]) # x2
472
- boxes[:, 3].clip(0, img_shape[0], out=boxes[:, 3]) # y2
473
 
474
 
475
  def non_max_suppression(prediction, conf_thres=0.25, iou_thres=0.45, classes=None, agnostic=False, multi_label=False,
 
396
  return y
397
 
398
 
399
+ def xyxy2xywhn(x, w=640, h=640, clip=False, eps=0.0):
400
  # Convert nx4 boxes from [x1, y1, x2, y2] to [x, y, w, h] normalized where xy1=top-left, xy2=bottom-right
401
  if clip:
402
+ clip_coords(x, (h - eps, w - eps)) # warning: inplace clip
403
  y = x.clone() if isinstance(x, torch.Tensor) else np.copy(x)
404
  y[:, 0] = ((x[:, 0] + x[:, 2]) / 2) / w # x center
405
  y[:, 1] = ((x[:, 1] + x[:, 3]) / 2) / h # y center
 
458
  return coords
459
 
460
 
461
+ def clip_coords(boxes, shape):
462
  # Clip bounding xyxy bounding boxes to image shape (height, width)
463
+ if isinstance(boxes, torch.Tensor): # faster individually
464
+ boxes[:, 0].clamp_(0, shape[1]) # x1
465
+ boxes[:, 1].clamp_(0, shape[0]) # y1
466
+ boxes[:, 2].clamp_(0, shape[1]) # x2
467
+ boxes[:, 3].clamp_(0, shape[0]) # y2
468
+ else: # np.array (faster grouped)
469
+ boxes[:, [0, 2]] = boxes[:, [0, 2]].clip(0, shape[1]) # x1, x2
470
+ boxes[:, [1, 3]] = boxes[:, [1, 3]].clip(0, shape[0]) # y1, y2
 
 
471
 
472
 
473
  def non_max_suppression(prediction, conf_thres=0.25, iou_thres=0.45, classes=None, agnostic=False, multi_label=False,