|
|
@@ -1,536 +0,0 @@
|
|
|
-# Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved.
|
|
|
-#
|
|
|
-# Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
-# you may not use this file except in compliance with the License.
|
|
|
-# You may obtain a copy of the License at
|
|
|
-#
|
|
|
-# http://www.apache.org/licenses/LICENSE-2.0
|
|
|
-#
|
|
|
-# Unless required by applicable law or agreed to in writing, software
|
|
|
-# distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
-# See the License for the specific language governing permissions and
|
|
|
-# limitations under the License.
|
|
|
-"""
|
|
|
-function:
|
|
|
- transforms for segmentation in PaddleX<2.0
|
|
|
-"""
|
|
|
-
|
|
|
-import numpy as np
|
|
|
-import cv2
|
|
|
-import copy
|
|
|
-from .operators import Transform, Compose, RandomHorizontalFlip, RandomVerticalFlip, Resize, \
|
|
|
- ResizeByShort, Normalize, RandomDistort, ArrangeSegmenter
|
|
|
-from .operators import Padding as dy_Padding
|
|
|
-
|
|
|
-__all__ = [
|
|
|
- 'Compose', 'RandomHorizontalFlip', 'RandomVerticalFlip', 'Resize',
|
|
|
- 'ResizeByShort', 'Normalize', 'RandomDistort', 'ArrangeSegmenter',
|
|
|
- 'ResizeByLong', 'ResizeRangeScaling', 'ResizeStepScaling', 'Padding',
|
|
|
- 'RandomPaddingCrop', 'RandomBlur', 'RandomRotate', 'RandomScaleAspect',
|
|
|
- 'Clip', 'ComposedSegTransforms'
|
|
|
-]
|
|
|
-
|
|
|
-
|
|
|
-class ResizeByLong(Transform):
|
|
|
- """对图像长边resize到固定值,短边按比例进行缩放。当存在标注图像时,则同步进行处理。
|
|
|
- Args:
|
|
|
- long_size (int): resize后图像的长边大小。
|
|
|
- """
|
|
|
-
|
|
|
- def __init__(self, long_size=256):
|
|
|
- super(ResizeByLong, self).__init__()
|
|
|
- self.long_size = long_size
|
|
|
-
|
|
|
- def apply_im(self, image):
|
|
|
- image = _resize_long(image, long_size=self.long_size)
|
|
|
- return image
|
|
|
-
|
|
|
- def apply_mask(self, mask):
|
|
|
- mask = _resize_long(
|
|
|
- mask, long_size=self.long_size, interpolation=cv2.INTER_NEAREST)
|
|
|
- return mask
|
|
|
-
|
|
|
- def apply(self, sample):
|
|
|
- sample['image'] = self.apply_im(sample['image'])
|
|
|
- if 'mask' in sample:
|
|
|
- sample['mask'] = self.apply_mask(sample['mask'])
|
|
|
-
|
|
|
- return sample
|
|
|
-
|
|
|
-
|
|
|
-class ResizeRangeScaling(Transform):
|
|
|
- """对图像长边随机resize到指定范围内,短边按比例进行缩放。当存在标注图像时,则同步进行处理。
|
|
|
- Args:
|
|
|
- min_value (int): 图像长边resize后的最小值。默认值400。
|
|
|
- max_value (int): 图像长边resize后的最大值。默认值600。
|
|
|
- Raises:
|
|
|
- ValueError: min_value大于max_value
|
|
|
- """
|
|
|
-
|
|
|
- def __init__(self, min_value=400, max_value=600):
|
|
|
- super(ResizeRangeScaling, self).__init__()
|
|
|
- if min_value > max_value:
|
|
|
- raise ValueError('min_value must be less than max_value, '
|
|
|
- 'but they are {} and {}.'.format(min_value,
|
|
|
- max_value))
|
|
|
- self.min_value = min_value
|
|
|
- self.max_value = max_value
|
|
|
-
|
|
|
- def apply_im(self, image, random_size):
|
|
|
- image = _resize_long(image, long_size=random_size)
|
|
|
- return image
|
|
|
-
|
|
|
- def apply_mask(self, mask, random_size):
|
|
|
- mask = _resize_long(
|
|
|
- mask, long_size=random_size, interpolation=cv2.INTER_NEAREST)
|
|
|
- return mask
|
|
|
-
|
|
|
- def apply(self, sample):
|
|
|
- if self.min_value == self.max_value:
|
|
|
- random_size = self.max_value
|
|
|
- else:
|
|
|
- random_size = int(
|
|
|
- np.random.uniform(self.min_value, self.max_value) + 0.5)
|
|
|
- sample['image'] = self.apply_im(sample['image'], random_size)
|
|
|
- if 'mask' in sample:
|
|
|
- sample['mask'] = self.apply_mask(sample['mask'], random_size)
|
|
|
-
|
|
|
- return sample
|
|
|
-
|
|
|
-
|
|
|
-class ResizeStepScaling(Transform):
|
|
|
- """对图像按照某一个比例resize,这个比例以scale_step_size为步长
|
|
|
- 在[min_scale_factor, max_scale_factor]随机变动。当存在标注图像时,则同步进行处理。
|
|
|
- Args:
|
|
|
- min_scale_factor(float), resize最小尺度。默认值0.75。
|
|
|
- max_scale_factor (float), resize最大尺度。默认值1.25。
|
|
|
- scale_step_size (float), resize尺度范围间隔。默认值0.25。
|
|
|
- Raises:
|
|
|
- ValueError: min_scale_factor大于max_scale_factor
|
|
|
- """
|
|
|
-
|
|
|
- def __init__(self,
|
|
|
- min_scale_factor=0.75,
|
|
|
- max_scale_factor=1.25,
|
|
|
- scale_step_size=0.25):
|
|
|
- if min_scale_factor > max_scale_factor:
|
|
|
- raise ValueError(
|
|
|
- 'min_scale_factor must be less than max_scale_factor, '
|
|
|
- 'but they are {} and {}.'.format(min_scale_factor,
|
|
|
- max_scale_factor))
|
|
|
- super(ResizeStepScaling, self).__init__()
|
|
|
- self.min_scale_factor = min_scale_factor
|
|
|
- self.max_scale_factor = max_scale_factor
|
|
|
- self.scale_step_size = scale_step_size
|
|
|
-
|
|
|
- def apply_im(self, image, scale_factor):
|
|
|
- image = cv2.resize(
|
|
|
- image, (0, 0),
|
|
|
- fx=scale_factor,
|
|
|
- fy=scale_factor,
|
|
|
- interpolation=cv2.INTER_LINEAR)
|
|
|
- if image.ndim < 3:
|
|
|
- image = np.expand_dims(image, axis=-1)
|
|
|
- return image
|
|
|
-
|
|
|
- def apply_mask(self, mask, scale_factor):
|
|
|
- mask = cv2.resize(
|
|
|
- mask, (0, 0),
|
|
|
- fx=scale_factor,
|
|
|
- fy=scale_factor,
|
|
|
- interpolation=cv2.INTER_NEAREST)
|
|
|
- return mask
|
|
|
-
|
|
|
- def apply(self, sample):
|
|
|
- if self.min_scale_factor == self.max_scale_factor:
|
|
|
- scale_factor = self.min_scale_factor
|
|
|
-
|
|
|
- elif self.scale_step_size == 0:
|
|
|
- scale_factor = np.random.uniform(self.min_scale_factor,
|
|
|
- self.max_scale_factor)
|
|
|
-
|
|
|
- else:
|
|
|
- num_steps = int((self.max_scale_factor - self.min_scale_factor) /
|
|
|
- self.scale_step_size + 1)
|
|
|
- scale_factors = np.linspace(self.min_scale_factor,
|
|
|
- self.max_scale_factor,
|
|
|
- num_steps).tolist()
|
|
|
- np.random.shuffle(scale_factors)
|
|
|
- scale_factor = scale_factors[0]
|
|
|
-
|
|
|
- sample['image'] = self.apply_im(sample['image'], scale_factor)
|
|
|
- if 'mask' in sample:
|
|
|
- sample['mask'] = self.apply_mask(sample['mask'], scale_factor)
|
|
|
-
|
|
|
- return sample
|
|
|
-
|
|
|
-
|
|
|
-class Padding(dy_Padding):
|
|
|
- """对图像或标注图像进行padding,padding方向为右和下。
|
|
|
- 根据提供的值对图像或标注图像进行padding操作。
|
|
|
- Args:
|
|
|
- target_size (int|list|tuple): padding后图像的大小。
|
|
|
- im_padding_value (list): 图像padding的值。默认为[127.5, 127.5, 127.5]。
|
|
|
- label_padding_value (int): 标注图像padding的值。默认值为255。
|
|
|
- Raises:
|
|
|
- TypeError: target_size不是int|list|tuple。
|
|
|
- ValueError: target_size为list|tuple时元素个数不等于2。
|
|
|
- """
|
|
|
-
|
|
|
- def __init__(self,
|
|
|
- target_size,
|
|
|
- im_padding_value=[127.5, 127.5, 127.5],
|
|
|
- label_padding_value=255):
|
|
|
- super(Padding, self).__init__(
|
|
|
- target_size=target_size,
|
|
|
- pad_mode=0,
|
|
|
- offsets=None,
|
|
|
- im_padding_value=im_padding_value,
|
|
|
- label_padding_value=label_padding_value)
|
|
|
-
|
|
|
-
|
|
|
-class RandomPaddingCrop(Transform):
|
|
|
- """对图像和标注图进行随机裁剪,当所需要的裁剪尺寸大于原图时,则进行padding操作。
|
|
|
- Args:
|
|
|
- crop_size (int|list|tuple): 裁剪图像大小。默认为512。
|
|
|
- im_padding_value (list): 图像padding的值。默认为[127.5, 127.5, 127.5]。
|
|
|
- label_padding_value (int): 标注图像padding的值。默认值为255。
|
|
|
- Raises:
|
|
|
- TypeError: crop_size不是int/list/tuple。
|
|
|
- ValueError: target_size为list/tuple时元素个数不等于2。
|
|
|
- """
|
|
|
-
|
|
|
- def __init__(self,
|
|
|
- crop_size=512,
|
|
|
- im_padding_value=[127.5, 127.5, 127.5],
|
|
|
- label_padding_value=255):
|
|
|
- if isinstance(crop_size, list) or isinstance(crop_size, tuple):
|
|
|
- if len(crop_size) != 2:
|
|
|
- raise ValueError(
|
|
|
- 'when crop_size is list or tuple, it should include 2 elements, but it is {}'
|
|
|
- .format(crop_size))
|
|
|
- elif not isinstance(crop_size, int):
|
|
|
- raise TypeError(
|
|
|
- "Type of crop_size is invalid. Must be Integer or List or tuple, now is {}"
|
|
|
- .format(type(crop_size)))
|
|
|
- super(RandomPaddingCrop, self).__init__()
|
|
|
- self.crop_size = crop_size
|
|
|
- self.im_padding_value = im_padding_value
|
|
|
- self.label_padding_value = label_padding_value
|
|
|
-
|
|
|
- def apply_im(self, image, pad_h, pad_w):
|
|
|
- im_h, im_w, im_c = image.shape
|
|
|
- orig_im = copy.deepcopy(image)
|
|
|
- image = np.zeros(
|
|
|
- (im_h + pad_h, im_w + pad_w, im_c)).astype(orig_im.dtype)
|
|
|
- for i in range(im_c):
|
|
|
- image[:, :, i] = np.pad(orig_im[:, :, i],
|
|
|
- pad_width=((0, pad_h), (0, pad_w)),
|
|
|
- mode='constant',
|
|
|
- constant_values=(self.im_padding_value[i],
|
|
|
- self.im_padding_value[i]))
|
|
|
- return image
|
|
|
-
|
|
|
- def apply_mask(self, mask, pad_h, pad_w):
|
|
|
- mask = np.pad(mask,
|
|
|
- pad_width=((0, pad_h), (0, pad_w)),
|
|
|
- mode='constant',
|
|
|
- constant_values=(self.label_padding_value,
|
|
|
- self.label_padding_value))
|
|
|
- return mask
|
|
|
-
|
|
|
- def apply(self, sample):
|
|
|
- """
|
|
|
- Args:
|
|
|
- im (np.ndarray): 图像np.ndarray数据。
|
|
|
- im_info (list): 存储图像reisze或padding前的shape信息,如
|
|
|
- [('resize', [200, 300]), ('padding', [400, 600])]表示
|
|
|
- 图像在过resize前shape为(200, 300), 过padding前shape为
|
|
|
- (400, 600)
|
|
|
- label (np.ndarray): 标注图像np.ndarray数据。
|
|
|
- Returns:
|
|
|
- tuple: 当label为空时,返回的tuple为(im, im_info),分别对应图像np.ndarray数据、存储与图像相关信息的字典;
|
|
|
- 当label不为空时,返回的tuple为(im, im_info, label),分别对应图像np.ndarray数据、
|
|
|
- 存储与图像相关信息的字典和标注图像np.ndarray数据。
|
|
|
- """
|
|
|
- if isinstance(self.crop_size, int):
|
|
|
- crop_width = self.crop_size
|
|
|
- crop_height = self.crop_size
|
|
|
- else:
|
|
|
- crop_width = self.crop_size[0]
|
|
|
- crop_height = self.crop_size[1]
|
|
|
-
|
|
|
- im_h, im_w, im_c = sample['image'].shape
|
|
|
-
|
|
|
- if im_h == crop_height and im_w == crop_width:
|
|
|
- return sample
|
|
|
- else:
|
|
|
- pad_height = max(crop_height - im_h, 0)
|
|
|
- pad_width = max(crop_width - im_w, 0)
|
|
|
- if pad_height > 0 or pad_width > 0:
|
|
|
- sample['image'] = self.apply_im(sample['image'], pad_height,
|
|
|
- pad_width)
|
|
|
-
|
|
|
- if 'mask' in sample:
|
|
|
- sample['mask'] = self.apply_mask(sample['mask'],
|
|
|
- pad_height, pad_width)
|
|
|
-
|
|
|
- im_h = sample['image'].shape[0]
|
|
|
- im_w = sample['image'].shape[1]
|
|
|
-
|
|
|
- if crop_height > 0 and crop_width > 0:
|
|
|
- h_off = np.random.randint(im_h - crop_height + 1)
|
|
|
- w_off = np.random.randint(im_w - crop_width + 1)
|
|
|
-
|
|
|
- sample['image'] = sample['image'][h_off:(
|
|
|
- crop_height + h_off), w_off:(w_off + crop_width), :]
|
|
|
- if 'mask' in sample:
|
|
|
- sample['mask'] = sample['mask'][h_off:(
|
|
|
- crop_height + h_off), w_off:(w_off + crop_width)]
|
|
|
- return sample
|
|
|
-
|
|
|
-
|
|
|
-class RandomBlur(Transform):
|
|
|
- """以一定的概率对图像进行高斯模糊。
|
|
|
- Args:
|
|
|
- prob (float): 图像模糊概率。默认为0.1。
|
|
|
- """
|
|
|
-
|
|
|
- def __init__(self, prob=0.1):
|
|
|
- super(RandomBlur, self).__init__()
|
|
|
- self.prob = prob
|
|
|
-
|
|
|
- def apply_im(self, image, radius):
|
|
|
- image = cv2.GaussianBlur(image, (radius, radius), 0, 0)
|
|
|
- return image
|
|
|
-
|
|
|
- def apply(self, sample):
|
|
|
- if self.prob <= 0:
|
|
|
- n = 0
|
|
|
- elif self.prob >= 1:
|
|
|
- n = 1
|
|
|
- else:
|
|
|
- n = int(1.0 / self.prob)
|
|
|
- if n > 0:
|
|
|
- if np.random.randint(0, n) == 0:
|
|
|
- radius = np.random.randint(3, 10)
|
|
|
- if radius % 2 != 1:
|
|
|
- radius = radius + 1
|
|
|
- if radius > 9:
|
|
|
- radius = 9
|
|
|
- sample['image'] = self.apply_im(sample['image'], radius)
|
|
|
-
|
|
|
- return sample
|
|
|
-
|
|
|
-
|
|
|
-class RandomRotate(Transform):
|
|
|
- """对图像进行随机旋转, 模型训练时的数据增强操作。
|
|
|
- 在旋转区间[-rotate_range, rotate_range]内,对图像进行随机旋转,当存在标注图像时,同步进行,
|
|
|
- 并对旋转后的图像和标注图像进行相应的padding。
|
|
|
- Args:
|
|
|
- rotate_range (float): 最大旋转角度。默认为15度。
|
|
|
- im_padding_value (list): 图像padding的值。默认为[127.5, 127.5, 127.5]。
|
|
|
- label_padding_value (int): 标注图像padding的值。默认为255。
|
|
|
- """
|
|
|
-
|
|
|
- def __init__(self,
|
|
|
- rotate_range=15,
|
|
|
- im_padding_value=[127.5, 127.5, 127.5],
|
|
|
- label_padding_value=255):
|
|
|
- super(RandomRotate, self).__init__()
|
|
|
- self.rotate_range = rotate_range
|
|
|
- self.im_padding_value = im_padding_value
|
|
|
- self.label_padding_value = label_padding_value
|
|
|
-
|
|
|
- def apply(self, sample):
|
|
|
- if self.rotate_range > 0:
|
|
|
- h, w, c = sample['image'].shape
|
|
|
- do_rotation = np.random.uniform(-self.rotate_range,
|
|
|
- self.rotate_range)
|
|
|
- pc = (w // 2, h // 2)
|
|
|
- r = cv2.getRotationMatrix2D(pc, do_rotation, 1.0)
|
|
|
- cos = np.abs(r[0, 0])
|
|
|
- sin = np.abs(r[0, 1])
|
|
|
-
|
|
|
- nw = int((h * sin) + (w * cos))
|
|
|
- nh = int((h * cos) + (w * sin))
|
|
|
-
|
|
|
- (cx, cy) = pc
|
|
|
- r[0, 2] += (nw / 2) - cx
|
|
|
- r[1, 2] += (nh / 2) - cy
|
|
|
- dsize = (nw, nh)
|
|
|
- rot_ims = list()
|
|
|
- for i in range(0, c, 3):
|
|
|
- ori_im = sample['image'][:, :, i:i + 3]
|
|
|
- rot_im = cv2.warpAffine(
|
|
|
- ori_im,
|
|
|
- r,
|
|
|
- dsize=dsize,
|
|
|
- flags=cv2.INTER_LINEAR,
|
|
|
- borderMode=cv2.BORDER_CONSTANT,
|
|
|
- borderValue=self.im_padding_value[i:i + 3])
|
|
|
- rot_ims.append(rot_im)
|
|
|
- sample['image'] = np.concatenate(rot_ims, axis=-1)
|
|
|
- if 'mask' in sample:
|
|
|
- sample['mask'] = cv2.warpAffine(
|
|
|
- sample['mask'],
|
|
|
- r,
|
|
|
- dsize=dsize,
|
|
|
- flags=cv2.INTER_NEAREST,
|
|
|
- borderMode=cv2.BORDER_CONSTANT,
|
|
|
- borderValue=self.label_padding_value)
|
|
|
-
|
|
|
- return sample
|
|
|
-
|
|
|
-
|
|
|
-class RandomScaleAspect(Transform):
|
|
|
- """裁剪并resize回原始尺寸的图像和标注图像。
|
|
|
- 按照一定的面积比和宽高比对图像进行裁剪,并reszie回原始图像的图像,当存在标注图时,同步进行。
|
|
|
- Args:
|
|
|
- min_scale (float):裁取图像占原始图像的面积比,取值[0,1],为0时则返回原图。默认为0.5。
|
|
|
- aspect_ratio (float): 裁取图像的宽高比范围,非负值,为0时返回原图。默认为0.33。
|
|
|
- """
|
|
|
-
|
|
|
- def __init__(self, min_scale=0.5, aspect_ratio=0.33):
|
|
|
- super(RandomScaleAspect, self).__init__()
|
|
|
- self.min_scale = min_scale
|
|
|
- self.aspect_ratio = aspect_ratio
|
|
|
-
|
|
|
- def apply(self, sample):
|
|
|
- if self.min_scale != 0 and self.aspect_ratio != 0:
|
|
|
- img_height = sample['image'].shape[0]
|
|
|
- img_width = sample['image'].shape[1]
|
|
|
- for i in range(0, 10):
|
|
|
- area = img_height * img_width
|
|
|
- target_area = area * np.random.uniform(self.min_scale, 1.0)
|
|
|
- aspectRatio = np.random.uniform(self.aspect_ratio,
|
|
|
- 1.0 / self.aspect_ratio)
|
|
|
-
|
|
|
- dw = int(np.sqrt(target_area * 1.0 * aspectRatio))
|
|
|
- dh = int(np.sqrt(target_area * 1.0 / aspectRatio))
|
|
|
- if (np.random.randint(10) < 5):
|
|
|
- tmp = dw
|
|
|
- dw = dh
|
|
|
- dh = tmp
|
|
|
-
|
|
|
- if (dh < img_height and dw < img_width):
|
|
|
- h1 = np.random.randint(0, img_height - dh)
|
|
|
- w1 = np.random.randint(0, img_width - dw)
|
|
|
-
|
|
|
- sample['image'] = sample['image'][h1:(h1 + dh), w1:(w1 + dw
|
|
|
- ), :]
|
|
|
- sample['image'] = cv2.resize(
|
|
|
- sample['image'], (img_width, img_height),
|
|
|
- interpolation=cv2.INTER_LINEAR)
|
|
|
- if sample['image'].ndim < 3:
|
|
|
- sample['image'] = np.expand_dims(
|
|
|
- sample['image'], axis=-1)
|
|
|
-
|
|
|
- if 'mask' in sample:
|
|
|
- sample['mask'] = sample['mask'][h1:(h1 + dh), w1:(w1 +
|
|
|
- dw)]
|
|
|
- sample['mask'] = cv2.resize(
|
|
|
- sample['mask'], (img_width, img_height),
|
|
|
- interpolation=cv2.INTER_NEAREST)
|
|
|
- break
|
|
|
- return sample
|
|
|
-
|
|
|
-
|
|
|
-class Clip(Transform):
|
|
|
- """
|
|
|
- 对图像上超出一定范围的数据进行截断。
|
|
|
- Args:
|
|
|
- min_val (list): 裁剪的下限,小于min_val的数值均设为min_val. 默认值0.
|
|
|
- max_val (list): 裁剪的上限,大于max_val的数值均设为max_val. 默认值255.0.
|
|
|
- """
|
|
|
-
|
|
|
- def __init__(self, min_val=[0, 0, 0], max_val=[255.0, 255.0, 255.0]):
|
|
|
- if not (isinstance(min_val, list) and isinstance(max_val, list)):
|
|
|
- raise ValueError("{}: input type is invalid.".format(self))
|
|
|
- super(Clip, self).__init__()
|
|
|
- self.min_val = min_val
|
|
|
- self.max_val = max_val
|
|
|
-
|
|
|
- def apply_im(self, image):
|
|
|
- for k in range(image.shape[2]):
|
|
|
- np.clip(
|
|
|
- image[:, :, k],
|
|
|
- self.min_val[k],
|
|
|
- self.max_val[k],
|
|
|
- out=image[:, :, k])
|
|
|
- return image
|
|
|
-
|
|
|
- def apply(self, sample):
|
|
|
- sample['image'] = self.apply_im(sample['image'])
|
|
|
- return sample
|
|
|
-
|
|
|
-
|
|
|
-class ComposedSegTransforms(Compose):
|
|
|
- """ 语义分割模型(UNet/DeepLabv3p)的图像处理流程,具体如下
|
|
|
- 训练阶段:
|
|
|
- 1. 随机对图像以0.5的概率水平翻转,若random_horizontal_flip为False,则跳过此步骤
|
|
|
- 2. 按不同的比例随机Resize原图, 处理方式参考[paddlex.seg.transforms.ResizeRangeScaling](#resizerangescaling)。若min_max_size为None,则跳过此步骤
|
|
|
- 3. 从原图中随机crop出大小为train_crop_size大小的子图,如若crop出来的图小于train_crop_size,则会将图padding到对应大小
|
|
|
- 4. 图像归一化
|
|
|
- 预测阶段:
|
|
|
- 1. 将图像的最长边resize至(min_max_size[0] + min_max_size[1])//2, 短边按比例resize。若min_max_size为None,则跳过此步骤
|
|
|
- 2. 图像归一化
|
|
|
- Args:
|
|
|
- mode(str): Transforms所处的阶段,包括`train', 'eval'或'test'
|
|
|
- min_max_size(list): 用于对图像进行resize,具体作用参见上述步骤。
|
|
|
- train_crop_size(list): 训练过程中随机裁剪原图用于训练,具体作用参见上述步骤。此参数仅在mode为`train`时生效。
|
|
|
- mean(list): 图像均值, 默认为[0.485, 0.456, 0.406]。
|
|
|
- std(list): 图像方差,默认为[0.229, 0.224, 0.225]。
|
|
|
- random_horizontal_flip(bool): 数据增强,是否随机水平翻转图像,此参数仅在mode为`train`时生效。
|
|
|
- """
|
|
|
-
|
|
|
- def __init__(self,
|
|
|
- mode,
|
|
|
- min_max_size=[400, 600],
|
|
|
- train_crop_size=[512, 512],
|
|
|
- mean=[0.5, 0.5, 0.5],
|
|
|
- std=[0.5, 0.5, 0.5],
|
|
|
- random_horizontal_flip=True):
|
|
|
- if mode == 'train':
|
|
|
- # 训练时的transforms,包含数据增强
|
|
|
- if min_max_size is None:
|
|
|
- transforms = [
|
|
|
- RandomPaddingCrop(crop_size=train_crop_size), Normalize(
|
|
|
- mean=mean, std=std)
|
|
|
- ]
|
|
|
- else:
|
|
|
- transforms = [
|
|
|
- ResizeRangeScaling(
|
|
|
- min_value=min(min_max_size),
|
|
|
- max_value=max(min_max_size)),
|
|
|
- RandomPaddingCrop(crop_size=train_crop_size), Normalize(
|
|
|
- mean=mean, std=std)
|
|
|
- ]
|
|
|
- if random_horizontal_flip:
|
|
|
- transforms.insert(0, RandomHorizontalFlip())
|
|
|
- else:
|
|
|
- # 验证/预测时的transforms
|
|
|
- if min_max_size is None:
|
|
|
- transforms = [Normalize(mean=mean, std=std)]
|
|
|
- else:
|
|
|
- long_size = (min(min_max_size) + max(min_max_size)) // 2
|
|
|
- transforms = [
|
|
|
- ResizeByLong(long_size=long_size), Normalize(
|
|
|
- mean=mean, std=std)
|
|
|
- ]
|
|
|
- super(ComposedSegTransforms, self).__init__(transforms)
|
|
|
-
|
|
|
-
|
|
|
-def _resize_long(im, long_size=224, interpolation=cv2.INTER_LINEAR):
|
|
|
- value = max(im.shape[0], im.shape[1])
|
|
|
- scale = float(long_size) / float(value)
|
|
|
- resized_width = int(round(im.shape[1] * scale))
|
|
|
- resized_height = int(round(im.shape[0] * scale))
|
|
|
-
|
|
|
- im_dims = im.ndim
|
|
|
- im = cv2.resize(
|
|
|
- im, (resized_width, resized_height), interpolation=interpolation)
|
|
|
- if im_dims >= 3 and im.ndim < 3:
|
|
|
- im = np.expand_dims(im, axis=-1)
|
|
|
- return im
|