mirror of https://github.com/opencv/opencv.git
Open Source Computer Vision Library
https://opencv.org/
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
72 lines
2.9 KiB
72 lines
2.9 KiB
3 years ago
|
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, scale=1):
|
||
|
self.warper_type = warper_type
|
||
|
self.warper = cv.PyRotationWarper(warper_type, scale)
|
||
|
self.scale = scale
|
||
|
|
||
|
def warp_images_and_image_masks(self, imgs, cameras, scale=None, aspect=1):
|
||
|
self.update_scale(scale)
|
||
|
for img, camera in zip(imgs, cameras):
|
||
|
yield self.warp_image_and_image_mask(img, camera, scale, aspect)
|
||
|
|
||
|
def warp_image_and_image_mask(self, img, camera, scale=None, aspect=1):
|
||
|
self.update_scale(scale)
|
||
|
corner, img_warped = self.warp_image(img, camera, aspect)
|
||
|
mask = 255 * np.ones((img.shape[0], img.shape[1]), np.uint8)
|
||
|
_, mask_warped = self.warp_image(mask, camera, aspect, mask=True)
|
||
|
return img_warped, mask_warped, corner
|
||
|
|
||
|
def warp_image(self, image, camera, aspect=1, mask=False):
|
||
|
if mask:
|
||
|
interp_mode = cv.INTER_NEAREST
|
||
|
border_mode = cv.BORDER_CONSTANT
|
||
|
else:
|
||
|
interp_mode = cv.INTER_LINEAR
|
||
|
border_mode = cv.BORDER_REFLECT
|
||
|
|
||
|
corner, warped_image = self.warper.warp(image,
|
||
|
Warper.get_K(camera, aspect),
|
||
|
camera.R,
|
||
|
interp_mode,
|
||
|
border_mode)
|
||
|
return corner, warped_image
|
||
|
|
||
|
def warp_roi(self, width, height, camera, scale=None, aspect=1):
|
||
|
self.update_scale(scale)
|
||
|
roi = (width, height)
|
||
|
K = Warper.get_K(camera, aspect)
|
||
|
return self.warper.warpRoi(roi, K, camera.R)
|
||
|
|
||
|
def update_scale(self, scale):
|
||
|
if scale is not None and scale != self.scale:
|
||
|
self.warper = cv.PyRotationWarper(self.warper_type, scale) # setScale not working: https://docs.opencv.org/master/d5/d76/classcv_1_1PyRotationWarper.html#a90b000bb75f95294f9b0b6ec9859eb55
|
||
|
self.scale = scale
|
||
|
|
||
|
@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
|