123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153 |
- from imageio import imread
- from PIL import Image
- from os.path import isfile
- import copy
- import numpy as np
- from cvdatasets import utils
- from .part import Parts, UniformParts
- def should_have_parts(func):
- def inner(self, *args, **kwargs):
- assert self.has_parts, "parts are not present!"
- return func(self, *args, **kwargs)
- return inner
- class ImageWrapper(object):
- @staticmethod
- def read_image(im_path, mode="RGB"):
- # im = imread(im_path, pilmode=mode)
- im = Image.open(im_path, mode="r")
- return im
- def __init__(self, im_path, label, parts=None, mode="RGB", part_rescale_size=None):
- self.mode = mode
- self.im = im_path
- self._im_array = None
- self.label = label
- self.parts = Parts(self.im, parts, part_rescale_size)
- self.parent = None
- self._feature = None
- def __del__(self):
- if isinstance(self._im, Image.Image):
- if self._im is not None and getattr(self._im, "fp", None) is not None:
- self._im.close()
- @property
- def im_array(self):
- if self._im_array is None:
- if isinstance(self._im, Image.Image):
- _im = self._im.convert(self.mode)
- self._im_array = utils.asarray(_im)
- elif isinstance(self._im, np.ndarray):
- if self.mode == "RGB" and self._im.ndim == 2:
- self._im_array = np.stack((self._im,) * 3, axis=-1)
- elif self._im.ndim in (3, 4):
- self._im_array = self._im
- else:
- raise ValueError()
- else:
- raise ValueError()
- return self._im_array
- @property
- def im(self):
- if isinstance(self._im, Image.Image) and self._im.mode != self.mode:
- self._im = self._im.convert(self.mode)
- return self._im
- @im.setter
- def im(self, value):
- if isinstance(value, str):
- assert isfile(value), "Image \"{}\" does not exist!".format(value)
- self._im = ImageWrapper.read_image(value, mode=self.mode)
- self._im_path = value
- else:
- self._im = value
- def as_tuple(self):
- return self.im_array, self.parts, self.label
- def copy(self):
- new = copy.copy(self)
- new.parent = self
- deepcopies = [
- "_feature",
- "parts",
- ]
- for attr_name in deepcopies:
- attr_copy = copy.deepcopy(getattr(self, attr_name))
- setattr(new, attr_name, attr_copy)
- return new
- @property
- def feature(self):
- return self._feature
- @feature.setter
- def feature(self, im_feature):
- self._feature = im_feature
- def crop(self, x, y, w, h):
- result = self.copy()
- # result.im = self.im[y:y+h, x:x+w]
- result.im = self.im.crop((x, y, x+w, y+h))
- if self.has_parts:
- result.parts.offset(-x, -y)
- return result
- @should_have_parts
- def hide_parts_outside_bb(self, x, y, w, h):
- result = self.copy()
- result.parts.hide_outside_bb(x, y, w, h)
- return result
- def uniform_parts(self, ratio):
- result = self.copy()
- result.parts = UniformParts(self.im, ratio=ratio)
- return result
- @should_have_parts
- def select_parts(self, idxs):
- result = self.copy()
- result.parts.select(idxs)
- return result
- @should_have_parts
- def select_random_parts(self, rnd, n_parts):
- idxs, xy = self.visible_part_locs()
- rnd_idxs = utils.random_idxs(idxs, rnd=rnd, n_parts=n_parts)
- return self.select_parts(rnd_idxs)
- @should_have_parts
- def visible_crops(self, ratio):
- return self.parts.visible_crops(self.im, ratio=ratio)
- @should_have_parts
- def visible_part_locs(self):
- return self.parts.visible_locs()
- @should_have_parts
- def reveal_visible(self, ratio):
- result = self.copy()
- result.im = self.parts.reveal(self.im, ratio=ratio)
- return result
- @should_have_parts
- def part_crops(self, ratio):
- crops = self.visible_crops(ratio)
- idxs, _ = self.visible_part_locs()
- result = self.copy()
- result.im = crops[idxs]
- return result
- @property
- def has_parts(self):
- return self.parts is not None
|