Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added augmentations #749

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
141 changes: 141 additions & 0 deletions deepforest/augmentations.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
import albumentations as A
from deepforest import utilities, get_data
import cv2
from albumentations.pytorch import ToTensorV2


def get_augmentations(augment=True):
try:
config_path = get_data("deepforest_config.yml")
except Exception as e:
raise ValueError("No config file provided and deepforest_config.yml "
"not found either in local directory or in installed "
"package location. {}".format(e))

augmentations = []
format_bbox = 'pascal_voc'
label_fields = ['category_ids']
try:
config = utilities.read_config(config_path)
augment_config = config["train" if augment else "validation"]["augmentations"]
except KeyError as e:
raise ValueError("Missing key in the configuration file: {}".format(e))

if not augment_config:
default_augmentations = config["train" if augment else "validation"][
"default_augmentations"]
for augment in default_augmentations:
augment_config_type = augment.get('type')
params = augment.get('params', {})

if augment_config_type.lower() == 'horizontalflip':
augmentations.append(A.HorizontalFlip(**params))

elif augment_config_type.lower() == 'verticalflip':
augmentations.append(A.VerticalFlip(**params))

elif augment_config_type.lower() == 'randomrotate90':
augmentations.append(A.RandomRotate90(**params))

elif augment_config_type.lower() == 'randomcrop':
augmentations.append(A.RandomCrop(**params))

elif augment_config_type.lower() == 'randombrightnesscontrast':
augmentations.append(A.RandomBrightnessContrast(**params))

elif augment_config_type.lower() == 'normalize':
augmentations.append(A.Normalize(**params))

elif augment_config_type.lower() == 'totensorv2':
augmentations.append(ToTensorV2())

elif augment_config_type.lower() == 'bbox':
format_bbox = params['format']
label_fields = params['label_fields']

transform = A.Compose(augmentations,
bbox_params=A.BboxParams(format=format_bbox,
label_fields=label_fields))

return transform

for augment in augment_config:
augment_config_type = augment.get('type')
params = augment.get('params', {})
if augment_config_type.lower() == "randomsizedbboxsafecrop":
try:
augmentations.append(A.RandomSizedBBoxSafeCrop(**params))
except KeyError as e:
raise ValueError(
"Missing parameter for RandomSizedBBoxSafeCrop: {}".format(e))

elif augment_config_type.lower() == "padifneeded":
min_height = params.get('min_height')
pad_height_divisor = params.get('pad_height_divisor', 'None')

try:
min_width = params['min_width']
position = params.get('position', 'top_left')
border_mode = params.get('border_mode', cv2.BORDER_CONSTANT)
value = params.get('value', 0)
mask_value = params.get('mask_value', None)
always_apply = params.get('always_apply', False)
p = params.get('p', 1.0)
except KeyError as e:
raise ValueError("Missing parameter for PadIfNeeded: {}".format(e))

if min_height == 'None' and pad_height_divisor != 'None':
augmentations.append(
A.PadIfNeeded(min_height=None,
min_width=min_width,
pad_height_divisor=pad_height_divisor,
position=position,
border_mode=border_mode,
value=value,
mask_value=mask_value,
always_apply=always_apply,
p=p))
elif min_height != "None" and pad_height_divisor == "None":
augmentations.append(
A.PadIfNeeded(min_height=min_height,
min_width=min_width,
position=position,
border_mode=border_mode,
value=value,
mask_value=mask_value,
always_apply=always_apply,
p=p))

elif augment_config_type.lower() == "totensorv2":
augmentations.append(ToTensorV2())

elif augment_config_type.lower() == 'horizontalflip':
augmentations.append(A.HorizontalFlip(**params))

elif augment_config_type.lower() == 'verticalflip':
augmentations.append(A.VerticalFlip(**params))

elif augment_config_type.lower() == 'randomrotate90':
augmentations.append(A.RandomRotate90(**params))

elif augment_config_type.lower() == 'randomcrop':
augmentations.append(A.RandomCrop(**params))

elif augment_config_type.lower() == 'randombrightnesscontrast':
augmentations.append(A.RandomBrightnessContrast(**params))

elif augment_config_type.lower() == 'normalize':
augmentations.append(A.Normalize(**params))

elif augment_config_type.lower() == 'totensorv2':
augmentations.append(ToTensorV2())

elif augment_config_type.lower() == 'bbox':
format_bbox = params['format']
label_fields = params['label_fields']

transform = A.Compose(augmentations,
bbox_params=A.BboxParams(format=format_bbox,
label_fields=label_fields))

return transform
58 changes: 58 additions & 0 deletions deepforest/data/deepforest_config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,57 @@ retinanet:
train:
csv_file:
root_dir:
augmentations:
- type: RandomSizedBBoxSafeCrop
params:
height: 300
width: 300
erosion_rate: 0.0
interpolation: 1
always_apply: False
- type: PadIfNeeded
params:
always_apply: False
p: 1.0
min_height: 1024
min_width: 1024
pad_height_divisor: None
pad_width_divisor: None
position: "center" # Store as string and convert in code
border_mode: 0 # cv2.BORDER_CONSTANT as integer
value: 0
- type: ToTensorV2
- type: BBox
params:
format: pascal_voc
label_fields: [category_ids]

default_augmentations:
- type: HorizontalFlip
params:
p: 0.5
- type: VerticalFlip
params:
p: 0.5
- type: RandomBrightnessContrast
params:
brightness_limit: 0.2
contrast_limit: 0.2
p: 0.5
- type: RandomRotate90
params:
p: 0.5
- type: Normalize
params:
mean: [0.485, 0.456, 0.406]
std: [0.229, 0.224, 0.225]
max_pixel_value: 255.0
p: 1.0
- type: ToTensorV2
- type: BBox
params:
format: pascal_voc
label_fields: [category_ids]

# Optimizer initial learning rate
lr: 0.001
Expand Down Expand Up @@ -55,6 +106,13 @@ validation:
# callback args
csv_file:
root_dir:
augmentations:
default_augmentations:
- type: ToTensorV2
- type: BBox
params:
format: pascal_voc
label_fields: [category_ids]
# Intersection over union evaluation
iou_threshold: 0.4
val_accuracy_interval: 20
60 changes: 59 additions & 1 deletion deepforest_config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,62 @@ retinanet:
train:
csv_file:
root_dir:
augmentations:
- type: RandomSizedBBoxSafeCrop
params:
height: 300
width: 300
erosion_rate: 0.0
interpolation: 1
always_apply: False
- type: PadIfNeeded
params:
always_apply: False
p: 1.0
min_height: 1024
min_width: 1024
pad_height_divisor: None
pad_width_divisor: None
position: "center" # Store as string and convert in code
border_mode: 0 # cv2.BORDER_CONSTANT as integer
value: 0
- type: ToTensorV2
- type: BBox
params:
format: pascal_voc
label_fields: [category_ids]

default_augmentations:
- type: HorizontalFlip
params:
p: 0.5
- type: VerticalFlip
params:
p: 0.5
- type: RandomBrightnessContrast
params:
brightness_limit: 0.2
contrast_limit: 0.2
p: 0.5
- type: RandomRotate90
params:
p: 0.5
- type: Normalize
params:
mean: [0.485, 0.456, 0.406]
std: [0.229, 0.224, 0.225]
max_pixel_value: 255.0
p: 1.0
- type: ToTensorV2
- type: BBox
params:
format: pascal_voc
label_fields: [category_ids]

# Optimizer initial learning rate
lr: 0.001
scheduler:
type:
type:
params:
# Common parameters
T_max: 10
Expand Down Expand Up @@ -55,6 +106,13 @@ validation:
# callback args
csv_file:
root_dir:
augmentations:
default_augmentations:
- type: ToTensorV2
- type: BBox
params:
format: pascal_voc
label_fields: [category_ids]
# Intersection over union evaluation
iou_threshold: 0.4
val_accuracy_interval: 20
Loading
Loading