@ -55,11 +55,11 @@ class Compose:
return self . transforms
return self . transforms
def __repr__ ( self ) :
def __repr__ ( self ) :
format_string = f " { self . __class__ . __name__ } ( "
format_string = f ' { self . __class__ . __name__ } ( '
for t in self . transforms :
for t in self . transforms :
format_string + = " \n "
format_string + = ' \n '
format_string + = f " { t } "
format_string + = f ' { t } '
format_string + = " \n ) "
format_string + = ' \n ) '
return format_string
return format_string
@ -86,11 +86,11 @@ class BaseMixTransform:
if self . pre_transform is not None :
if self . pre_transform is not None :
for i , data in enumerate ( mix_labels ) :
for i , data in enumerate ( mix_labels ) :
mix_labels [ i ] = self . pre_transform ( data )
mix_labels [ i ] = self . pre_transform ( data )
labels [ " mix_labels " ] = mix_labels
labels [ ' mix_labels ' ] = mix_labels
# Mosaic or MixUp
# Mosaic or MixUp
labels = self . _mix_transform ( labels )
labels = self . _mix_transform ( labels )
labels . pop ( " mix_labels " , None )
labels . pop ( ' mix_labels ' , None )
return labels
return labels
def _mix_transform ( self , labels ) :
def _mix_transform ( self , labels ) :
@ -109,7 +109,7 @@ class Mosaic(BaseMixTransform):
"""
"""
def __init__ ( self , dataset , imgsz = 640 , p = 1.0 , border = ( 0 , 0 ) ) :
def __init__ ( self , dataset , imgsz = 640 , p = 1.0 , border = ( 0 , 0 ) ) :
assert 0 < = p < = 1.0 , " The probability should be in range [0, 1]. " f " got { p } . "
assert 0 < = p < = 1.0 , ' The probability should be in range [0, 1]. ' f ' got { p } . '
super ( ) . __init__ ( dataset = dataset , p = p )
super ( ) . __init__ ( dataset = dataset , p = p )
self . dataset = dataset
self . dataset = dataset
self . imgsz = imgsz
self . imgsz = imgsz
@ -120,15 +120,15 @@ class Mosaic(BaseMixTransform):
def _mix_transform ( self , labels ) :
def _mix_transform ( self , labels ) :
mosaic_labels = [ ]
mosaic_labels = [ ]
assert labels . get ( " rect_shape " , None ) is None , " rect and mosaic is exclusive. "
assert labels . get ( ' rect_shape ' , None ) is None , ' rect and mosaic is exclusive. '
assert len ( labels . get ( " mix_labels " , [ ] ) ) > 0 , " There are no other images for mosaic augment. "
assert len ( labels . get ( ' mix_labels ' , [ ] ) ) > 0 , ' There are no other images for mosaic augment. '
s = self . imgsz
s = self . imgsz
yc , xc = ( int ( random . uniform ( - x , 2 * s + x ) ) for x in self . border ) # mosaic center x, y
yc , xc = ( int ( random . uniform ( - x , 2 * s + x ) ) for x in self . border ) # mosaic center x, y
for i in range ( 4 ) :
for i in range ( 4 ) :
labels_patch = ( labels if i == 0 else labels [ " mix_labels " ] [ i - 1 ] ) . copy ( )
labels_patch = ( labels if i == 0 else labels [ ' mix_labels ' ] [ i - 1 ] ) . copy ( )
# Load image
# Load image
img = labels_patch [ " img " ]
img = labels_patch [ ' img ' ]
h , w = labels_patch . pop ( " resized_shape " )
h , w = labels_patch . pop ( ' resized_shape ' )
# place img in img4
# place img in img4
if i == 0 : # top left
if i == 0 : # top left
@ -152,15 +152,15 @@ class Mosaic(BaseMixTransform):
labels_patch = self . _update_labels ( labels_patch , padw , padh )
labels_patch = self . _update_labels ( labels_patch , padw , padh )
mosaic_labels . append ( labels_patch )
mosaic_labels . append ( labels_patch )
final_labels = self . _cat_labels ( mosaic_labels )
final_labels = self . _cat_labels ( mosaic_labels )
final_labels [ " img " ] = img4
final_labels [ ' img ' ] = img4
return final_labels
return final_labels
def _update_labels ( self , labels , padw , padh ) :
def _update_labels ( self , labels , padw , padh ) :
""" Update labels """
""" Update labels """
nh , nw = labels [ " img " ] . shape [ : 2 ]
nh , nw = labels [ ' img ' ] . shape [ : 2 ]
labels [ " instances " ] . convert_bbox ( format = " xyxy " )
labels [ ' instances ' ] . convert_bbox ( format = ' xyxy ' )
labels [ " instances " ] . denormalize ( nw , nh )
labels [ ' instances ' ] . denormalize ( nw , nh )
labels [ " instances " ] . add_padding ( padw , padh )
labels [ ' instances ' ] . add_padding ( padw , padh )
return labels
return labels
def _cat_labels ( self , mosaic_labels ) :
def _cat_labels ( self , mosaic_labels ) :
@ -169,16 +169,16 @@ class Mosaic(BaseMixTransform):
cls = [ ]
cls = [ ]
instances = [ ]
instances = [ ]
for labels in mosaic_labels :
for labels in mosaic_labels :
cls . append ( labels [ " cls " ] )
cls . append ( labels [ ' cls ' ] )
instances . append ( labels [ " instances " ] )
instances . append ( labels [ ' instances ' ] )
final_labels = {
final_labels = {
" im_file " : mosaic_labels [ 0 ] [ " im_file " ] ,
' im_file ' : mosaic_labels [ 0 ] [ ' im_file ' ] ,
" ori_shape " : mosaic_labels [ 0 ] [ " ori_shape " ] ,
' ori_shape ' : mosaic_labels [ 0 ] [ ' ori_shape ' ] ,
" resized_shape " : ( self . imgsz * 2 , self . imgsz * 2 ) ,
' resized_shape ' : ( self . imgsz * 2 , self . imgsz * 2 ) ,
" cls " : np . concatenate ( cls , 0 ) ,
' cls ' : np . concatenate ( cls , 0 ) ,
" instances " : Instances . concatenate ( instances , axis = 0 ) ,
' instances ' : Instances . concatenate ( instances , axis = 0 ) ,
" mosaic_border " : self . border }
' mosaic_border ' : self . border }
final_labels [ " instances " ] . clip ( self . imgsz * 2 , self . imgsz * 2 )
final_labels [ ' instances ' ] . clip ( self . imgsz * 2 , self . imgsz * 2 )
return final_labels
return final_labels
@ -193,10 +193,10 @@ class MixUp(BaseMixTransform):
def _mix_transform ( self , labels ) :
def _mix_transform ( self , labels ) :
# Applies MixUp augmentation https://arxiv.org/pdf/1710.09412.pdf
# Applies MixUp augmentation https://arxiv.org/pdf/1710.09412.pdf
r = np . random . beta ( 32.0 , 32.0 ) # mixup ratio, alpha=beta=32.0
r = np . random . beta ( 32.0 , 32.0 ) # mixup ratio, alpha=beta=32.0
labels2 = labels [ " mix_labels " ] [ 0 ]
labels2 = labels [ ' mix_labels ' ] [ 0 ]
labels [ " img " ] = ( labels [ " img " ] * r + labels2 [ " img " ] * ( 1 - r ) ) . astype ( np . uint8 )
labels [ ' img ' ] = ( labels [ ' img ' ] * r + labels2 [ ' img ' ] * ( 1 - r ) ) . astype ( np . uint8 )
labels [ " instances " ] = Instances . concatenate ( [ labels [ " instances " ] , labels2 [ " instances " ] ] , axis = 0 )
labels [ ' instances ' ] = Instances . concatenate ( [ labels [ ' instances ' ] , labels2 [ ' instances ' ] ] , axis = 0 )
labels [ " cls " ] = np . concatenate ( [ labels [ " cls " ] , labels2 [ " cls " ] ] , 0 )
labels [ ' cls ' ] = np . concatenate ( [ labels [ ' cls ' ] , labels2 [ ' cls ' ] ] , 0 )
return labels
return labels
@ -338,18 +338,18 @@ class RandomPerspective:
Args :
Args :
labels ( Dict ) : a dict of ` bboxes ` , ` segments ` , ` keypoints ` .
labels ( Dict ) : a dict of ` bboxes ` , ` segments ` , ` keypoints ` .
"""
"""
if self . pre_transform and " mosaic_border " not in labels :
if self . pre_transform and ' mosaic_border ' not in labels :
labels = self . pre_transform ( labels )
labels = self . pre_transform ( labels )
labels . pop ( " ratio_pad " ) # do not need ratio pad
labels . pop ( ' ratio_pad ' ) # do not need ratio pad
img = labels [ " img " ]
img = labels [ ' img ' ]
cls = labels [ " cls " ]
cls = labels [ ' cls ' ]
instances = labels . pop ( " instances " )
instances = labels . pop ( ' instances ' )
# make sure the coord formats are right
# make sure the coord formats are right
instances . convert_bbox ( format = " xyxy " )
instances . convert_bbox ( format = ' xyxy ' )
instances . denormalize ( * img . shape [ : 2 ] [ : : - 1 ] )
instances . denormalize ( * img . shape [ : 2 ] [ : : - 1 ] )
border = labels . pop ( " mosaic_border " , self . border )
border = labels . pop ( ' mosaic_border ' , self . border )
self . size = img . shape [ 1 ] + border [ 1 ] * 2 , img . shape [ 0 ] + border [ 0 ] * 2 # w, h
self . size = img . shape [ 1 ] + border [ 1 ] * 2 , img . shape [ 0 ] + border [ 0 ] * 2 # w, h
# M is affine matrix
# M is affine matrix
# scale for func:`box_candidates`
# scale for func:`box_candidates`
@ -365,7 +365,7 @@ class RandomPerspective:
if keypoints is not None :
if keypoints is not None :
keypoints = self . apply_keypoints ( keypoints , M )
keypoints = self . apply_keypoints ( keypoints , M )
new_instances = Instances ( bboxes , segments , keypoints , bbox_format = " xyxy " , normalized = False )
new_instances = Instances ( bboxes , segments , keypoints , bbox_format = ' xyxy ' , normalized = False )
# clip
# clip
new_instances . clip ( * self . size )
new_instances . clip ( * self . size )
@ -375,10 +375,10 @@ class RandomPerspective:
i = self . box_candidates ( box1 = instances . bboxes . T ,
i = self . box_candidates ( box1 = instances . bboxes . T ,
box2 = new_instances . bboxes . T ,
box2 = new_instances . bboxes . T ,
area_thr = 0.01 if len ( segments ) else 0.10 )
area_thr = 0.01 if len ( segments ) else 0.10 )
labels [ " instances " ] = new_instances [ i ]
labels [ ' instances ' ] = new_instances [ i ]
labels [ " cls " ] = cls [ i ]
labels [ ' cls ' ] = cls [ i ]
labels [ " img " ] = img
labels [ ' img ' ] = img
labels [ " resized_shape " ] = img . shape [ : 2 ]
labels [ ' resized_shape ' ] = img . shape [ : 2 ]
return labels
return labels
def box_candidates ( self , box1 , box2 , wh_thr = 2 , ar_thr = 100 , area_thr = 0.1 , eps = 1e-16 ) : # box1(4,n), box2(4,n)
def box_candidates ( self , box1 , box2 , wh_thr = 2 , ar_thr = 100 , area_thr = 0.1 , eps = 1e-16 ) : # box1(4,n), box2(4,n)
@ -397,7 +397,7 @@ class RandomHSV:
self . vgain = vgain
self . vgain = vgain
def __call__ ( self , labels ) :
def __call__ ( self , labels ) :
img = labels [ " img " ]
img = labels [ ' img ' ]
if self . hgain or self . sgain or self . vgain :
if self . hgain or self . sgain or self . vgain :
r = np . random . uniform ( - 1 , 1 , 3 ) * [ self . hgain , self . sgain , self . vgain ] + 1 # random gains
r = np . random . uniform ( - 1 , 1 , 3 ) * [ self . hgain , self . sgain , self . vgain ] + 1 # random gains
hue , sat , val = cv2 . split ( cv2 . cvtColor ( img , cv2 . COLOR_BGR2HSV ) )
hue , sat , val = cv2 . split ( cv2 . cvtColor ( img , cv2 . COLOR_BGR2HSV ) )
@ -415,30 +415,30 @@ class RandomHSV:
class RandomFlip :
class RandomFlip :
def __init__ ( self , p = 0.5 , direction = " horizontal " ) - > None :
def __init__ ( self , p = 0.5 , direction = ' horizontal ' ) - > None :
assert direction in [ " horizontal " , " vertical " ] , f " Support direction `horizontal` or `vertical`, got { direction } "
assert direction in [ ' horizontal ' , ' vertical ' ] , f ' Support direction `horizontal` or `vertical`, got { direction } '
assert 0 < = p < = 1.0
assert 0 < = p < = 1.0
self . p = p
self . p = p
self . direction = direction
self . direction = direction
def __call__ ( self , labels ) :
def __call__ ( self , labels ) :
img = labels [ " img " ]
img = labels [ ' img ' ]
instances = labels . pop ( " instances " )
instances = labels . pop ( ' instances ' )
instances . convert_bbox ( format = " xywh " )
instances . convert_bbox ( format = ' xywh ' )
h , w = img . shape [ : 2 ]
h , w = img . shape [ : 2 ]
h = 1 if instances . normalized else h
h = 1 if instances . normalized else h
w = 1 if instances . normalized else w
w = 1 if instances . normalized else w
# Flip up-down
# Flip up-down
if self . direction == " vertical " and random . random ( ) < self . p :
if self . direction == ' vertical ' and random . random ( ) < self . p :
img = np . flipud ( img )
img = np . flipud ( img )
instances . flipud ( h )
instances . flipud ( h )
if self . direction == " horizontal " and random . random ( ) < self . p :
if self . direction == ' horizontal ' and random . random ( ) < self . p :
img = np . fliplr ( img )
img = np . fliplr ( img )
instances . fliplr ( w )
instances . fliplr ( w )
labels [ " img " ] = np . ascontiguousarray ( img )
labels [ ' img ' ] = np . ascontiguousarray ( img )
labels [ " instances " ] = instances
labels [ ' instances ' ] = instances
return labels
return labels
@ -455,9 +455,9 @@ class LetterBox:
def __call__ ( self , labels = None , image = None ) :
def __call__ ( self , labels = None , image = None ) :
if labels is None :
if labels is None :
labels = { }
labels = { }
img = labels . get ( " img " ) if image is None else image
img = labels . get ( ' img ' ) if image is None else image
shape = img . shape [ : 2 ] # current shape [height, width]
shape = img . shape [ : 2 ] # current shape [height, width]
new_shape = labels . pop ( " rect_shape " , self . new_shape )
new_shape = labels . pop ( ' rect_shape ' , self . new_shape )
if isinstance ( new_shape , int ) :
if isinstance ( new_shape , int ) :
new_shape = ( new_shape , new_shape )
new_shape = ( new_shape , new_shape )
@ -479,8 +479,8 @@ class LetterBox:
dw / = 2 # divide padding into 2 sides
dw / = 2 # divide padding into 2 sides
dh / = 2
dh / = 2
if labels . get ( " ratio_pad " ) :
if labels . get ( ' ratio_pad ' ) :
labels [ " ratio_pad " ] = ( labels [ " ratio_pad " ] , ( dw , dh ) ) # for evaluation
labels [ ' ratio_pad ' ] = ( labels [ ' ratio_pad ' ] , ( dw , dh ) ) # for evaluation
if shape [ : : - 1 ] != new_unpad : # resize
if shape [ : : - 1 ] != new_unpad : # resize
img = cv2 . resize ( img , new_unpad , interpolation = cv2 . INTER_LINEAR )
img = cv2 . resize ( img , new_unpad , interpolation = cv2 . INTER_LINEAR )
@ -491,18 +491,18 @@ class LetterBox:
if len ( labels ) :
if len ( labels ) :
labels = self . _update_labels ( labels , ratio , dw , dh )
labels = self . _update_labels ( labels , ratio , dw , dh )
labels [ " img " ] = img
labels [ ' img ' ] = img
labels [ " resized_shape " ] = new_shape
labels [ ' resized_shape ' ] = new_shape
return labels
return labels
else :
else :
return img
return img
def _update_labels ( self , labels , ratio , padw , padh ) :
def _update_labels ( self , labels , ratio , padw , padh ) :
""" Update labels """
""" Update labels """
labels [ " instances " ] . convert_bbox ( format = " xyxy " )
labels [ ' instances ' ] . convert_bbox ( format = ' xyxy ' )
labels [ " instances " ] . denormalize ( * labels [ " img " ] . shape [ : 2 ] [ : : - 1 ] )
labels [ ' instances ' ] . denormalize ( * labels [ ' img ' ] . shape [ : 2 ] [ : : - 1 ] )
labels [ " instances " ] . scale ( * ratio )
labels [ ' instances ' ] . scale ( * ratio )
labels [ " instances " ] . add_padding ( padw , padh )
labels [ ' instances ' ] . add_padding ( padw , padh )
return labels
return labels
@ -513,11 +513,11 @@ class CopyPaste:
def __call__ ( self , labels ) :
def __call__ ( self , labels ) :
# Implement Copy-Paste augmentation https://arxiv.org/abs/2012.07177, labels as nx5 np.array(cls, xyxy)
# Implement Copy-Paste augmentation https://arxiv.org/abs/2012.07177, labels as nx5 np.array(cls, xyxy)
im = labels [ " img " ]
im = labels [ ' img ' ]
cls = labels [ " cls " ]
cls = labels [ ' cls ' ]
h , w = im . shape [ : 2 ]
h , w = im . shape [ : 2 ]
instances = labels . pop ( " instances " )
instances = labels . pop ( ' instances ' )
instances . convert_bbox ( format = " xyxy " )
instances . convert_bbox ( format = ' xyxy ' )
instances . denormalize ( w , h )
instances . denormalize ( w , h )
if self . p and len ( instances . segments ) :
if self . p and len ( instances . segments ) :
n = len ( instances )
n = len ( instances )
@ -540,9 +540,9 @@ class CopyPaste:
i = cv2 . flip ( im_new , 1 ) . astype ( bool )
i = cv2 . flip ( im_new , 1 ) . astype ( bool )
im [ i ] = result [ i ] # cv2.imwrite('debug.jpg', im) # debug
im [ i ] = result [ i ] # cv2.imwrite('debug.jpg', im) # debug
labels [ " img " ] = im
labels [ ' img ' ] = im
labels [ " cls " ] = cls
labels [ ' cls ' ] = cls
labels [ " instances " ] = instances
labels [ ' instances ' ] = instances
return labels
return labels
@ -551,11 +551,11 @@ class Albumentations:
def __init__ ( self , p = 1.0 ) :
def __init__ ( self , p = 1.0 ) :
self . p = p
self . p = p
self . transform = None
self . transform = None
prefix = colorstr ( " albumentations: " )
prefix = colorstr ( ' albumentations: ' )
try :
try :
import albumentations as A
import albumentations as A
check_version ( A . __version__ , " 1.0.3 " , hard = True ) # version requirement
check_version ( A . __version__ , ' 1.0.3 ' , hard = True ) # version requirement
T = [
T = [
A . Blur ( p = 0.01 ) ,
A . Blur ( p = 0.01 ) ,
@ -565,28 +565,28 @@ class Albumentations:
A . RandomBrightnessContrast ( p = 0.0 ) ,
A . RandomBrightnessContrast ( p = 0.0 ) ,
A . RandomGamma ( p = 0.0 ) ,
A . RandomGamma ( p = 0.0 ) ,
A . ImageCompression ( quality_lower = 75 , p = 0.0 ) , ] # transforms
A . ImageCompression ( quality_lower = 75 , p = 0.0 ) , ] # transforms
self . transform = A . Compose ( T , bbox_params = A . BboxParams ( format = " yolo " , label_fields = [ " class_labels " ] ) )
self . transform = A . Compose ( T , bbox_params = A . BboxParams ( format = ' yolo ' , label_fields = [ ' class_labels ' ] ) )
LOGGER . info ( prefix + " , " . join ( f " { x } " . replace ( " always_apply=False, " , " " ) for x in T if x . p ) )
LOGGER . info ( prefix + ' , ' . join ( f ' { x } ' . replace ( ' always_apply=False, ' , ' ' ) for x in T if x . p ) )
except ImportError : # package not installed, skip
except ImportError : # package not installed, skip
pass
pass
except Exception as e :
except Exception as e :
LOGGER . info ( f " { prefix } { e } " )
LOGGER . info ( f ' { prefix } { e } ' )
def __call__ ( self , labels ) :
def __call__ ( self , labels ) :
im = labels [ " img " ]
im = labels [ ' img ' ]
cls = labels [ " cls " ]
cls = labels [ ' cls ' ]
if len ( cls ) :
if len ( cls ) :
labels [ " instances " ] . convert_bbox ( " xywh " )
labels [ ' instances ' ] . convert_bbox ( ' xywh ' )
labels [ " instances " ] . normalize ( * im . shape [ : 2 ] [ : : - 1 ] )
labels [ ' instances ' ] . normalize ( * im . shape [ : 2 ] [ : : - 1 ] )
bboxes = labels [ " instances " ] . bboxes
bboxes = labels [ ' instances ' ] . bboxes
# TODO: add supports of segments and keypoints
# TODO: add supports of segments and keypoints
if self . transform and random . random ( ) < self . p :
if self . transform and random . random ( ) < self . p :
new = self . transform ( image = im , bboxes = bboxes , class_labels = cls ) # transformed
new = self . transform ( image = im , bboxes = bboxes , class_labels = cls ) # transformed
labels [ " img " ] = new [ " image " ]
labels [ ' img ' ] = new [ ' image ' ]
labels [ " cls " ] = np . array ( new [ " class_labels " ] )
labels [ ' cls ' ] = np . array ( new [ ' class_labels ' ] )
bboxes = np . array ( new [ " bboxes " ] )
bboxes = np . array ( new [ ' bboxes ' ] )
labels [ " instances " ] . update ( bboxes = bboxes )
labels [ ' instances ' ] . update ( bboxes = bboxes )
return labels
return labels
@ -594,7 +594,7 @@ class Albumentations:
class Format :
class Format :
def __init__ ( self ,
def __init__ ( self ,
bbox_format = " xywh " ,
bbox_format = ' xywh ' ,
normalize = True ,
normalize = True ,
return_mask = False ,
return_mask = False ,
return_keypoint = False ,
return_keypoint = False ,
@ -610,10 +610,10 @@ class Format:
self . batch_idx = batch_idx # keep the batch indexes
self . batch_idx = batch_idx # keep the batch indexes
def __call__ ( self , labels ) :
def __call__ ( self , labels ) :
img = labels . pop ( " img " )
img = labels . pop ( ' img ' )
h , w = img . shape [ : 2 ]
h , w = img . shape [ : 2 ]
cls = labels . pop ( " cls " )
cls = labels . pop ( ' cls ' )
instances = labels . pop ( " instances " )
instances = labels . pop ( ' instances ' )
instances . convert_bbox ( format = self . bbox_format )
instances . convert_bbox ( format = self . bbox_format )
instances . denormalize ( w , h )
instances . denormalize ( w , h )
nl = len ( instances )
nl = len ( instances )
@ -625,17 +625,17 @@ class Format:
else :
else :
masks = torch . zeros ( 1 if self . mask_overlap else nl , img . shape [ 0 ] / / self . mask_ratio ,
masks = torch . zeros ( 1 if self . mask_overlap else nl , img . shape [ 0 ] / / self . mask_ratio ,
img . shape [ 1 ] / / self . mask_ratio )
img . shape [ 1 ] / / self . mask_ratio )
labels [ " masks " ] = masks
labels [ ' masks ' ] = masks
if self . normalize :
if self . normalize :
instances . normalize ( w , h )
instances . normalize ( w , h )
labels [ " img " ] = self . _format_img ( img )
labels [ ' img ' ] = self . _format_img ( img )
labels [ " cls " ] = torch . from_numpy ( cls ) if nl else torch . zeros ( nl )
labels [ ' cls ' ] = torch . from_numpy ( cls ) if nl else torch . zeros ( nl )
labels [ " bboxes " ] = torch . from_numpy ( instances . bboxes ) if nl else torch . zeros ( ( nl , 4 ) )
labels [ ' bboxes ' ] = torch . from_numpy ( instances . bboxes ) if nl else torch . zeros ( ( nl , 4 ) )
if self . return_keypoint :
if self . return_keypoint :
labels [ " keypoints " ] = torch . from_numpy ( instances . keypoints ) if nl else torch . zeros ( ( nl , 17 , 2 ) )
labels [ ' keypoints ' ] = torch . from_numpy ( instances . keypoints ) if nl else torch . zeros ( ( nl , 17 , 2 ) )
# then we can use collate_fn
# then we can use collate_fn
if self . batch_idx :
if self . batch_idx :
labels [ " batch_idx " ] = torch . zeros ( nl )
labels [ ' batch_idx ' ] = torch . zeros ( nl )
return labels
return labels
def _format_img ( self , img ) :
def _format_img ( self , img ) :
@ -676,15 +676,15 @@ def v8_transforms(dataset, imgsz, hyp):
MixUp ( dataset , pre_transform = pre_transform , p = hyp . mixup ) ,
MixUp ( dataset , pre_transform = pre_transform , p = hyp . mixup ) ,
Albumentations ( p = 1.0 ) ,
Albumentations ( p = 1.0 ) ,
RandomHSV ( hgain = hyp . hsv_h , sgain = hyp . hsv_s , vgain = hyp . hsv_v ) ,
RandomHSV ( hgain = hyp . hsv_h , sgain = hyp . hsv_s , vgain = hyp . hsv_v ) ,
RandomFlip ( direction = " vertical " , p = hyp . flipud ) ,
RandomFlip ( direction = ' vertical ' , p = hyp . flipud ) ,
RandomFlip ( direction = " horizontal " , p = hyp . fliplr ) , ] ) # transforms
RandomFlip ( direction = ' horizontal ' , p = hyp . fliplr ) , ] ) # transforms
# Classification augmentations -----------------------------------------------------------------------------------------
# Classification augmentations -----------------------------------------------------------------------------------------
def classify_transforms ( size = 224 ) :
def classify_transforms ( size = 224 ) :
# Transforms to apply if albumentations not installed
# Transforms to apply if albumentations not installed
if not isinstance ( size , int ) :
if not isinstance ( size , int ) :
raise TypeError ( f " classify_transforms() size { size } must be integer, not (list, tuple) " )
raise TypeError ( f ' classify_transforms() size { size } must be integer, not (list, tuple) ' )
# T.Compose([T.ToTensor(), T.Resize(size), T.CenterCrop(size), T.Normalize(IMAGENET_MEAN, IMAGENET_STD)])
# T.Compose([T.ToTensor(), T.Resize(size), T.CenterCrop(size), T.Normalize(IMAGENET_MEAN, IMAGENET_STD)])
return T . Compose ( [ CenterCrop ( size ) , ToTensor ( ) , T . Normalize ( IMAGENET_MEAN , IMAGENET_STD ) ] )
return T . Compose ( [ CenterCrop ( size ) , ToTensor ( ) , T . Normalize ( IMAGENET_MEAN , IMAGENET_STD ) ] )
@ -701,17 +701,17 @@ def classify_albumentations(
auto_aug = False ,
auto_aug = False ,
) :
) :
# YOLOv8 classification Albumentations (optional, only used if package is installed)
# YOLOv8 classification Albumentations (optional, only used if package is installed)
prefix = colorstr ( " albumentations: " )
prefix = colorstr ( ' albumentations: ' )
try :
try :
import albumentations as A
import albumentations as A
from albumentations . pytorch import ToTensorV2
from albumentations . pytorch import ToTensorV2
check_version ( A . __version__ , " 1.0.3 " , hard = True ) # version requirement
check_version ( A . __version__ , ' 1.0.3 ' , hard = True ) # version requirement
if augment : # Resize and crop
if augment : # Resize and crop
T = [ A . RandomResizedCrop ( height = size , width = size , scale = scale ) ]
T = [ A . RandomResizedCrop ( height = size , width = size , scale = scale ) ]
if auto_aug :
if auto_aug :
# TODO: implement AugMix, AutoAug & RandAug in albumentation
# TODO: implement AugMix, AutoAug & RandAug in albumentation
LOGGER . info ( f " { prefix } auto augmentations are currently not supported " )
LOGGER . info ( f ' { prefix } auto augmentations are currently not supported ' )
else :
else :
if hflip > 0 :
if hflip > 0 :
T + = [ A . HorizontalFlip ( p = hflip ) ]
T + = [ A . HorizontalFlip ( p = hflip ) ]
@ -723,13 +723,13 @@ def classify_albumentations(
else : # Use fixed crop for eval set (reproducibility)
else : # Use fixed crop for eval set (reproducibility)
T = [ A . SmallestMaxSize ( max_size = size ) , A . CenterCrop ( height = size , width = size ) ]
T = [ A . SmallestMaxSize ( max_size = size ) , A . CenterCrop ( height = size , width = size ) ]
T + = [ A . Normalize ( mean = mean , std = std ) , ToTensorV2 ( ) ] # Normalize and convert to Tensor
T + = [ A . Normalize ( mean = mean , std = std ) , ToTensorV2 ( ) ] # Normalize and convert to Tensor
LOGGER . info ( prefix + " , " . join ( f " { x } " . replace ( " always_apply=False, " , " " ) for x in T if x . p ) )
LOGGER . info ( prefix + ' , ' . join ( f ' { x } ' . replace ( ' always_apply=False, ' , ' ' ) for x in T if x . p ) )
return A . Compose ( T )
return A . Compose ( T )
except ImportError : # package not installed, skip
except ImportError : # package not installed, skip
pass
pass
except Exception as e :
except Exception as e :
LOGGER . info ( f " { prefix } { e } " )
LOGGER . info ( f ' { prefix } { e } ' )
class ClassifyLetterBox :
class ClassifyLetterBox :