Skip to content
This repository was archived by the owner on Jul 10, 2025. It is now read-only.

Commit 69fbf90

Browse files
Adding apply_to_images to Pad (#2534)
* Added apply_to_images method to Pad * Fix style * More style fixes. * Test hooks.
1 parent 850fa46 commit 69fbf90

3 files changed

Lines changed: 88 additions & 0 deletions

File tree

albumentations/augmentations/geometric/functional.py

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1537,6 +1537,62 @@ def pad_with_params(
15371537
return pad_fn(img)
15381538

15391539

1540+
def pad_images_with_params(
1541+
images: np.ndarray,
1542+
h_pad_top: int,
1543+
h_pad_bottom: int,
1544+
w_pad_left: int,
1545+
w_pad_right: int,
1546+
border_mode: int,
1547+
value: tuple[float, ...] | float | None,
1548+
) -> np.ndarray:
1549+
"""Pad a batch of images with explicitly defined padding on each side.
1550+
1551+
This function adds specified amounts of padding to each side of the image for each
1552+
image in the batch.
1553+
1554+
Args:
1555+
images (np.ndarray): Input batch of images to pad.
1556+
h_pad_top (int): Number of pixels to add at the top.
1557+
h_pad_bottom (int): Number of pixels to add at the bottom.
1558+
w_pad_left (int): Number of pixels to add on the left.
1559+
w_pad_right (int): Number of pixels to add on the right.
1560+
border_mode (int): OpenCV border mode for padding.
1561+
value (tuple[float, ...] | float | None): Value(s) to fill the border pixels.
1562+
1563+
Returns:
1564+
np.ndarray: Padded batch of images.
1565+
1566+
"""
1567+
no_channel_dim = images.ndim == 3
1568+
if no_channel_dim:
1569+
images = images[..., np.newaxis]
1570+
1571+
cv2np_border_modes = {
1572+
cv2.BORDER_CONSTANT: "constant",
1573+
cv2.BORDER_REPLICATE: "edge",
1574+
cv2.BORDER_REFLECT: "symmetric",
1575+
cv2.BORDER_WRAP: "wrap",
1576+
cv2.BORDER_REFLECT_101: "reflect",
1577+
cv2.BORDER_REFLECT101: "reflect",
1578+
cv2.BORDER_DEFAULT: "reflect", # same as cv2.BORDER_REFLECT_101
1579+
}
1580+
mode = cv2np_border_modes[border_mode]
1581+
1582+
pad_width = ((0, 0), (h_pad_top, h_pad_bottom), (w_pad_left, w_pad_right), (0, 0))
1583+
if mode == "constant":
1584+
constant_values = np.array(((0, 0), (value, value), (value, value), (0, 0)), dtype=object)
1585+
kwargs = {"constant_values": constant_values}
1586+
else:
1587+
kwargs = {}
1588+
1589+
images = np.pad(images, pad_width=pad_width, mode=mode, **kwargs)
1590+
if no_channel_dim:
1591+
images = images[..., 0]
1592+
1593+
return images
1594+
1595+
15401596
@preserve_channel_dim
15411597
def remap(
15421598
img: np.ndarray,

albumentations/augmentations/geometric/pad.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,36 @@ def apply_to_keypoints(
334334
image_shape=params["shape"][:2],
335335
)
336336

337+
def apply_to_images(
338+
self,
339+
images: np.ndarray,
340+
pad_top: int,
341+
pad_bottom: int,
342+
pad_left: int,
343+
pad_right: int,
344+
**params: Any,
345+
) -> np.ndarray:
346+
"""Apply the Pad transform to a batch of images.
347+
348+
Args:
349+
images (np.ndarray): Batch of images to be transformed.
350+
pad_top (int): Top padding.
351+
pad_bottom (int): Bottom padding.
352+
pad_left (int): Left padding.
353+
pad_right (int): Right padding.
354+
**params (Any): Additional parameters.
355+
356+
"""
357+
return fgeometric.pad_images_with_params(
358+
images,
359+
pad_top,
360+
pad_bottom,
361+
pad_left,
362+
pad_right,
363+
border_mode=self.border_mode,
364+
value=self.fill,
365+
)
366+
337367
def get_params_dependent_on_data(
338368
self,
339369
params: dict[str, Any],

tests/test_core.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1032,6 +1032,8 @@ def test_images_as_target(augmentation_cls, params, as_array, shape):
10321032
A.RandomFog, A.RandomSnow, A.RandomRain, A.HEStain}:
10331033
pytest.skip(f"{augmentation_cls.__name__} is not applicable to grayscale images")
10341034

1035+
if "fill" in params and not np.isscalar(params["fill"]):
1036+
params["fill"] = params["fill"][0]
10351037

10361038
image = np.random.uniform(0, 255, shape).astype(np.float32) if augmentation_cls == A.FromFloat else np.random.randint(0, 255, shape, dtype=np.uint8)
10371039

0 commit comments

Comments
 (0)