@@ -51,6 +51,18 @@ fn input_coord(
5151 Ctm :: AlignCorners => {
5252 dest_coord as f32 * ( length_original - 1 ) as f32 / ( length_resized - 1 ) as f32
5353 }
54+ Ctm :: PytorchHalfPixel => {
55+ // There are some queries over this transform mode, see
56+ // https://github.com/onnx/onnx/issues/4275 (applies to cubic interpolation only)
57+ // and https://github.com/onnx/onnx/issues/4276 (comparison with
58+ // PyTorch behavior). This implementation does however match
59+ // ONNX Runtime (https://github.com/microsoft/onnxruntime/blob/24620e70d9f14956a0dc84bb8a332dcd64c95a94/onnxruntime/core/providers/cpu/tensor/upsamplebase.h#L331)
60+ if length_resized > 1 {
61+ ( dest_coord as f32 + 0.5 ) / scale - 0.5
62+ } else {
63+ 0.
64+ }
65+ }
5466 }
5567}
5668
@@ -73,6 +85,7 @@ pub enum CoordTransformMode {
7385 HalfPixel ,
7486 Asymmetric ,
7587 AlignCorners ,
88+ PytorchHalfPixel ,
7689}
7790
7891const CHAN_GROUP_SIZE : usize = 4 ;
@@ -648,18 +661,25 @@ mod tests {
648661 coord_transform_mode : None ,
649662 expected : Tensor :: from_data ( & [ 1 , 1 , 0 , 0 ] , vec ! [ ] ) ,
650663 } ,
651- // Scale width and height by 0.5x
664+ // Scale to output width and height less than 2, using `HalfPixel`
665+ // `coord_transform_mode`.
666+ //
667+ // When the output size is < 2, `half_pixel` and `pytorch_half_pixel`
668+ // produce different results. Otherwise they are the same.
652669 Case {
653670 image,
654671 scales : vec ! [ 1. , 1. , 0.5 , 0.5 ] ,
655- coord_transform_mode : None ,
656-
657- // OpenCV and PyTorch produce different results for this case.
658- // This result matches OpenCV. This relates to the `half_pixel`
659- // vs `pytorch_half_pixel` values for the `coordinate_transformation_mode`
660- // attribute in the ONNX op.
672+ coord_transform_mode : Some ( CoordTransformMode :: HalfPixel ) ,
661673 expected : Tensor :: from_data ( & [ 1 , 1 , 1 , 1 ] , vec ! [ 0.5 ] ) ,
662674 } ,
675+ // Scale to output width and height less than 2, using `PytorchHalfPixel`
676+ // `coord_transform_mode`.
677+ Case {
678+ image,
679+ scales : vec ! [ 1. , 1. , 0.5 , 0.5 ] ,
680+ coord_transform_mode : Some ( CoordTransformMode :: PytorchHalfPixel ) ,
681+ expected : Tensor :: from_data ( & [ 1 , 1 , 1 , 1 ] , vec ! [ 0.2 ] ) ,
682+ } ,
663683 // Scale width and height by 1x
664684 Case {
665685 image,
0 commit comments