12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879 |
- from statistics import median
- import cv2 as cv
- import numpy as np
- class Warper:
- WARP_TYPE_CHOICES = ('spherical', 'plane', 'affine', 'cylindrical',
- 'fisheye', 'stereographic', 'compressedPlaneA2B1',
- 'compressedPlaneA1.5B1',
- 'compressedPlanePortraitA2B1',
- 'compressedPlanePortraitA1.5B1',
- 'paniniA2B1', 'paniniA1.5B1', 'paniniPortraitA2B1',
- 'paniniPortraitA1.5B1', 'mercator',
- 'transverseMercator')
- DEFAULT_WARP_TYPE = 'spherical'
- def __init__(self, warper_type=DEFAULT_WARP_TYPE):
- self.warper_type = warper_type
- self.scale = None
- def set_scale(self, cameras):
- focals = [cam.focal for cam in cameras]
- self.scale = median(focals)
- def warp_images(self, imgs, cameras, aspect=1):
- for img, camera in zip(imgs, cameras):
- yield self.warp_image(img, camera, aspect)
- def warp_image(self, img, camera, aspect=1):
- warper = cv.PyRotationWarper(self.warper_type, self.scale*aspect)
- _, warped_image = warper.warp(img,
- Warper.get_K(camera, aspect),
- camera.R,
- cv.INTER_LINEAR,
- cv.BORDER_REFLECT)
- return warped_image
- def create_and_warp_masks(self, sizes, cameras, aspect=1):
- for size, camera in zip(sizes, cameras):
- yield self.create_and_warp_mask(size, camera, aspect)
- def create_and_warp_mask(self, size, camera, aspect=1):
- warper = cv.PyRotationWarper(self.warper_type, self.scale*aspect)
- mask = 255 * np.ones((size[1], size[0]), np.uint8)
- _, warped_mask = warper.warp(mask,
- Warper.get_K(camera, aspect),
- camera.R,
- cv.INTER_NEAREST,
- cv.BORDER_CONSTANT)
- return warped_mask
- def warp_rois(self, sizes, cameras, aspect=1):
- roi_corners = []
- roi_sizes = []
- for size, camera in zip(sizes, cameras):
- roi = self.warp_roi(size, camera, aspect)
- roi_corners.append(roi[0:2])
- roi_sizes.append(roi[2:4])
- return roi_corners, roi_sizes
- def warp_roi(self, size, camera, aspect=1):
- warper = cv.PyRotationWarper(self.warper_type, self.scale*aspect)
- K = Warper.get_K(camera, aspect)
- return warper.warpRoi(size, K, camera.R)
- @staticmethod
- def get_K(camera, aspect=1):
- K = camera.K().astype(np.float32)
- """ Modification of intrinsic parameters needed if cameras were
- obtained on different scale than the scale of the Images which should
- be warped """
- K[0, 0] *= aspect
- K[0, 2] *= aspect
- K[1, 1] *= aspect
- K[1, 2] *= aspect
- return K
|