|
- import numpy as np
- import cv2
- import numbers
- import logging
-
- class Filter:
- # 根据需要添加其它函数
- def imnormalize(self, img, mean, std, to_rgb=True):
- """Inplace normalize an image with mean and std.
-
- Args:
- img (ndarray): Image to be normalized.
- mean (ndarray): The mean to be used for normalize.
- std (ndarray): The std to be used for normalize.
- to_rgb (bool): Whether to convert to rgb.
-
- Returns:
- ndarray: The normalized image.
- """
- # cv2 inplace normalization does not accept uint8
- #assert img.dtype != np.uint8
- mean = np.float64(mean.reshape(1, -1))
- stdinv = 1 / np.float64(std.reshape(1, -1))
- if to_rgb:
- cv2.cvtColor(img, cv2.COLOR_BGR2RGB, img) # inplace
- cv2.subtract(img, mean, img) # inplace
- cv2.multiply(img, stdinv, img) # inplace
- return img
-
- def impad(self, img,
- *,
- shape=None,
- padding=None,
- pad_val=0,
- padding_mode='constant'):
- assert (shape is not None) ^ (padding is not None)
- if shape is not None:
- padding = (0, 0, shape[1] - img.shape[1], shape[0] - img.shape[0])
-
- # check pad_val
- if isinstance(pad_val, tuple):
- assert len(pad_val) == img.shape[-1]
- elif not isinstance(pad_val, numbers.Number):
- raise TypeError('pad_val must be a int or a tuple. '
- f'But received {type(pad_val)}')
-
- # check padding
- if isinstance(padding, tuple) and len(padding) in [2, 4]:
- if len(padding) == 2:
- padding = (padding[0], padding[1], padding[0], padding[1])
- elif isinstance(padding, numbers.Number):
- padding = (padding, padding, padding, padding)
- else:
- raise ValueError('Padding must be a int or a 2, or 4 element tuple.'
- f'But received {padding}')
-
- # check padding mode
- assert padding_mode in ['constant', 'edge', 'reflect', 'symmetric']
-
- border_type = {
- 'constant': cv2.BORDER_CONSTANT,
- 'edge': cv2.BORDER_REPLICATE,
- 'reflect': cv2.BORDER_REFLECT_101,
- 'symmetric': cv2.BORDER_REFLECT
- }
- logging.error("padding...")
- logging.error(padding)
- self.pad_x = padding[0]
- self.pad_y = padding[1]
- img = cv2.copyMakeBorder(
- img,
- padding[1],
- padding[3],
- padding[0],
- padding[2],
- border_type[padding_mode],
- value=pad_val)
-
- return img
-
- # 可选提供init函数
- def init(self, params):
- self.means = params['normal.means']
- self.stds = params['normal.stds']
- self.resize_width = params['resize.width']
- self.resize_height = params['resize.height']
-
- # 必须提供filter函数
- def filter(self, inputs, meta_list):
- images_data = inputs['INPUT']
- images = []
- for image_data, meta in zip(images_data, meta_list):
- image_data = np.asarray(bytearray(image_data[0]), dtype="uint8")
- image = cv2.imdecode(image_data, cv2.IMREAD_COLOR)
-
- h, w, _ = image.shape
- img_scale = (self.resize_width, self.resize_height)
- max_long_edge = max(img_scale)
- max_short_edge = min(img_scale)
- scale_factor = min(max_long_edge / max(h, w), max_short_edge / min(h, w))
- meta['scale_factor'] = scale_factor
- scale_w = int(w * float(scale_factor) + 0.5)
- scale_h = int(h * float(scale_factor) + 0.5)
- image = cv2.resize(image, (scale_w, scale_h))
-
- image = np.asarray(image).astype(np.float32)
- mean = np.array(self.means, dtype=np.float32)
- std = np.array(self.stds, dtype=np.float32)
- image = self.imnormalize(image, mean, std)
-
- divisor = 32
- pad_h = int(np.ceil(image.shape[0] / divisor)) * divisor
- pad_w = int(np.ceil(image.shape[1] / divisor)) * divisor
- image = self.impad(image, shape=(pad_h, pad_w), pad_val=0)
- image = np.asarray(image).astype(np.float32)
- image = np.transpose(image, [2, 0, 1])
-
- images.append(image)
-
- return {'input': images}
-
- # 可选提供finalize函数
- def finalize(self):
- pass
|