53
53
from torchvision .transforms .v2 .functional ._utils import _get_kernel , _register_kernel_internal
54
54
55
55
56
+ # While we are working on adjusting transform functions
57
+ # for rotated and oriented bounding boxes formats,
58
+ # we limit the perimeter of tests to formats
59
+ # for which transform functions are already implemented.
60
+ # In the future, this global variable will be replaced with `list(tv_tensors.BoundingBoxFormat)`
61
+ # to support all available formats.
62
+ SUPPORTED_BOX_FORMATS = [tv_tensors .BoundingBoxFormat [x ] for x in ["XYXY" , "XYWH" , "CXCYWH" ]]
63
+ NEW_BOX_FORMATS = [tv_tensors .BoundingBoxFormat [x ] for x in ["XYWHR" , "CXCYWHR" , "XYXYXYXY" ]]
64
+
56
65
# turns all warnings into errors for this module
57
66
pytestmark = [pytest .mark .filterwarnings ("error" )]
58
67
@@ -626,7 +635,7 @@ def test_kernel_image(self, size, interpolation, use_max_size, antialias, dtype,
626
635
check_scripted_vs_eager = not isinstance (size , int ),
627
636
)
628
637
629
- @pytest .mark .parametrize ("format" , list ( tv_tensors . BoundingBoxFormat ) )
638
+ @pytest .mark .parametrize ("format" , SUPPORTED_BOX_FORMATS )
630
639
@pytest .mark .parametrize ("size" , OUTPUT_SIZES )
631
640
@pytest .mark .parametrize ("use_max_size" , [True , False ])
632
641
@pytest .mark .parametrize ("dtype" , [torch .float32 , torch .int64 ])
@@ -757,7 +766,7 @@ def _reference_resize_bounding_boxes(self, bounding_boxes, *, size, max_size=Non
757
766
new_canvas_size = (new_height , new_width ),
758
767
)
759
768
760
- @pytest .mark .parametrize ("format" , list ( tv_tensors . BoundingBoxFormat ) )
769
+ @pytest .mark .parametrize ("format" , SUPPORTED_BOX_FORMATS )
761
770
@pytest .mark .parametrize ("size" , OUTPUT_SIZES )
762
771
@pytest .mark .parametrize ("use_max_size" , [True , False ])
763
772
@pytest .mark .parametrize ("fn" , [F .resize , transform_cls_to_functional (transforms .Resize )])
@@ -1003,7 +1012,7 @@ class TestHorizontalFlip:
1003
1012
def test_kernel_image (self , dtype , device ):
1004
1013
check_kernel (F .horizontal_flip_image , make_image (dtype = dtype , device = device ))
1005
1014
1006
- @pytest .mark .parametrize ("format" , list ( tv_tensors . BoundingBoxFormat ) )
1015
+ @pytest .mark .parametrize ("format" , SUPPORTED_BOX_FORMATS )
1007
1016
@pytest .mark .parametrize ("dtype" , [torch .float32 , torch .int64 ])
1008
1017
@pytest .mark .parametrize ("device" , cpu_and_cuda ())
1009
1018
def test_kernel_bounding_boxes (self , format , dtype , device ):
@@ -1072,7 +1081,7 @@ def _reference_horizontal_flip_bounding_boxes(self, bounding_boxes):
1072
1081
1073
1082
return reference_affine_bounding_boxes_helper (bounding_boxes , affine_matrix = affine_matrix )
1074
1083
1075
- @pytest .mark .parametrize ("format" , list ( tv_tensors . BoundingBoxFormat ) )
1084
+ @pytest .mark .parametrize ("format" , SUPPORTED_BOX_FORMATS )
1076
1085
@pytest .mark .parametrize (
1077
1086
"fn" , [F .horizontal_flip , transform_cls_to_functional (transforms .RandomHorizontalFlip , p = 1 )]
1078
1087
)
@@ -1169,7 +1178,7 @@ def test_kernel_image(self, param, value, dtype, device):
1169
1178
shear = _EXHAUSTIVE_TYPE_AFFINE_KWARGS ["shear" ],
1170
1179
center = _EXHAUSTIVE_TYPE_AFFINE_KWARGS ["center" ],
1171
1180
)
1172
- @pytest .mark .parametrize ("format" , list ( tv_tensors . BoundingBoxFormat ) )
1181
+ @pytest .mark .parametrize ("format" , SUPPORTED_BOX_FORMATS )
1173
1182
@pytest .mark .parametrize ("dtype" , [torch .float32 , torch .int64 ])
1174
1183
@pytest .mark .parametrize ("device" , cpu_and_cuda ())
1175
1184
def test_kernel_bounding_boxes (self , param , value , format , dtype , device ):
@@ -1318,7 +1327,7 @@ def _reference_affine_bounding_boxes(self, bounding_boxes, *, angle, translate,
1318
1327
),
1319
1328
)
1320
1329
1321
- @pytest .mark .parametrize ("format" , list ( tv_tensors . BoundingBoxFormat ) )
1330
+ @pytest .mark .parametrize ("format" , SUPPORTED_BOX_FORMATS )
1322
1331
@pytest .mark .parametrize ("angle" , _CORRECTNESS_AFFINE_KWARGS ["angle" ])
1323
1332
@pytest .mark .parametrize ("translate" , _CORRECTNESS_AFFINE_KWARGS ["translate" ])
1324
1333
@pytest .mark .parametrize ("scale" , _CORRECTNESS_AFFINE_KWARGS ["scale" ])
@@ -1346,7 +1355,7 @@ def test_functional_bounding_boxes_correctness(self, format, angle, translate, s
1346
1355
1347
1356
torch .testing .assert_close (actual , expected )
1348
1357
1349
- @pytest .mark .parametrize ("format" , list ( tv_tensors . BoundingBoxFormat ) )
1358
+ @pytest .mark .parametrize ("format" , SUPPORTED_BOX_FORMATS )
1350
1359
@pytest .mark .parametrize ("center" , _CORRECTNESS_AFFINE_KWARGS ["center" ])
1351
1360
@pytest .mark .parametrize ("seed" , list (range (5 )))
1352
1361
def test_transform_bounding_boxes_correctness (self , format , center , seed ):
@@ -1453,7 +1462,7 @@ class TestVerticalFlip:
1453
1462
def test_kernel_image (self , dtype , device ):
1454
1463
check_kernel (F .vertical_flip_image , make_image (dtype = dtype , device = device ))
1455
1464
1456
- @pytest .mark .parametrize ("format" , list ( tv_tensors . BoundingBoxFormat ) )
1465
+ @pytest .mark .parametrize ("format" , SUPPORTED_BOX_FORMATS )
1457
1466
@pytest .mark .parametrize ("dtype" , [torch .float32 , torch .int64 ])
1458
1467
@pytest .mark .parametrize ("device" , cpu_and_cuda ())
1459
1468
def test_kernel_bounding_boxes (self , format , dtype , device ):
@@ -1520,7 +1529,7 @@ def _reference_vertical_flip_bounding_boxes(self, bounding_boxes):
1520
1529
1521
1530
return reference_affine_bounding_boxes_helper (bounding_boxes , affine_matrix = affine_matrix )
1522
1531
1523
- @pytest .mark .parametrize ("format" , list ( tv_tensors . BoundingBoxFormat ) )
1532
+ @pytest .mark .parametrize ("format" , SUPPORTED_BOX_FORMATS )
1524
1533
@pytest .mark .parametrize ("fn" , [F .vertical_flip , transform_cls_to_functional (transforms .RandomVerticalFlip , p = 1 )])
1525
1534
def test_bounding_boxes_correctness (self , format , fn ):
1526
1535
bounding_boxes = make_bounding_boxes (format = format )
@@ -1589,7 +1598,7 @@ def test_kernel_image(self, param, value, dtype, device):
1589
1598
expand = [False , True ],
1590
1599
center = _EXHAUSTIVE_TYPE_AFFINE_KWARGS ["center" ],
1591
1600
)
1592
- @pytest .mark .parametrize ("format" , list ( tv_tensors . BoundingBoxFormat ) )
1601
+ @pytest .mark .parametrize ("format" , SUPPORTED_BOX_FORMATS )
1593
1602
@pytest .mark .parametrize ("dtype" , [torch .float32 , torch .uint8 ])
1594
1603
@pytest .mark .parametrize ("device" , cpu_and_cuda ())
1595
1604
def test_kernel_bounding_boxes (self , param , value , format , dtype , device ):
@@ -1760,7 +1769,7 @@ def _reference_rotate_bounding_boxes(self, bounding_boxes, *, angle, expand, cen
1760
1769
bounding_boxes
1761
1770
)
1762
1771
1763
- @pytest .mark .parametrize ("format" , list ( tv_tensors . BoundingBoxFormat ) )
1772
+ @pytest .mark .parametrize ("format" , SUPPORTED_BOX_FORMATS )
1764
1773
@pytest .mark .parametrize ("angle" , _CORRECTNESS_AFFINE_KWARGS ["angle" ])
1765
1774
@pytest .mark .parametrize ("expand" , [False , True ])
1766
1775
@pytest .mark .parametrize ("center" , _CORRECTNESS_AFFINE_KWARGS ["center" ])
@@ -1773,7 +1782,7 @@ def test_functional_bounding_boxes_correctness(self, format, angle, expand, cent
1773
1782
torch .testing .assert_close (actual , expected )
1774
1783
torch .testing .assert_close (F .get_size (actual ), F .get_size (expected ), atol = 2 if expand else 0 , rtol = 0 )
1775
1784
1776
- @pytest .mark .parametrize ("format" , list ( tv_tensors . BoundingBoxFormat ) )
1785
+ @pytest .mark .parametrize ("format" , SUPPORTED_BOX_FORMATS )
1777
1786
@pytest .mark .parametrize ("expand" , [False , True ])
1778
1787
@pytest .mark .parametrize ("center" , _CORRECTNESS_AFFINE_KWARGS ["center" ])
1779
1788
@pytest .mark .parametrize ("seed" , list (range (5 )))
@@ -2694,7 +2703,7 @@ def test_kernel_image(self, param, value, dtype, device):
2694
2703
check_cuda_vs_cpu = dtype is not torch .float16 ,
2695
2704
)
2696
2705
2697
- @pytest .mark .parametrize ("format" , list ( tv_tensors . BoundingBoxFormat ) )
2706
+ @pytest .mark .parametrize ("format" , SUPPORTED_BOX_FORMATS )
2698
2707
@pytest .mark .parametrize ("dtype" , [torch .float32 , torch .int64 ])
2699
2708
@pytest .mark .parametrize ("device" , cpu_and_cuda ())
2700
2709
def test_kernel_bounding_boxes (self , format , dtype , device ):
@@ -2821,7 +2830,7 @@ def test_kernel_image(self, kwargs, dtype, device):
2821
2830
check_kernel (F .crop_image , make_image (self .INPUT_SIZE , dtype = dtype , device = device ), ** kwargs )
2822
2831
2823
2832
@pytest .mark .parametrize ("kwargs" , CORRECTNESS_CROP_KWARGS )
2824
- @pytest .mark .parametrize ("format" , list ( tv_tensors . BoundingBoxFormat ) )
2833
+ @pytest .mark .parametrize ("format" , SUPPORTED_BOX_FORMATS )
2825
2834
@pytest .mark .parametrize ("dtype" , [torch .float32 , torch .int64 ])
2826
2835
@pytest .mark .parametrize ("device" , cpu_and_cuda ())
2827
2836
def test_kernel_bounding_box (self , kwargs , format , dtype , device ):
@@ -2971,7 +2980,7 @@ def _reference_crop_bounding_boxes(self, bounding_boxes, *, top, left, height, w
2971
2980
)
2972
2981
2973
2982
@pytest .mark .parametrize ("kwargs" , CORRECTNESS_CROP_KWARGS )
2974
- @pytest .mark .parametrize ("format" , list ( tv_tensors . BoundingBoxFormat ) )
2983
+ @pytest .mark .parametrize ("format" , SUPPORTED_BOX_FORMATS )
2975
2984
@pytest .mark .parametrize ("dtype" , [torch .float32 , torch .int64 ])
2976
2985
@pytest .mark .parametrize ("device" , cpu_and_cuda ())
2977
2986
def test_functional_bounding_box_correctness (self , kwargs , format , dtype , device ):
@@ -2984,7 +2993,7 @@ def test_functional_bounding_box_correctness(self, kwargs, format, dtype, device
2984
2993
assert_equal (F .get_size (actual ), F .get_size (expected ))
2985
2994
2986
2995
@pytest .mark .parametrize ("output_size" , [(17 , 11 ), (11 , 17 ), (11 , 11 )])
2987
- @pytest .mark .parametrize ("format" , list ( tv_tensors . BoundingBoxFormat ) )
2996
+ @pytest .mark .parametrize ("format" , SUPPORTED_BOX_FORMATS )
2988
2997
@pytest .mark .parametrize ("dtype" , [torch .float32 , torch .int64 ])
2989
2998
@pytest .mark .parametrize ("device" , cpu_and_cuda ())
2990
2999
@pytest .mark .parametrize ("seed" , list (range (5 )))
@@ -3507,7 +3516,8 @@ def test_aug_mix_severity_error(self, severity):
3507
3516
3508
3517
3509
3518
class TestConvertBoundingBoxFormat :
3510
- old_new_formats = list (itertools .permutations (iter (tv_tensors .BoundingBoxFormat ), 2 ))
3519
+ old_new_formats = list (itertools .permutations (SUPPORTED_BOX_FORMATS , 2 ))
3520
+ old_new_formats += list (itertools .permutations (NEW_BOX_FORMATS , 2 ))
3511
3521
3512
3522
@pytest .mark .parametrize (("old_format" , "new_format" ), old_new_formats )
3513
3523
def test_kernel (self , old_format , new_format ):
@@ -3518,7 +3528,7 @@ def test_kernel(self, old_format, new_format):
3518
3528
old_format = old_format ,
3519
3529
)
3520
3530
3521
- @pytest .mark .parametrize ("format" , list ( tv_tensors . BoundingBoxFormat ) )
3531
+ @pytest .mark .parametrize ("format" , SUPPORTED_BOX_FORMATS )
3522
3532
@pytest .mark .parametrize ("inplace" , [False , True ])
3523
3533
def test_kernel_noop (self , format , inplace ):
3524
3534
input = make_bounding_boxes (format = format ).as_subclass (torch .Tensor )
@@ -3542,9 +3552,13 @@ def test_kernel_inplace(self, old_format, new_format):
3542
3552
output_inplace = F .convert_bounding_box_format (
3543
3553
input , old_format = old_format , new_format = new_format , inplace = True
3544
3554
)
3545
- assert output_inplace .data_ptr () == input .data_ptr ()
3546
- assert output_inplace ._version > input_version
3547
- assert output_inplace is input
3555
+ if old_format != tv_tensors .BoundingBoxFormat .XYXYXYXY and new_format != tv_tensors .BoundingBoxFormat .XYXYXYXY :
3556
+ # NOTE: BoundingBox format conversion from and to XYXYXYXY format
3557
+ # cannot modify the input tensor inplace as it requires a dimension
3558
+ # change.
3559
+ assert output_inplace .data_ptr () == input .data_ptr ()
3560
+ assert output_inplace ._version > input_version
3561
+ assert output_inplace is input
3548
3562
3549
3563
assert_equal (output_inplace , output_out_of_place )
3550
3564
@@ -3563,7 +3577,7 @@ def test_transform(self, old_format, new_format, format_type):
3563
3577
@pytest .mark .parametrize (("old_format" , "new_format" ), old_new_formats )
3564
3578
def test_strings (self , old_format , new_format ):
3565
3579
# Non-regression test for https://github.com/pytorch/vision/issues/8258
3566
- input = tv_tensors . BoundingBoxes ( torch . tensor ([[ 10 , 10 , 20 , 20 ]]), format = old_format , canvas_size = (50 , 50 ))
3580
+ input = make_bounding_boxes ( format = old_format , canvas_size = (50 , 50 ))
3567
3581
expected = self ._reference_convert_bounding_box_format (input , new_format )
3568
3582
3569
3583
old_format = old_format .name
@@ -3728,7 +3742,7 @@ def _reference_resized_crop_bounding_boxes(self, bounding_boxes, *, top, left, h
3728
3742
new_canvas_size = size ,
3729
3743
)
3730
3744
3731
- @pytest .mark .parametrize ("format" , list ( tv_tensors . BoundingBoxFormat ) )
3745
+ @pytest .mark .parametrize ("format" , SUPPORTED_BOX_FORMATS )
3732
3746
def test_functional_bounding_boxes_correctness (self , format ):
3733
3747
bounding_boxes = make_bounding_boxes (self .INPUT_SIZE , format = format )
3734
3748
@@ -3796,7 +3810,7 @@ def test_kernel_image(self, param, value, dtype, device):
3796
3810
),
3797
3811
)
3798
3812
3799
- @pytest .mark .parametrize ("format" , list ( tv_tensors . BoundingBoxFormat ) )
3813
+ @pytest .mark .parametrize ("format" , SUPPORTED_BOX_FORMATS )
3800
3814
def test_kernel_bounding_boxes (self , format ):
3801
3815
bounding_boxes = make_bounding_boxes (format = format )
3802
3816
check_kernel (
@@ -3915,7 +3929,7 @@ def _reference_pad_bounding_boxes(self, bounding_boxes, *, padding):
3915
3929
)
3916
3930
3917
3931
@pytest .mark .parametrize ("padding" , CORRECTNESS_PADDINGS )
3918
- @pytest .mark .parametrize ("format" , list ( tv_tensors . BoundingBoxFormat ) )
3932
+ @pytest .mark .parametrize ("format" , SUPPORTED_BOX_FORMATS )
3919
3933
@pytest .mark .parametrize ("dtype" , [torch .int64 , torch .float32 ])
3920
3934
@pytest .mark .parametrize ("device" , cpu_and_cuda ())
3921
3935
@pytest .mark .parametrize ("fn" , [F .pad , transform_cls_to_functional (transforms .Pad )])
@@ -3944,7 +3958,7 @@ def test_kernel_image(self, output_size, dtype, device):
3944
3958
)
3945
3959
3946
3960
@pytest .mark .parametrize ("output_size" , OUTPUT_SIZES )
3947
- @pytest .mark .parametrize ("format" , list ( tv_tensors . BoundingBoxFormat ) )
3961
+ @pytest .mark .parametrize ("format" , SUPPORTED_BOX_FORMATS )
3948
3962
def test_kernel_bounding_boxes (self , output_size , format ):
3949
3963
bounding_boxes = make_bounding_boxes (self .INPUT_SIZE , format = format )
3950
3964
check_kernel (
@@ -4023,7 +4037,7 @@ def _reference_center_crop_bounding_boxes(self, bounding_boxes, output_size):
4023
4037
)
4024
4038
4025
4039
@pytest .mark .parametrize ("output_size" , OUTPUT_SIZES )
4026
- @pytest .mark .parametrize ("format" , list ( tv_tensors . BoundingBoxFormat ) )
4040
+ @pytest .mark .parametrize ("format" , SUPPORTED_BOX_FORMATS )
4027
4041
@pytest .mark .parametrize ("dtype" , [torch .int64 , torch .float32 ])
4028
4042
@pytest .mark .parametrize ("device" , cpu_and_cuda ())
4029
4043
@pytest .mark .parametrize ("fn" , [F .center_crop , transform_cls_to_functional (transforms .CenterCrop )])
@@ -4090,7 +4104,7 @@ def test_kernel_image_error(self):
4090
4104
coefficients = COEFFICIENTS ,
4091
4105
start_end_points = START_END_POINTS ,
4092
4106
)
4093
- @pytest .mark .parametrize ("format" , list ( tv_tensors . BoundingBoxFormat ) )
4107
+ @pytest .mark .parametrize ("format" , SUPPORTED_BOX_FORMATS )
4094
4108
def test_kernel_bounding_boxes (self , param , value , format ):
4095
4109
if param == "start_end_points" :
4096
4110
kwargs = dict (zip (["startpoints" , "endpoints" ], value ))
@@ -4266,7 +4280,7 @@ def perspective_bounding_boxes(bounding_boxes):
4266
4280
)
4267
4281
4268
4282
@pytest .mark .parametrize (("startpoints" , "endpoints" ), START_END_POINTS )
4269
- @pytest .mark .parametrize ("format" , list ( tv_tensors . BoundingBoxFormat ) )
4283
+ @pytest .mark .parametrize ("format" , SUPPORTED_BOX_FORMATS )
4270
4284
@pytest .mark .parametrize ("dtype" , [torch .int64 , torch .float32 ])
4271
4285
@pytest .mark .parametrize ("device" , cpu_and_cuda ())
4272
4286
def test_correctness_perspective_bounding_boxes (self , startpoints , endpoints , format , dtype , device ):
@@ -4473,7 +4487,7 @@ def test_correctness_image(self, mean, std, dtype, fn):
4473
4487
4474
4488
4475
4489
class TestClampBoundingBoxes :
4476
- @pytest .mark .parametrize ("format" , list ( tv_tensors . BoundingBoxFormat ) )
4490
+ @pytest .mark .parametrize ("format" , SUPPORTED_BOX_FORMATS )
4477
4491
@pytest .mark .parametrize ("dtype" , [torch .int64 , torch .float32 ])
4478
4492
@pytest .mark .parametrize ("device" , cpu_and_cuda ())
4479
4493
def test_kernel (self , format , dtype , device ):
@@ -4485,7 +4499,7 @@ def test_kernel(self, format, dtype, device):
4485
4499
canvas_size = bounding_boxes .canvas_size ,
4486
4500
)
4487
4501
4488
- @pytest .mark .parametrize ("format" , list ( tv_tensors . BoundingBoxFormat ) )
4502
+ @pytest .mark .parametrize ("format" , SUPPORTED_BOX_FORMATS )
4489
4503
def test_functional (self , format ):
4490
4504
check_functional (F .clamp_bounding_boxes , make_bounding_boxes (format = format ))
4491
4505
0 commit comments