opencv/apps/opencv_stitching_tool/opencv_stitching/warper.py
Lukas-Alexander Weber d37bcbdc92
Merge pull request #21420 from lukasalexanderweber:4.x
Introduce Cropping to OpenCV Stitching Tool

* Introduced Cropping

* integrate https://github.com/opencv/opencv/pull/21413/

* fixed failing subsetter tests

* updated stuff
2022-02-01 16:56:44 +00:00

80 lines
3.0 KiB
Python

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