@@ -522,7 +522,7 @@ def resize_bounding_boxes(
522522 size : Optional [list [int ]],
523523 max_size : Optional [int ] = None ,
524524 format : tv_tensors .BoundingBoxFormat = tv_tensors .BoundingBoxFormat .XYXY ,
525- clamping_mode : CLAMPING_MODE_TYPE = "hard" , # TODOBB soft
525+ clamping_mode : CLAMPING_MODE_TYPE = "soft" ,
526526) -> tuple [torch .Tensor , tuple [int , int ]]:
527527 # We set the default format as `tv_tensors.BoundingBoxFormat.XYXY`
528528 # to ensure backward compatibility.
@@ -1108,15 +1108,16 @@ def _affine_bounding_boxes_with_expand(
11081108 shear : list [float ],
11091109 center : Optional [list [float ]] = None ,
11101110 expand : bool = False ,
1111- clamping_mode : CLAMPING_MODE_TYPE = "hard" , # TODOBB soft
1111+ clamping_mode : CLAMPING_MODE_TYPE = "soft" ,
11121112) -> tuple [torch .Tensor , tuple [int , int ]]:
11131113 if bounding_boxes .numel () == 0 :
11141114 return bounding_boxes , canvas_size
11151115
11161116 original_shape = bounding_boxes .shape
11171117 dtype = bounding_boxes .dtype
1118- need_cast = not bounding_boxes .is_floating_point ()
1119- bounding_boxes = bounding_boxes .float () if need_cast else bounding_boxes .clone ()
1118+ acceptable_dtypes = [torch .float64 ] # Ensure consistency between CPU and GPU.
1119+ need_cast = dtype not in acceptable_dtypes
1120+ bounding_boxes = bounding_boxes .to (torch .float64 ) if need_cast else bounding_boxes .clone ()
11201121 device = bounding_boxes .device
11211122 is_rotated = tv_tensors .is_rotated_bounding_format (format )
11221123 intermediate_format = tv_tensors .BoundingBoxFormat .XYXYXYXY if is_rotated else tv_tensors .BoundingBoxFormat .XYXY
@@ -1210,7 +1211,7 @@ def affine_bounding_boxes(
12101211 scale : float ,
12111212 shear : list [float ],
12121213 center : Optional [list [float ]] = None ,
1213- clamping_mode : CLAMPING_MODE_TYPE = "hard" , # TODOBB soft
1214+ clamping_mode : CLAMPING_MODE_TYPE = "soft" ,
12141215) -> torch .Tensor :
12151216 out_box , _ = _affine_bounding_boxes_with_expand (
12161217 bounding_boxes ,
@@ -1448,6 +1449,7 @@ def rotate_bounding_boxes(
14481449 angle : float ,
14491450 expand : bool = False ,
14501451 center : Optional [list [float ]] = None ,
1452+ clamping_mode : CLAMPING_MODE_TYPE = "soft" ,
14511453) -> tuple [torch .Tensor , tuple [int , int ]]:
14521454 return _affine_bounding_boxes_with_expand (
14531455 bounding_boxes ,
@@ -1459,6 +1461,7 @@ def rotate_bounding_boxes(
14591461 shear = [0.0 , 0.0 ],
14601462 center = center ,
14611463 expand = expand ,
1464+ clamping_mode = clamping_mode ,
14621465 )
14631466
14641467
@@ -1473,6 +1476,7 @@ def _rotate_bounding_boxes_dispatch(
14731476 angle = angle ,
14741477 expand = expand ,
14751478 center = center ,
1479+ clamping_mode = inpt .clamping_mode ,
14761480 )
14771481 return tv_tensors .wrap (output , like = inpt , canvas_size = canvas_size )
14781482
@@ -1739,7 +1743,7 @@ def pad_bounding_boxes(
17391743 canvas_size : tuple [int , int ],
17401744 padding : list [int ],
17411745 padding_mode : str = "constant" ,
1742- clamping_mode : CLAMPING_MODE_TYPE = "hard" , # TODOBB soft
1746+ clamping_mode : CLAMPING_MODE_TYPE = "soft" ,
17431747) -> tuple [torch .Tensor , tuple [int , int ]]:
17441748 if padding_mode not in ["constant" ]:
17451749 # TODO: add support of other padding modes
@@ -1857,7 +1861,7 @@ def crop_bounding_boxes(
18571861 left : int ,
18581862 height : int ,
18591863 width : int ,
1860- clamping_mode : CLAMPING_MODE_TYPE = "hard" , # TODOBB soft
1864+ clamping_mode : CLAMPING_MODE_TYPE = "soft" ,
18611865) -> tuple [torch .Tensor , tuple [int , int ]]:
18621866
18631867 # Crop or implicit pad if left and/or top have negative values:
@@ -2097,7 +2101,7 @@ def perspective_bounding_boxes(
20972101 startpoints : Optional [list [list [int ]]],
20982102 endpoints : Optional [list [list [int ]]],
20992103 coefficients : Optional [list [float ]] = None ,
2100- clamping_mode : CLAMPING_MODE_TYPE = "hard" , # TODOBB soft
2104+ clamping_mode : CLAMPING_MODE_TYPE = "soft" ,
21012105) -> torch .Tensor :
21022106 if bounding_boxes .numel () == 0 :
21032107 return bounding_boxes
@@ -2412,7 +2416,7 @@ def elastic_bounding_boxes(
24122416 format : tv_tensors .BoundingBoxFormat ,
24132417 canvas_size : tuple [int , int ],
24142418 displacement : torch .Tensor ,
2415- clamping_mode : CLAMPING_MODE_TYPE = "hard" , # TODOBB soft
2419+ clamping_mode : CLAMPING_MODE_TYPE = "soft" ,
24162420) -> torch .Tensor :
24172421 expected_shape = (1 , canvas_size [0 ], canvas_size [1 ], 2 )
24182422 if not isinstance (displacement , torch .Tensor ):
@@ -2433,19 +2437,19 @@ def elastic_bounding_boxes(
24332437
24342438 original_shape = bounding_boxes .shape
24352439 # TODO: first cast to float if bbox is int64 before convert_bounding_box_format
2436- intermediate_format = tv_tensors .BoundingBoxFormat .XYXYXYXY if is_rotated else tv_tensors .BoundingBoxFormat .XYXY
2440+ intermediate_format = tv_tensors .BoundingBoxFormat .CXCYWHR if is_rotated else tv_tensors .BoundingBoxFormat .XYXY
24372441
24382442 bounding_boxes = (
24392443 convert_bounding_box_format (bounding_boxes .clone (), old_format = format , new_format = intermediate_format )
2440- ).reshape (- 1 , 8 if is_rotated else 4 )
2444+ ).reshape (- 1 , 5 if is_rotated else 4 )
24412445
24422446 id_grid = _create_identity_grid (canvas_size , device = device , dtype = dtype )
24432447 # We construct an approximation of inverse grid as inv_grid = id_grid - displacement
24442448 # This is not an exact inverse of the grid
24452449 inv_grid = id_grid .sub_ (displacement )
24462450
24472451 # Get points from bboxes
2448- points = bounding_boxes if is_rotated else bounding_boxes [:, [[0 , 1 ], [2 , 1 ], [2 , 3 ], [0 , 3 ]]]
2452+ points = bounding_boxes [:, : 2 ] if is_rotated else bounding_boxes [:, [[0 , 1 ], [2 , 1 ], [2 , 3 ], [0 , 3 ]]]
24492453 points = points .reshape (- 1 , 2 )
24502454 if points .is_floating_point ():
24512455 points = points .ceil_ ()
@@ -2457,8 +2461,8 @@ def elastic_bounding_boxes(
24572461 transformed_points = inv_grid [0 , index_y , index_x , :].add_ (1 ).mul_ (0.5 * t_size ).sub_ (0.5 )
24582462
24592463 if is_rotated :
2460- transformed_points = transformed_points .reshape (- 1 , 8 )
2461- out_bboxes = _parallelogram_to_bounding_boxes ( transformed_points ).to (bounding_boxes .dtype )
2464+ transformed_points = transformed_points .reshape (- 1 , 2 )
2465+ out_bboxes = torch . cat ([ transformed_points , bounding_boxes [:, 2 :]], dim = 1 ).to (bounding_boxes .dtype )
24622466 else :
24632467 transformed_points = transformed_points .reshape (- 1 , 4 , 2 )
24642468 out_bbox_mins , out_bbox_maxs = torch .aminmax (transformed_points , dim = 1 )
@@ -2619,11 +2623,18 @@ def center_crop_bounding_boxes(
26192623 format : tv_tensors .BoundingBoxFormat ,
26202624 canvas_size : tuple [int , int ],
26212625 output_size : list [int ],
2626+ clamping_mode : CLAMPING_MODE_TYPE = "soft" ,
26222627) -> tuple [torch .Tensor , tuple [int , int ]]:
26232628 crop_height , crop_width = _center_crop_parse_output_size (output_size )
26242629 crop_top , crop_left = _center_crop_compute_crop_anchor (crop_height , crop_width , * canvas_size )
26252630 return crop_bounding_boxes (
2626- bounding_boxes , format , top = crop_top , left = crop_left , height = crop_height , width = crop_width
2631+ bounding_boxes ,
2632+ format ,
2633+ top = crop_top ,
2634+ left = crop_left ,
2635+ height = crop_height ,
2636+ width = crop_width ,
2637+ clamping_mode = clamping_mode ,
26272638 )
26282639
26292640
@@ -2632,7 +2643,11 @@ def _center_crop_bounding_boxes_dispatch(
26322643 inpt : tv_tensors .BoundingBoxes , output_size : list [int ]
26332644) -> tv_tensors .BoundingBoxes :
26342645 output , canvas_size = center_crop_bounding_boxes (
2635- inpt .as_subclass (torch .Tensor ), format = inpt .format , canvas_size = inpt .canvas_size , output_size = output_size
2646+ inpt .as_subclass (torch .Tensor ),
2647+ format = inpt .format ,
2648+ canvas_size = inpt .canvas_size ,
2649+ output_size = output_size ,
2650+ clamping_mode = inpt .clamping_mode ,
26362651 )
26372652 return tv_tensors .wrap (output , like = inpt , canvas_size = canvas_size )
26382653
@@ -2779,17 +2794,29 @@ def resized_crop_bounding_boxes(
27792794 height : int ,
27802795 width : int ,
27812796 size : list [int ],
2797+ clamping_mode : CLAMPING_MODE_TYPE = "soft" ,
27822798) -> tuple [torch .Tensor , tuple [int , int ]]:
2783- bounding_boxes , canvas_size = crop_bounding_boxes (bounding_boxes , format , top , left , height , width )
2784- return resize_bounding_boxes (bounding_boxes , format = format , canvas_size = canvas_size , size = size )
2799+ bounding_boxes , canvas_size = crop_bounding_boxes (
2800+ bounding_boxes , format , top , left , height , width , clamping_mode = clamping_mode
2801+ )
2802+ return resize_bounding_boxes (
2803+ bounding_boxes , format = format , canvas_size = canvas_size , size = size , clamping_mode = clamping_mode
2804+ )
27852805
27862806
27872807@_register_kernel_internal (resized_crop , tv_tensors .BoundingBoxes , tv_tensor_wrapper = False )
27882808def _resized_crop_bounding_boxes_dispatch (
27892809 inpt : tv_tensors .BoundingBoxes , top : int , left : int , height : int , width : int , size : list [int ], ** kwargs
27902810) -> tv_tensors .BoundingBoxes :
27912811 output , canvas_size = resized_crop_bounding_boxes (
2792- inpt .as_subclass (torch .Tensor ), format = inpt .format , top = top , left = left , height = height , width = width , size = size
2812+ inpt .as_subclass (torch .Tensor ),
2813+ format = inpt .format ,
2814+ top = top ,
2815+ left = left ,
2816+ height = height ,
2817+ width = width ,
2818+ size = size ,
2819+ clamping_mode = inpt .clamping_mode ,
27932820 )
27942821 return tv_tensors .wrap (output , like = inpt , canvas_size = canvas_size )
27952822
0 commit comments