Skip to content

Commit

Permalink
Refactored Random Shadow (#1883)
Browse files Browse the repository at this point in the history
  • Loading branch information
ternaus authored Aug 15, 2024
1 parent d384b67 commit bee3a75
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 24 deletions.
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ repos:
types: [python]
- repo: https://github.com/astral-sh/ruff-pre-commit
# Ruff version.
rev: v0.5.7
rev: v0.6.0
hooks:
# Run the linter.
- id: ruff
Expand Down
8 changes: 4 additions & 4 deletions albumentations/augmentations/functional.py
Original file line number Diff line number Diff line change
Expand Up @@ -651,13 +651,13 @@ def add_sun_flare(


@preserve_channel_dim
def add_shadow(img: np.ndarray, vertices_list: list[np.ndarray], intensity_list: list[float]) -> np.ndarray:
def add_shadow(img: np.ndarray, vertices_list: list[np.ndarray], intensities: np.ndarray) -> np.ndarray:
"""Add shadows to the image by reducing the intensity of the pixel values in specified regions.
Args:
img (np.ndarray): Input image. Multichannel images are supported.
vertices_list (list[np.ndarray]): list of vertices for shadow polygons.
intensity_list (list[float]): list of shadow intensities. Range is [0, 1].
vertices_list (list[np.ndarray]): List of vertices for shadow polygons.
intensities (np.ndarray): Array of shadow intensities. Range is [0, 1].
Returns:
np.ndarray: Image with shadows added.
Expand All @@ -677,7 +677,7 @@ def add_shadow(img: np.ndarray, vertices_list: list[np.ndarray], intensity_list:
img_shadowed = img.copy()

# Iterate over the vertices and intensity list
for vertices, shadow_intensity in zip(vertices_list, intensity_list):
for vertices, shadow_intensity in zip(vertices_list, intensities):
# Create mask for the current shadow polygon
mask = np.zeros((img.shape[0], img.shape[1], 1), dtype=np.uint8)
cv2.fillPoly(mask, [vertices], (max_value,))
Expand Down
43 changes: 25 additions & 18 deletions albumentations/augmentations/transforms.py
Original file line number Diff line number Diff line change
Expand Up @@ -1131,15 +1131,17 @@ def get_transform_init_args(self) -> dict[str, Any]:


class RandomShadow(ImageOnlyTransform):
"""Simulates shadows for the image by reducing the brightness of the image in the shadow regions.
Works for both single and multi-channel images.
"""Simulates shadows for the image by reducing the brightness of the image in shadow regions.
Args:
shadow_roi: region of the image where shadows
will appear. All values should be in range [0, 1].
num_shadows_limit: Lower and upper limits for the possible number of shadows.
shadow_dimension: number of edges in the shadow polygons
shadow_roi (tuple): region of the image where shadows
will appear (x_min, y_min, x_max, y_max). All values should be in range [0, 1].
num_shadows_limit (tuple): Lower and upper limits for the possible number of shadows.
Default: (1, 2).
shadow_dimension (int): number of edges in the shadow polygons. Default: 5.
shadow_intensity_range (tuple): Range for the shadow intensity.
Should be two float values between 0 and 1. Default: (0.5, 0.5).
p (float): probability of applying the transform. Default: 0.5.
Targets:
image
Expand Down Expand Up @@ -1170,9 +1172,13 @@ class InitSchema(BaseTransformInitSchema):
)
shadow_dimension: int = Field(default=5, description="Number of edges in the shadow polygons", ge=1)

shadow_intensity_range: float | tuple[float, float] = Field(
default=0.5,
description="Value or sample range for the shadow intensity",
shadow_intensity_range: Annotated[
tuple[float, float],
AfterValidator(check_01),
AfterValidator(nondecreasing),
] = Field(
default=(0.5, 0.5),
description="Range for the shadow intensity",
)

@model_validator(mode="after")
Expand Down Expand Up @@ -1232,7 +1238,7 @@ def __init__(
num_shadows_lower: int | None = None,
num_shadows_upper: int | None = None,
shadow_dimension: int = 5,
shadow_intensity_range: float | tuple[float, float] = 0.5,
shadow_intensity_range: tuple[float, float] = (0.5, 0.5),
always_apply: bool | None = None,
p: float = 0.5,
):
Expand All @@ -1247,10 +1253,10 @@ def apply(
self,
img: np.ndarray,
vertices_list: list[np.ndarray],
intensity_list: list[float],
intensities: np.ndarray,
**params: Any,
) -> np.ndarray:
return fmain.add_shadow(img, vertices_list, intensity_list)
return fmain.add_shadow(img, vertices_list, intensities)

def get_params_dependent_on_data(self, params: dict[str, Any], data: dict[str, Any]) -> dict[str, list[np.ndarray]]:
height, width = params["shape"][:2]
Expand All @@ -1276,12 +1282,13 @@ def get_params_dependent_on_data(self, params: dict[str, Any], data: dict[str, A
]

# Sample shadow intensity for each shadow
if isinstance(self.shadow_intensity_range, float):
intensity_list = [self.shadow_intensity_range] * num_shadows
else:
intensity_list = [random.uniform(*self.shadow_intensity_range) for _ in range(num_shadows)]
intensities = random_utils.uniform(
self.shadow_intensity_range[0],
self.shadow_intensity_range[1],
size=num_shadows,
)

return {"vertices_list": vertices_list, "intensity_list": intensity_list}
return {"vertices_list": vertices_list, "intensities": intensities}

def get_transform_init_args_names(self) -> tuple[str, ...]:
return (
Expand Down
2 changes: 1 addition & 1 deletion requirements-dev.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ pytest>=8.3.2
pytest_cov>=5.0.0
pytest_mock>=3.14.0
requests>=2.31.0
ruff>=0.5.7
ruff>=0.6.0
tomli>=2.0.1
types-PyYAML
types-setuptools

0 comments on commit bee3a75

Please sign in to comment.