image_handler.py 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. import cv2 as cv
  2. from .megapix_scaler import MegapixDownscaler
  3. from .stitching_error import StitchingError
  4. class ImageHandler:
  5. DEFAULT_MEDIUM_MEGAPIX = 0.6
  6. DEFAULT_LOW_MEGAPIX = 0.1
  7. DEFAULT_FINAL_MEGAPIX = -1
  8. def __init__(self,
  9. medium_megapix=DEFAULT_MEDIUM_MEGAPIX,
  10. low_megapix=DEFAULT_LOW_MEGAPIX,
  11. final_megapix=DEFAULT_FINAL_MEGAPIX):
  12. if medium_megapix < low_megapix:
  13. raise StitchingError("Medium resolution megapix need to be "
  14. "greater or equal than low resolution "
  15. "megapix")
  16. self.medium_scaler = MegapixDownscaler(medium_megapix)
  17. self.low_scaler = MegapixDownscaler(low_megapix)
  18. self.final_scaler = MegapixDownscaler(final_megapix)
  19. self.scales_set = False
  20. self.img_names = []
  21. self.img_sizes = []
  22. def set_img_names(self, img_names):
  23. self.img_names = img_names
  24. def resize_to_medium_resolution(self):
  25. return self.read_and_resize_imgs(self.medium_scaler)
  26. def resize_to_low_resolution(self, medium_imgs=None):
  27. if medium_imgs and self.scales_set:
  28. return self.resize_imgs_by_scaler(medium_imgs, self.low_scaler)
  29. return self.read_and_resize_imgs(self.low_scaler)
  30. def resize_to_final_resolution(self):
  31. return self.read_and_resize_imgs(self.final_scaler)
  32. def read_and_resize_imgs(self, scaler):
  33. for img, size in self.input_images():
  34. yield self.resize_img_by_scaler(scaler, size, img)
  35. def resize_imgs_by_scaler(self, medium_imgs, scaler):
  36. for img, size in zip(medium_imgs, self.img_sizes):
  37. yield self.resize_img_by_scaler(scaler, size, img)
  38. @staticmethod
  39. def resize_img_by_scaler(scaler, size, img):
  40. desired_size = scaler.get_scaled_img_size(size)
  41. return cv.resize(img, desired_size,
  42. interpolation=cv.INTER_LINEAR_EXACT)
  43. def input_images(self):
  44. self.img_sizes = []
  45. for name in self.img_names:
  46. img = self.read_image(name)
  47. size = self.get_image_size(img)
  48. self.img_sizes.append(size)
  49. self.set_scaler_scales()
  50. yield img, size
  51. @staticmethod
  52. def get_image_size(img):
  53. """(width, height)"""
  54. return (img.shape[1], img.shape[0])
  55. @staticmethod
  56. def read_image(img_name):
  57. img = cv.imread(img_name)
  58. if img is None:
  59. raise StitchingError("Cannot read image " + img_name)
  60. return img
  61. def set_scaler_scales(self):
  62. if not self.scales_set:
  63. first_img_size = self.img_sizes[0]
  64. self.medium_scaler.set_scale_by_img_size(first_img_size)
  65. self.low_scaler.set_scale_by_img_size(first_img_size)
  66. self.final_scaler.set_scale_by_img_size(first_img_size)
  67. self.scales_set = True
  68. def get_medium_to_final_ratio(self):
  69. return self.final_scaler.scale / self.medium_scaler.scale
  70. def get_medium_to_low_ratio(self):
  71. return self.low_scaler.scale / self.medium_scaler.scale
  72. def get_final_to_low_ratio(self):
  73. return self.low_scaler.scale / self.final_scaler.scale
  74. def get_low_to_final_ratio(self):
  75. return self.final_scaler.scale / self.low_scaler.scale
  76. def get_final_img_sizes(self):
  77. return [self.final_scaler.get_scaled_img_size(sz)
  78. for sz in self.img_sizes]
  79. def get_low_img_sizes(self):
  80. return [self.low_scaler.get_scaled_img_size(sz)
  81. for sz in self.img_sizes]