warper.py 3.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. from statistics import median
  2. import cv2 as cv
  3. import numpy as np
  4. class Warper:
  5. WARP_TYPE_CHOICES = ('spherical', 'plane', 'affine', 'cylindrical',
  6. 'fisheye', 'stereographic', 'compressedPlaneA2B1',
  7. 'compressedPlaneA1.5B1',
  8. 'compressedPlanePortraitA2B1',
  9. 'compressedPlanePortraitA1.5B1',
  10. 'paniniA2B1', 'paniniA1.5B1', 'paniniPortraitA2B1',
  11. 'paniniPortraitA1.5B1', 'mercator',
  12. 'transverseMercator')
  13. DEFAULT_WARP_TYPE = 'spherical'
  14. def __init__(self, warper_type=DEFAULT_WARP_TYPE):
  15. self.warper_type = warper_type
  16. self.scale = None
  17. def set_scale(self, cameras):
  18. focals = [cam.focal for cam in cameras]
  19. self.scale = median(focals)
  20. def warp_images(self, imgs, cameras, aspect=1):
  21. for img, camera in zip(imgs, cameras):
  22. yield self.warp_image(img, camera, aspect)
  23. def warp_image(self, img, camera, aspect=1):
  24. warper = cv.PyRotationWarper(self.warper_type, self.scale*aspect)
  25. _, warped_image = warper.warp(img,
  26. Warper.get_K(camera, aspect),
  27. camera.R,
  28. cv.INTER_LINEAR,
  29. cv.BORDER_REFLECT)
  30. return warped_image
  31. def create_and_warp_masks(self, sizes, cameras, aspect=1):
  32. for size, camera in zip(sizes, cameras):
  33. yield self.create_and_warp_mask(size, camera, aspect)
  34. def create_and_warp_mask(self, size, camera, aspect=1):
  35. warper = cv.PyRotationWarper(self.warper_type, self.scale*aspect)
  36. mask = 255 * np.ones((size[1], size[0]), np.uint8)
  37. _, warped_mask = warper.warp(mask,
  38. Warper.get_K(camera, aspect),
  39. camera.R,
  40. cv.INTER_NEAREST,
  41. cv.BORDER_CONSTANT)
  42. return warped_mask
  43. def warp_rois(self, sizes, cameras, aspect=1):
  44. roi_corners = []
  45. roi_sizes = []
  46. for size, camera in zip(sizes, cameras):
  47. roi = self.warp_roi(size, camera, aspect)
  48. roi_corners.append(roi[0:2])
  49. roi_sizes.append(roi[2:4])
  50. return roi_corners, roi_sizes
  51. def warp_roi(self, size, camera, aspect=1):
  52. warper = cv.PyRotationWarper(self.warper_type, self.scale*aspect)
  53. K = Warper.get_K(camera, aspect)
  54. return warper.warpRoi(size, K, camera.R)
  55. @staticmethod
  56. def get_K(camera, aspect=1):
  57. K = camera.K().astype(np.float32)
  58. """ Modification of intrinsic parameters needed if cameras were
  59. obtained on different scale than the scale of the Images which should
  60. be warped """
  61. K[0, 0] *= aspect
  62. K[0, 2] *= aspect
  63. K[1, 1] *= aspect
  64. K[1, 2] *= aspect
  65. return K