Skip to content

Feat: add item_transform_random_perspective for detection and segmentation items - #393

Merged
cregouby merged 13 commits into
mlverse:mainfrom
DerrickUnleashed:feat/randomPerspective
Aug 26, 2026
Merged

Feat: add item_transform_random_perspective for detection and segmentation items#393
cregouby merged 13 commits into
mlverse:mainfrom
DerrickUnleashed:feat/randomPerspective

Conversation

@DerrickUnleashed

@DerrickUnleashed DerrickUnleashed commented Aug 24, 2026

Copy link
Copy Markdown
Contributor
url <- "https://upload.wikimedia.org/wikipedia/commons/b/b6/Felis_catus-cat_on_snow.jpg"

# ========== 1. DETECTION ITEM ==========
img <- base_loader(url) |> transform_to_tensor()
boxes <- torch_tensor(matrix(c(600, 200, 2880, 1860), ncol = 4), dtype = torch_float32())
det_item <- list(x = img, y = list(boxes = boxes, labels = "CAT"))
class(det_item) <- c("image_with_bounding_box", "list")

det_persp <- item_transform_random_perspective(det_item, p = 1)

p1 <- draw_bounding_boxes(det_item, colors = "blue", width = 10)$to(torch_float())$div(255)
p2 <- draw_bounding_boxes(det_persp, colors = "red", width = 10)$to(torch_float())$div(255)
grid1 <- vision_make_grid(torch_stack(list(p1, p2)), scale = TRUE)
tensor_image_browse(grid1)

# ========== 2. DETECTION DATASET ==========
ds_det <- pascal_detection_dataset(year = "2007", split = "trainval",
                                   transform = transform_to_tensor, download = TRUE)
orig_det <- ds_det[1]
ds_det_persp <- item_transform_random_perspective(ds_det, p = 1)
persp_det <- ds_det_persp[1]

p3 <- draw_bounding_boxes(orig_det, colors = "blue", width = 5)$to(torch_float())$div(255)
p4 <- draw_bounding_boxes(persp_det, colors = "red", width = 5)$to(torch_float())$div(255)
grid2 <- vision_make_grid(torch_stack(list(p3, p4)), scale = TRUE)
tensor_image_browse(grid2)

# ========== 3. SEGMENTATION ITEM ==========
img2 <- base_loader(url) |> transform_to_tensor()
h <- img2$shape[2]; w <- img2$shape[3]

mask1 <- torch_zeros(h, w, dtype = torch_bool()); mask1[, 1:150] <- TRUE
mask2 <- torch_zeros(h, w, dtype = torch_bool()); mask2[, 350:500] <- TRUE
masks <- torch_stack(list(mask1, mask2))
seg_item <- list(x = img2, y = list(masks = masks, labels = torch_tensor(c(1L, 2L)),
                                    image_height = h, image_width = w))
class(seg_item) <- c("image_with_segmentation_mask", "list")

seg_persp <- item_transform_random_perspective(seg_item, p = 1)

p5 <- draw_segmentation_masks(seg_item, alpha = 0.5, colors = c("red", "blue"))$to(torch_float())$div(255)
p6 <- draw_segmentation_masks(seg_persp, alpha = 0.5, colors = c("red", "blue"))$to(torch_float())$div(255)
grid3 <- vision_make_grid(torch_stack(list(p5, p6)), scale = TRUE)
tensor_image_browse(grid3)

# ========== 4. SEGMENTATION DATASET ==========
ds_seg <- pascal_segmentation_dataset(year = "2007", split = "trainval",
                                      transform = transform_to_tensor, download = TRUE)
orig_seg <- ds_seg[1]
ds_seg_persp <- item_transform_random_perspective(ds_seg, p = 1)
persp_seg <- ds_seg_persp[1]

p7 <- draw_segmentation_masks(orig_seg, alpha = 0.5)$to(torch_float())$div(255)
p8 <- draw_segmentation_masks(persp_seg, alpha = 0.5)$to(torch_float())$div(255)
grid4 <- vision_make_grid(torch_stack(list(p7, p8)), scale = TRUE)
tensor_image_browse(grid4)

DETECTION ITEM

file134f7407c63ea

DETECTION DATASET

file134f72683b8b9

SEGMENTATION ITEM

file134f711d48d70

SEGMENTATION DATASET

file134f71991bd35

Closes #359

Implements random perspective transformation for dataset items,
matching the pattern of item_transform_random_horizontal_flip().
Supports image_with_bounding_box, image_with_segmentation_mask,
and image_with_rotated_box item types, plus dataset wrapping.
Covers rejection of non-items, p=0/p=1 behavior, segmentation,
rotated boxes, defaults, label preservation, non-mutation, and
dataset wrapping.
…eferences

Generated via devtools::document(). Adds @Seealso links to the new
function in existing item_random_transforms family pages.
Generic, detection, and segmentation test blocks replace the 13
individual tests. Fix non-mutation check to use p=0 (p=1 mutates).
@DerrickUnleashed
DerrickUnleashed marked this pull request as ready for review August 24, 2026 07:19

@cregouby cregouby left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

praise Great addition, Thanks !

Comment thread R/item-transforms-random-geometry.R Outdated
Comment thread R/item-transforms-random-geometry.R Outdated
Comment thread R/item-transforms-random-geometry.R Outdated
Comment thread R/item-transforms-random-geometry.R Outdated
Comment thread R/item-transforms-random-geometry.R Outdated
Comment thread R/item-transforms-random-geometry.R Outdated
@cregouby
cregouby merged commit e5d4991 into mlverse:main Aug 26, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add item_transform_random_perspective

2 participants