blender.py 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. import cv2 as cv
  2. import numpy as np
  3. class Blender:
  4. BLENDER_CHOICES = ('multiband', 'feather', 'no',)
  5. DEFAULT_BLENDER = 'multiband'
  6. DEFAULT_BLEND_STRENGTH = 5
  7. def __init__(self, blender_type=DEFAULT_BLENDER,
  8. blend_strength=DEFAULT_BLEND_STRENGTH):
  9. self.blender_type = blender_type
  10. self.blend_strength = blend_strength
  11. self.blender = None
  12. def prepare(self, corners, sizes):
  13. dst_sz = cv.detail.resultRoi(corners=corners, sizes=sizes)
  14. blend_width = (np.sqrt(dst_sz[2] * dst_sz[3]) *
  15. self.blend_strength / 100)
  16. if self.blender_type == 'no' or blend_width < 1:
  17. self.blender = cv.detail.Blender_createDefault(
  18. cv.detail.Blender_NO
  19. )
  20. elif self.blender_type == "multiband":
  21. self.blender = cv.detail_MultiBandBlender()
  22. self.blender.setNumBands(int((np.log(blend_width) /
  23. np.log(2.) - 1.)))
  24. elif self.blender_type == "feather":
  25. self.blender = cv.detail_FeatherBlender()
  26. self.blender.setSharpness(1. / blend_width)
  27. self.blender.prepare(dst_sz)
  28. def feed(self, img, mask, corner):
  29. """https://docs.opencv.org/4.x/d6/d4a/classcv_1_1detail_1_1Blender.html#a64837308bcf4e414a6219beff6cbe37a""" # noqa
  30. self.blender.feed(cv.UMat(img.astype(np.int16)), mask, corner)
  31. def blend(self):
  32. """https://docs.opencv.org/4.x/d6/d4a/classcv_1_1detail_1_1Blender.html#aa0a91ce0d6046d3a63e0123cbb1b5c00""" # noqa
  33. result = None
  34. result_mask = None
  35. result, result_mask = self.blender.blend(result, result_mask)
  36. result = cv.convertScaleAbs(result)
  37. return result, result_mask
  38. @classmethod
  39. def create_panorama(cls, imgs, masks, corners, sizes):
  40. blender = cls("no")
  41. blender.prepare(corners, sizes)
  42. for img, mask, corner in zip(imgs, masks, corners):
  43. blender.feed(img, mask, corner)
  44. return blender.blend()