rotate.py 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. import cv2
  2. import numpy as np
  3. def get_2d_rotation_matrix(angle, cx=0, cy=0, scale=1,
  4. degrees=True, dtype=np.float32):
  5. """
  6. References:
  7. `cv2.getRotationMatrix2D` in OpenCV
  8. """
  9. if degrees:
  10. angle = np.deg2rad(angle)
  11. c = scale * np.cos(angle)
  12. s = scale * np.sin(angle)
  13. tx = cx - cx * c + cy * s
  14. ty = cy - cx * s - cy * c
  15. return np.array([[ c, -s, tx],
  16. [ s, c, ty],
  17. [ 0, 0, 1]], dtype=dtype)
  18. def rotate_image(image, angle, scale=1.0, center=None,
  19. degrees=True, border_value=0, auto_bound=False):
  20. """Rotate an image.
  21. Args:
  22. image : ndarray
  23. Image to be rotated.
  24. angle : float
  25. Rotation angle in degrees, positive values mean clockwise rotation.
  26. center : tuple
  27. Center of the rotation in the source image, by default
  28. it is the center of the image.
  29. scale : float
  30. Isotropic scale factor.
  31. degrees : bool
  32. border_value : int
  33. Border value.
  34. auto_bound : bool
  35. Whether to adjust the image size to cover the whole rotated image.
  36. Returns:
  37. ndarray: The rotated image.
  38. References:
  39. mmcv.imrotate
  40. """
  41. image_height, image_width = image.shape[:2]
  42. if auto_bound:
  43. center = None
  44. if center is None:
  45. center = ((image_width - 1) * 0.5, (image_height - 1) * 0.5)
  46. assert isinstance(center, tuple)
  47. rotation_matrix = get_2d_rotation_matrix(angle, center[0], center[1], scale, degrees)
  48. if auto_bound:
  49. scale_cos = np.abs(rotation_matrix[0, 0])
  50. scale_sin = np.abs(rotation_matrix[0, 1])
  51. new_width = image_width * scale_cos + image_height * scale_sin
  52. new_height = image_width * scale_sin + image_height * scale_cos
  53. rotation_matrix[0, 2] += (new_width - image_width) * 0.5
  54. rotation_matrix[1, 2] += (new_height - image_height) * 0.5
  55. image_width = int(np.round(new_width))
  56. image_height = int(np.round(new_height))
  57. rotated = cv2.warpAffine(image, rotation_matrix[:2,:], (image_width, image_height),
  58. borderValue=border_value)
  59. return rotated