|
58 | 58 |
|
59 | 59 | # %% |
60 | 60 | # Rotation |
61 | | -# -------------- |
| 61 | +# -------- |
| 62 | +# Rotated bounding boxes maintain their rotation with respect to the image even |
| 63 | +# when the image itself is rotated through the |
| 64 | +# :class:`~torchvision.transforms.RandomRotation` transform. |
62 | 65 | rotater = v2.RandomRotation(degrees=(0, 180), expand=True) |
63 | 66 | rotated_imgs = [rotater((orig_img, orig_box)) for _ in range(4)] |
64 | 67 | plot([(orig_img, orig_box)] + rotated_imgs, bbox_width=10) |
65 | 68 |
|
66 | 69 | # %% |
67 | 70 | # Padding |
68 | | -# ------------- |
69 | | -# The rotated bounding boxes also respect padding transforms. |
| 71 | +# ------- |
| 72 | +# Rotated bounding boxes also maintain their properties when the image is padded using |
| 73 | +# :class:`~torchvision.transforms.Pad`. |
70 | 74 | padded_imgs_and_boxes = [ |
71 | 75 | v2.Pad(padding=padding)(orig_img, orig_box) |
72 | 76 | for padding in (30, 50, 100, 200) |
|
75 | 79 |
|
76 | 80 | # %% |
77 | 81 | # Resizing |
78 | | -# -------------- |
79 | | -# Note that the bounding box looking bigger in the small images is an artifact, |
80 | | -# not reality. It is due to the the fact that we specify a fixed-size for the |
81 | | -# width of the lines to draw. When the image is, say, only 30 pixels wide, a |
82 | | -# line that is 3 pixels wide is relatively large. We could potentially try to |
83 | | -# tweak the plotting function to avoid this appearance. |
| 82 | +# -------- |
| 83 | +# Rotated bounding boxes are also resized along with an image in the |
| 84 | +# :class:`~torchvision.transforms.Resize` transform. |
| 85 | +# |
| 86 | +# Note that the bounding box looking bigger in the images with less pixels is |
| 87 | +# an artifact, not reality. That is merely the rasterised representation of the |
| 88 | +# bounding box's boundaries appearing bigger because we specify a fixed width of |
| 89 | +# that rasterized line. When the image is, say, only 30 pixels wide, a |
| 90 | +# line that is 3 pixels wide is relatively large. |
84 | 91 | resized_imgs = [ |
85 | 92 | v2.Resize(size=size)(orig_img, orig_box) |
86 | 93 | for size in (30, 50, 100, orig_img.size) |
87 | 94 | ] |
88 | | -plot([(orig_img, orig_box)] + resized_imgs, bbox_width=3) |
| 95 | +plot([(orig_img, orig_box)] + resized_imgs, bbox_width=5) |
89 | 96 |
|
90 | 97 | # %% |
91 | 98 | # Perspective |
92 | 99 | # ----------- |
| 100 | +# The rotated bounding box is also transformed along with the image when the |
| 101 | +# perspective is transformed with :class:`~torchvision.transforms.RandomPerspective`. |
93 | 102 | perspective_transformer = v2.RandomPerspective(distortion_scale=0.6, p=1.0) |
94 | 103 | perspective_imgs = [perspective_transformer(orig_img, orig_box) for _ in range(4)] |
95 | 104 | plot([(orig_img, orig_box)] + perspective_imgs, bbox_width=10) |
96 | 105 |
|
97 | 106 | # %% |
98 | 107 | # Elastic Transform |
99 | 108 | # ----------------- |
| 109 | +# The rotated bounding box is appropriately unchanged when going through the |
| 110 | +# :class:`~torchvision.transforms.ElasticTransform`. |
100 | 111 | elastic_imgs = [ |
101 | 112 | v2.ElasticTransform(alpha=alpha)(orig_img, orig_box) |
102 | 113 | for alpha in (100.0, 500.0, 1000.0, 2000.0) |
|
106 | 117 | # %% |
107 | 118 | # Crop & Clamping Modes |
108 | 119 | # --------------------- |
109 | | -# This section doubles as the example for Crop and for explaining clamping |
110 | | -# modes. My rationale for doing at both at once: any meaningful examples for |
111 | | -# cropping are going to impact the bounding box, and the only way to make |
112 | | -# sense of that is to also explain clamping modes. We should cover: |
| 120 | +# The :class:`~torchvision.transforms.CenterCrop` transform selectively crops |
| 121 | +# the image on a center location. The behavior of the rotated bounding box |
| 122 | +# depends on its `clamping_mode`. We can set the `clamping_mode` in the |
| 123 | +# :class:`~torchvision.tv_tensors.BoundingBoxes` constructur, or by directly |
| 124 | +# setting it after construction as we do in the example below. |
| 125 | +# |
| 126 | +# There are two values for `clamping_mode`: |
| 127 | +# |
| 128 | +# - `"soft"`: The default when constucting |
| 129 | +# :class:`~torchvision.tv_tensors.BoundingBoxes`. <Insert semantic |
| 130 | +# description for soft mode.> |
| 131 | +# - `"hard"`: <Insert semantic description for hard mode.> |
| 132 | +# |
| 133 | +# For standard bounding boxes, both modes behave the same. We also need to |
| 134 | +# document: |
| 135 | +# |
| 136 | +# - `clamping_mode` for individual kernels. |
| 137 | +# - `clamping_mode` in :class:`~torchvision.transforms.v2.ClampBoundingBoxes`. |
| 138 | +# - the new :class:`~torchvision.transforms.v2.SetClampingMode` transform. |
113 | 139 | # |
114 | | -# * Clamping mode kinds: hard, soft, None. Behavior of each, when to use them. |
115 | | -# * Clamping mode defaults for: bounding boxes, functionals, transforms in |
116 | | -# general, ClampingBoundingBoxes() specifically. |
117 | 140 | assert orig_box.clamping_mode == "soft" |
118 | 141 | hard_box = orig_box.clone() |
119 | 142 | hard_box.clamping_mode = "hard" |
|
0 commit comments