@@ -756,40 +756,8 @@ def adjust_gamma(img: Tensor, gamma: float, gain: float = 1) -> Tensor:
756756 return F_t .adjust_gamma (img , gamma , gain )
757757
758758
759- def rotate (img , angle , resample = False , expand = False , center = None , fill = None ):
760- """Rotate the image by angle.
761-
762-
763- Args:
764- img (PIL Image): PIL Image to be rotated.
765- angle (float or int): In degrees degrees counter clockwise order.
766- resample (``PIL.Image.NEAREST`` or ``PIL.Image.BILINEAR`` or ``PIL.Image.BICUBIC``, optional):
767- An optional resampling filter. See `filters`_ for more information.
768- If omitted, or if the image has mode "1" or "P", it is set to ``PIL.Image.NEAREST``.
769- expand (bool, optional): Optional expansion flag.
770- If true, expands the output image to make it large enough to hold the entire rotated image.
771- If false or omitted, make the output image the same size as the input image.
772- Note that the expand flag assumes rotation around the center and no translation.
773- center (2-tuple, optional): Optional center of rotation.
774- Origin is the upper left corner.
775- Default is the center of the image.
776- fill (n-tuple or int or float): Pixel fill value for area outside the rotated
777- image. If int or float, the value is used for all bands respectively.
778- Defaults to 0 for all bands. This option is only available for ``pillow>=5.2.0``.
779-
780- .. _filters: https://pillow.readthedocs.io/en/latest/handbook/concepts.html#filters
781-
782- """
783- if not F_pil ._is_pil_image (img ):
784- raise TypeError ('img should be PIL Image. Got {}' .format (type (img )))
785-
786- opts = _parse_fill (fill , img , '5.2.0' )
787-
788- return img .rotate (angle , resample , expand , center , ** opts )
789-
790-
791759def _get_inverse_affine_matrix (
792- center : List [int ], angle : float , translate : List [float ], scale : float , shear : List [float ]
760+ center : List [float ], angle : float , translate : List [float ], scale : float , shear : List [float ]
793761) -> List [float ]:
794762 # Helper method to compute inverse matrix for affine transformation
795763
@@ -838,6 +806,56 @@ def _get_inverse_affine_matrix(
838806 return matrix
839807
840808
809+ def rotate (
810+ img : Tensor , angle : float , resample : int = 0 , expand : bool = False ,
811+ center : Optional [List [int ]] = None , fill : Optional [int ] = None
812+ ) -> Tensor :
813+ """Rotate the image by angle.
814+ The image can be a PIL Image or a Tensor, in which case it is expected
815+ to have [..., H, W] shape, where ... means an arbitrary number of leading dimensions.
816+
817+ Args:
818+ img (PIL Image or Tensor): image to be rotated.
819+ angle (float or int): rotation angle value in degrees, counter-clockwise.
820+ resample (``PIL.Image.NEAREST`` or ``PIL.Image.BILINEAR`` or ``PIL.Image.BICUBIC``, optional):
821+ An optional resampling filter. See `filters`_ for more information.
822+ If omitted, or if the image has mode "1" or "P", it is set to ``PIL.Image.NEAREST``.
823+ expand (bool, optional): Optional expansion flag.
824+ If true, expands the output image to make it large enough to hold the entire rotated image.
825+ If false or omitted, make the output image the same size as the input image.
826+ Note that the expand flag assumes rotation around the center and no translation.
827+ center (list or tuple, optional): Optional center of rotation. Origin is the upper left corner.
828+ Default is the center of the image.
829+ fill (n-tuple or int or float): Pixel fill value for area outside the rotated
830+ image. If int or float, the value is used for all bands respectively.
831+ Defaults to 0 for all bands. This option is only available for ``pillow>=5.2.0``.
832+
833+ Returns:
834+ PIL Image or Tensor: Rotated image.
835+
836+ .. _filters: https://pillow.readthedocs.io/en/latest/handbook/concepts.html#filters
837+
838+ """
839+ if not isinstance (angle , (int , float )):
840+ raise TypeError ("Argument angle should be int or float" )
841+
842+ if center is not None and not isinstance (center , (list , tuple )):
843+ raise TypeError ("Argument center should be a sequence" )
844+
845+ if not isinstance (img , torch .Tensor ):
846+ return F_pil .rotate (img , angle = angle , resample = resample , expand = expand , center = center , fill = fill )
847+
848+ center_f = [0.0 , 0.0 ]
849+ if center is not None :
850+ img_size = _get_image_size (img )
851+ # Center is normalized to [-1, +1]
852+ center_f = [2.0 * t / s - 1.0 for s , t in zip (img_size , center )]
853+ # due to current incoherence of rotation angle direction between affine and rotate implementations
854+ # we need to set -angle.
855+ matrix = _get_inverse_affine_matrix (center_f , - angle , [0.0 , 0.0 ], 1.0 , [0.0 , 0.0 ])
856+ return F_t .rotate (img , matrix = matrix , resample = resample , expand = expand , fill = fill )
857+
858+
841859def affine (
842860 img : Tensor , angle : float , translate : List [int ], scale : float , shear : List [float ],
843861 resample : int = 0 , fillcolor : Optional [int ] = None
@@ -847,7 +865,7 @@ def affine(
847865 to have [..., H, W] shape, where ... means an arbitrary number of leading dimensions.
848866
849867 Args:
850- img (PIL Image or Tensor): image to be rotated .
868+ img (PIL Image or Tensor): image to transform .
851869 angle (float or int): rotation angle in degrees between -180 and 180, clockwise direction.
852870 translate (list or tuple of integers): horizontal and vertical translations (post-rotation translation)
853871 scale (float): overall scale
@@ -911,7 +929,7 @@ def affine(
911929 # we need to rescale translate by image size / 2 as its values can be between -1 and 1
912930 translate = [2.0 * t / s for s , t in zip (img_size , translate )]
913931
914- matrix = _get_inverse_affine_matrix ([0 , 0 ], angle , translate , scale , shear )
932+ matrix = _get_inverse_affine_matrix ([0.0 , 0. 0 ], angle , translate , scale , shear )
915933 return F_t .affine (img , matrix = matrix , resample = resample , fillcolor = fillcolor )
916934
917935
0 commit comments