@@ -317,7 +317,7 @@ def _compute_expected_bbox(bbox, angle_, translate_, scale_, shear_, center_):
317
317
[bbox_xyxy [2 ].item (), bbox_xyxy [3 ].item (), 1.0 ],
318
318
]
319
319
)
320
- transformed_points = points @ true_matrix .T
320
+ transformed_points = np . matmul ( points , true_matrix .T )
321
321
out_bbox = [
322
322
np .min (transformed_points [:, 0 ]),
323
323
np .min (transformed_points [:, 1 ]),
@@ -371,3 +371,53 @@ def _compute_expected_bbox(bbox, angle_, translate_, scale_, shear_, center_):
371
371
expected_bboxes = expected_bboxes .squeeze (0 )
372
372
373
373
torch .testing .assert_close (output_bboxes , expected_bboxes )
374
+
375
+
376
+ def test_correctness_affine_bounding_box_on_fixed_input ():
377
+ # Check transformation against known expected output
378
+ image_size = (64 , 64 )
379
+ # xyxy format
380
+ in_boxes = [
381
+ [20 , 25 , 35 , 45 ],
382
+ [50 , 5 , 70 , 22 ],
383
+ [image_size [1 ] // 2 - 10 , image_size [0 ] // 2 - 10 , image_size [1 ] // 2 + 10 , image_size [0 ] // 2 + 10 ],
384
+ [1 , 1 , 5 , 5 ],
385
+ ]
386
+ in_boxes = features .BoundingBox (
387
+ in_boxes , format = features .BoundingBoxFormat .XYXY , image_size = image_size , dtype = torch .float64
388
+ )
389
+ # Tested parameters
390
+ angle = 63
391
+ scale = 0.89
392
+ dx = 0.12
393
+ dy = 0.23
394
+
395
+ # Expected bboxes computed using albumentations:
396
+ # from albumentations.augmentations.geometric.functional import bbox_shift_scale_rotate
397
+ # from albumentations.augmentations.geometric.functional import normalize_bbox, denormalize_bbox
398
+ # expected_bboxes = []
399
+ # for in_box in in_boxes:
400
+ # n_in_box = normalize_bbox(in_box, *image_size)
401
+ # n_out_box = bbox_shift_scale_rotate(n_in_box, -angle, scale, dx, dy, *image_size)
402
+ # out_box = denormalize_bbox(n_out_box, *image_size)
403
+ # expected_bboxes.append(out_box)
404
+ expected_bboxes = [
405
+ (24.522435977922218 , 34.375689508290854 , 46.443125279998114 , 54.3516575015695 ),
406
+ (54.88288587110401 , 50.08453280875634 , 76.44484547743795 , 72.81332520036864 ),
407
+ (27.709526487041554 , 34.74952648704156 , 51.650473512958435 , 58.69047351295844 ),
408
+ (48.56528888843238 , 9.611532109828834 , 53.35347829361575 , 14.39972151501221 ),
409
+ ]
410
+
411
+ output_boxes = F .affine_bounding_box (
412
+ in_boxes ,
413
+ in_boxes .format ,
414
+ in_boxes .image_size ,
415
+ angle ,
416
+ (dx * image_size [1 ], dy * image_size [0 ]),
417
+ scale ,
418
+ shear = (0 , 0 ),
419
+ )
420
+
421
+ assert len (output_boxes ) == len (expected_bboxes )
422
+ for a_out_box , out_box in zip (expected_bboxes , output_boxes ):
423
+ np .testing .assert_allclose (out_box .cpu ().numpy (), a_out_box )
0 commit comments