|
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