def __init__(self, kernel_size, iterations=1, random=True): if isinstance(kernel_size, int): kernel_size = kernel_size, kernel_size + 1 elif not mmcv.is_tuple_of(kernel_size, int) or len(kernel_size) != 2: raise ValueError('kernel_size must be an int or a tuple of 2 int, ' f'but got {kernel_size}') if isinstance(iterations, int): iterations = iterations, iterations + 1 elif not mmcv.is_tuple_of(iterations, int) or len(iterations) != 2: raise ValueError('iterations must be an int or a tuple of 2 int, ' f'but got {iterations}') self.random = random if self.random: min_kernel, max_kernel = kernel_size self.iterations = iterations self.kernels = [ cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (size, size)) for size in range(min_kernel, max_kernel) ] else: erode_ksize, dilate_ksize = kernel_size self.iterations = iterations self.kernels = [ cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (erode_ksize, erode_ksize)), cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (dilate_ksize, dilate_ksize)) ]
def __init__(self, keys, crop_size, scale=(0.08, 1.0), ratio=(3. / 4., 4. / 3.), interpolation='bilinear'): assert keys, 'Keys should not be empty.' if isinstance(crop_size, int): crop_size = (crop_size, crop_size) elif not mmcv.is_tuple_of(crop_size, int): raise TypeError('"crop_size" must be an integer ' 'or a tuple of integers, but got ' f'{type(crop_size)}') if not mmcv.is_tuple_of(scale, float): raise TypeError('"scale" must be a tuple of float, ' f'but got {type(scale)}') if not mmcv.is_tuple_of(ratio, float): raise TypeError('"ratio" must be a tuple of float, ' f'but got {type(ratio)}') self.keys = keys self.crop_size = crop_size self.scale = scale self.ratio = ratio self.interpolation = interpolation
def __init__(self, area_range=(0.08, 1.0), aspect_ratio_range=(3 / 4, 4 / 3), lazy=False): self.area_range = area_range self.aspect_ratio_range = aspect_ratio_range self.lazy = lazy if not mmcv.is_tuple_of(self.area_range, float): raise TypeError(f'Area_range must be a tuple of float, ' f'but got {type(area_range)}') if not mmcv.is_tuple_of(self.aspect_ratio_range, float): raise TypeError(f'Aspect_ratio_range must be a tuple of float, ' f'but got {type(aspect_ratio_range)}')
def __init__(self, keys, crop_size, crop_pos=None): if not mmcv.is_tuple_of(crop_size, int): raise TypeError( 'Elements of crop_size must be int and crop_size must be' f' tuple, but got {type(crop_size[0])} in {type(crop_size)}') if not mmcv.is_tuple_of(crop_pos, int) and (crop_pos is not None): raise TypeError( 'Elements of crop_pos must be int and crop_pos must be' f' tuple or None, but got {type(crop_pos[0])} in ' f'{type(crop_pos)}') self.keys = keys self.crop_size = crop_size self.crop_pos = crop_pos
def __init__(self, channels, ratio=4, conv_cfg=None, act_cfg=(dict(type='ReLU'), dict(type='HSigmoid', bias=3.0, divisor=6.0)), init_cfg=None): super().__init__(init_cfg=init_cfg) if isinstance(act_cfg, dict): act_cfg = (act_cfg, act_cfg) assert len(act_cfg) == 2 assert mmcv.is_tuple_of(act_cfg, dict) self.channels = channels self.expansion = 4 # for a1, b1, a2, b2 self.global_avgpool = nn.AdaptiveAvgPool2d(1) self.conv1 = ConvModule(in_channels=channels, out_channels=int(channels / ratio), kernel_size=1, stride=1, conv_cfg=conv_cfg, act_cfg=act_cfg[0]) self.conv2 = ConvModule(in_channels=int(channels / ratio), out_channels=channels * self.expansion, kernel_size=1, stride=1, conv_cfg=conv_cfg, act_cfg=act_cfg[1])
def __init__(self, arch='small', conv_cfg=None, norm_cfg=dict(type='BN'), out_indices=(0, 1, 12), frozen_stages=-1, reduction_factor=1, norm_eval=False, with_cp=False): super(MobileNetV3, self).__init__() assert arch in self.arch_settings assert isinstance(reduction_factor, int) and reduction_factor > 0 assert mmcv.is_tuple_of(out_indices, int) for index in out_indices: if index not in range(0, len(self.arch_settings[arch]) + 2): raise ValueError( 'the item in out_indices must in ' f'range(0, {len(self.arch_settings[arch])+2}). ' f'But received {index}') if frozen_stages not in range(-1, len(self.arch_settings[arch]) + 2): raise ValueError('frozen_stages must be in range(-1, ' f'{len(self.arch_settings[arch])+2}). ' f'But received {frozen_stages}') self.arch = arch self.conv_cfg = conv_cfg self.norm_cfg = norm_cfg self.out_indices = out_indices self.frozen_stages = frozen_stages self.reduction_factor = reduction_factor self.norm_eval = norm_eval self.with_cp = with_cp self.layers = self._make_layer()
def __init__(self, channels, ratio=16, conv_cfg=None, act_cfg=(dict(type='ReLU'), dict(type='HSigmoid', bias=3.0, divisor=6.0))): super(SELayer, self).__init__() if isinstance(act_cfg, dict): act_cfg = (act_cfg, act_cfg) assert len(act_cfg) == 2 assert mmcv.is_tuple_of(act_cfg, dict) self.global_avgpool = nn.AdaptiveAvgPool2d(1) self.conv1 = ConvModule(in_channels=channels, out_channels=make_divisible( channels // ratio, 8), kernel_size=1, stride=1, conv_cfg=conv_cfg, act_cfg=act_cfg[0]) self.conv2 = ConvModule(in_channels=make_divisible( channels // ratio, 8), out_channels=channels, kernel_size=1, stride=1, conv_cfg=conv_cfg, act_cfg=act_cfg[1])
def __init__(self, module_keys, interp_mode='lerp', interp_cfg=None, interval=-1, start_iter=0): super().__init__() assert isinstance(module_keys, str) or mmcv.is_tuple_of( module_keys, str) self.module_keys = (module_keys, ) if isinstance(module_keys, str) else module_keys # sanity check for the format of module keys for k in self.module_keys: assert k.endswith( '_ema'), 'You should give keys that end with "_ema".' self.interp_mode = interp_mode self.interp_cfg = dict() if interp_cfg is None else deepcopy( interp_cfg) self.interval = interval self.start_iter = start_iter assert hasattr( self, interp_mode ), f'Currently, we do not support {self.interp_mode} for EMA.' self.interp_func = partial( getattr(self, interp_mode), **self.interp_cfg)
def __init__(self, input_size, scale=(256, 320)): if isinstance(input_size, int): self.input_size = (input_size, input_size) else: self.input_size = input_size assert mmcv.is_tuple_of(self.input_size, int) self.scale = scale
def __init__(self, channels, ratio=32, conv_cfg=None, act_cfg=(dict(type='ReLU'), dict(type='Sigmoid'))): super().__init__() if isinstance(act_cfg, dict): act_cfg = (act_cfg, act_cfg) assert len(act_cfg) == 2 assert mmcv.is_tuple_of(act_cfg, dict) self.pool_h = nn.AdaptiveAvgPool2d((None, 1)) self.pool_w = nn.AdaptiveAvgPool2d((1, None)) mip = max(8, channels // ratio) self.conv1 = nn.Conv2d(channels, mip, kernel_size=1, stride=1, padding=0) self.bn1 = nn.BatchNorm2d(mip) self.act = h_swish() self.conv_h = nn.Conv2d(mip, channels, kernel_size=1, stride=1, padding=0) self.conv_w = nn.Conv2d(mip, channels, kernel_size=1, stride=1, padding=0)
def __init__(self, channels, ratio=16, conv_cfg=None, norm_cfg=None, act_cfg=(dict(type='ReLU'), dict(type='Sigmoid'))): super().__init__() if isinstance(act_cfg, dict): act_cfg = (act_cfg, act_cfg) assert len(act_cfg) == 2 assert mmcv.is_tuple_of(act_cfg, dict) self.channels = channels total_channel = sum(channels) self.conv1 = ConvModule(in_channels=total_channel, out_channels=int(total_channel / ratio), kernel_size=1, stride=1, conv_cfg=conv_cfg, norm_cfg=norm_cfg, act_cfg=act_cfg[0]) self.conv2 = ConvModule(in_channels=int(total_channel / ratio), out_channels=total_channel, kernel_size=1, stride=1, conv_cfg=conv_cfg, norm_cfg=norm_cfg, act_cfg=act_cfg[1])
def __init__(self, channels, squeeze_channels=None, ratio=16, divisor=8, bias='auto', conv_cfg=None, act_cfg=(dict(type='ReLU'), dict(type='Sigmoid')), init_cfg=None): super(SELayer, self).__init__(init_cfg) if isinstance(act_cfg, dict): act_cfg = (act_cfg, act_cfg) assert len(act_cfg) == 2 assert mmcv.is_tuple_of(act_cfg, dict) self.global_avgpool = nn.AdaptiveAvgPool2d(1) if squeeze_channels is None: squeeze_channels = make_divisible(channels // ratio, divisor) assert isinstance(squeeze_channels, int) and squeeze_channels > 0, \ '"squeeze_channels" should be a positive integer, but get ' + \ f'{squeeze_channels} instead.' self.conv1 = ConvModule(in_channels=channels, out_channels=squeeze_channels, kernel_size=1, stride=1, bias=bias, conv_cfg=conv_cfg, act_cfg=act_cfg[0]) self.conv2 = ConvModule(in_channels=squeeze_channels, out_channels=channels, kernel_size=1, stride=1, bias=bias, conv_cfg=conv_cfg, act_cfg=act_cfg[1])
def __init__(self, channels, ratio=16, conv_cfg=None, norm_cfg=None, act_cfg=(dict(type='ReLU'), dict(type='Sigmoid'))): super().__init__() if isinstance(act_cfg, dict): act_cfg = (act_cfg, act_cfg) assert len(act_cfg) == 2 assert mmcv.is_tuple_of(act_cfg, dict) self.global_avgpool = nn.AdaptiveAvgPool2d(1) self.conv1 = ConvModule(in_channels=channels, out_channels=int(channels / ratio), kernel_size=1, stride=1, conv_cfg=conv_cfg, norm_cfg=norm_cfg, act_cfg=act_cfg[0]) self.conv2 = ConvModule(in_channels=int(channels / ratio), out_channels=channels, kernel_size=1, stride=1, conv_cfg=conv_cfg, norm_cfg=norm_cfg, act_cfg=act_cfg[1])
def __init__(self, clip_len, body_segments, aug_segments, aug_ratio, frame_interval=1, test_interval=6, start_index=1, temporal_jitter=False, mode='train'): super().__init__(clip_len, frame_interval=frame_interval, start_index=start_index, temporal_jitter=temporal_jitter) self.body_segments = body_segments self.aug_segments = aug_segments self.aug_ratio = _pair(aug_ratio) if not mmcv.is_tuple_of(self.aug_ratio, (int, float)): raise TypeError(f'aug_ratio should be int, float' f'or tuple of int and float, ' f'but got {type(aug_ratio)}') assert len(self.aug_ratio) == 2 assert mode in ['train', 'val', 'test'] self.mode = mode self.test_interval = test_interval
def __init__(self, keys, crop_sizes, unknown_source='alpha', interpolations='bilinear'): if 'alpha' not in keys: raise ValueError(f'"alpha" must be in keys, but got {keys}') self.keys = keys if not isinstance(crop_sizes, list): raise TypeError( f'Crop sizes must be list, but got {type(crop_sizes)}.') self.crop_sizes = [_pair(crop_size) for crop_size in crop_sizes] if not mmcv.is_tuple_of(self.crop_sizes[0], int): raise TypeError('Elements of crop_sizes must be int or tuple of ' f'int, but got {type(self.crop_sizes[0][0])}.') if unknown_source not in ['alpha', 'trimap']: raise ValueError('unknown_source must be "alpha" or "trimap", ' f'but got {unknown_source}') elif unknown_source not in keys: # it could only be trimap, since alpha is checked before raise ValueError( 'if unknown_source is "trimap", it must also be set in keys') self.unknown_source = unknown_source if isinstance(interpolations, str): self.interpolations = [interpolations] * len(self.keys) elif mmcv.is_list_of(interpolations, str) and len(interpolations) == len(self.keys): self.interpolations = interpolations else: raise TypeError( 'interpolations must be a str or list of str with ' f'the same length as keys, but got {interpolations}')
def __init__(self, crop_size): if mmcv.is_tuple_of(crop_size, int): assert len(crop_size) == 2, 'length of crop_size must be 2.' elif not isinstance(crop_size, int): raise TypeError('crop_size must be int or a tuple of int, but got ' f'{type(crop_size)}') self.crop_size = _pair(crop_size)
def __init__(self, keys, crop_size, random_crop=True): if not mmcv.is_tuple_of(crop_size, int): raise TypeError( 'Elements of crop_size must be int and crop_size must be' f' tuple, but got {type(crop_size[0])} in {type(crop_size)}') self.keys = keys self.crop_size = crop_size self.random_crop = random_crop
def __init__(self, input_size, scale=(0.08, 1.0), ratio=(3. / 4., 4. / 3.)): if isinstance(input_size, int): self.input_size = (input_size, input_size) else: self.input_size = input_size assert mmcv.is_tuple_of(self.input_size, int) self.scale = scale self.ratio = ratio
def test_is_seq_of(): assert mmcv.is_seq_of([1.0, 2.0, 3.0], float) assert mmcv.is_seq_of([(1, ), (2, ), (3, )], tuple) assert mmcv.is_seq_of((1.0, 2.0, 3.0), float) assert mmcv.is_list_of([1.0, 2.0, 3.0], float) assert not mmcv.is_seq_of((1.0, 2.0, 3.0), float, seq_type=list) assert not mmcv.is_tuple_of([1.0, 2.0, 3.0], float) assert not mmcv.is_seq_of([1.0, 2, 3], int) assert not mmcv.is_seq_of((1.0, 2, 3), int)
def __init__(self, keys, bd_ratio_range=(0.1, 0.4), test_mode=False): if 'seg' not in keys: raise ValueError(f'"seg" must be in keys, but got {keys}') if (not mmcv.is_tuple_of(bd_ratio_range, float) or len(bd_ratio_range) != 2): raise TypeError('bd_ratio_range must be a tuple of 2 int, but got ' f'{bd_ratio_range}') self.keys = keys self.bd_ratio_range = bd_ratio_range self.test_mode = test_mode
def __init__(self, bbox_enlarge_range): assert (is_tuple_of(bbox_enlarge_range, float) and len(bbox_enlarge_range) == 3) \ or isinstance(bbox_enlarge_range, float), \ f'Invalid arguments bbox_enlarge_range {bbox_enlarge_range}' if isinstance(bbox_enlarge_range, float): bbox_enlarge_range = [bbox_enlarge_range] * 3 self.bbox_enlarge_range = np.array(bbox_enlarge_range, dtype=np.float32)[np.newaxis, :]
def __init__(self, arch='small', conv_cfg=None, norm_cfg=dict(type='BN'), out_indices=(0, 1, 12), frozen_stages=-1, reduction_factor=1, norm_eval=False, with_cp=False, pretrained=None, init_cfg=None): super(MobileNetV3, self).__init__(init_cfg) self.pretrained = pretrained assert not (init_cfg and pretrained), \ 'init_cfg and pretrained cannot be setting at the same time' if isinstance(pretrained, str): warnings.warn('DeprecationWarning: pretrained is a deprecated, ' 'please use "init_cfg" instead') self.init_cfg = dict(type='Pretrained', checkpoint=pretrained) elif pretrained is None: if init_cfg is None: self.init_cfg = [ dict(type='Kaiming', layer='Conv2d'), dict( type='Constant', val=1, layer=['_BatchNorm', 'GroupNorm']) ] else: raise TypeError('pretrained must be a str or None') assert arch in self.arch_settings assert isinstance(reduction_factor, int) and reduction_factor > 0 assert mmcv.is_tuple_of(out_indices, int) for index in out_indices: if index not in range(0, len(self.arch_settings[arch]) + 2): raise ValueError( 'the item in out_indices must in ' f'range(0, {len(self.arch_settings[arch])+2}). ' f'But received {index}') if frozen_stages not in range(-1, len(self.arch_settings[arch]) + 2): raise ValueError('frozen_stages must be in range(-1, ' f'{len(self.arch_settings[arch])+2}). ' f'But received {frozen_stages}') self.arch = arch self.conv_cfg = conv_cfg self.norm_cfg = norm_cfg self.out_indices = out_indices self.frozen_stages = frozen_stages self.reduction_factor = reduction_factor self.norm_eval = norm_eval self.with_cp = with_cp self.layers = self._make_layer()
def __init__(self, crop_size, groups): self.crop_size = _pair(crop_size) self.groups = groups if not mmcv.is_tuple_of(self.crop_size, int): raise TypeError( 'Crop size must be int or tuple of int, but got {}'.format( type(crop_size))) if not isinstance(groups, int): raise TypeError(f'Groups must be int, but got {type(groups)}.') if groups <= 0: raise ValueError('Groups must be positive.')
def __init__(self, keys, degrees): if isinstance(degrees, (int, float)): if degrees < 0.0: raise ValueError('Degrees must be positive if it is a number.') else: degrees = (-degrees, degrees) elif not mmcv.is_tuple_of(degrees, (int, float)): raise TypeError(f'Degrees must be float | int or tuple of float | ' 'int, but got ' f'{type(degrees)}.') self.keys = keys self.degrees = degrees
def __init__(self, fg_thr=0.2, border_width=25, erode_ksize=3, dilate_ksize=5, erode_iter_range=(10, 20), dilate_iter_range=(3, 7), blur_ksizes=[(21, 21), (31, 31), (41, 41)]): if not isinstance(fg_thr, float): raise TypeError(f'fg_thr must be a float, but got {type(fg_thr)}') if not isinstance(border_width, int): raise TypeError( f'border_width must be an int, but got {type(border_width)}') if not isinstance(erode_ksize, int): raise TypeError( f'erode_ksize must be an int, but got {type(erode_ksize)}') if not isinstance(dilate_ksize, int): raise TypeError( f'dilate_ksize must be an int, but got {type(dilate_ksize)}') if (not mmcv.is_tuple_of(erode_iter_range, int) or len(erode_iter_range) != 2): raise TypeError('erode_iter_range must be a tuple of 2 int, ' f'but got {erode_iter_range}') if (not mmcv.is_tuple_of(dilate_iter_range, int) or len(dilate_iter_range) != 2): raise TypeError('dilate_iter_range must be a tuple of 2 int, ' f'but got {dilate_iter_range}') if not mmcv.is_list_of(blur_ksizes, tuple): raise TypeError( f'blur_ksizes must be a list of tuple, but got {blur_ksizes}') self.fg_thr = fg_thr self.border_width = border_width self.erode_ksize = erode_ksize self.dilate_ksize = dilate_ksize self.erode_iter_range = erode_iter_range self.dilate_iter_range = dilate_iter_range self.blur_ksizes = blur_ksizes
def __init__(self, channels, ratio=16, conv_cfg=None, act_cfg=(dict(type='ReLU'), dict(type='Sigmoid'))): super().__init__() if isinstance(act_cfg, dict): act_cfg = (act_cfg, act_cfg) assert len(act_cfg) == 2 assert mmcv.is_tuple_of(act_cfg, dict) self.global_avgpool = nn.AdaptiveAvgPool2d(1) # self.conv = nn.Conv1d(1, 1, kernel_size=k_size, padding=(k_size - 1) // 2, bias=False) self.conv = nn.Conv1d(1, 1, kernel_size=3, padding=1, bias=False) self.sigmoid = nn.Sigmoid()
def __init__(self, in_channels, vote_per_seed=1, gt_per_seed=3, num_points=-1, conv_channels=(16, 16), conv_cfg=dict(type='Conv1d'), norm_cfg=dict(type='BN1d'), act_cfg=dict(type='ReLU'), norm_feats=True, with_res_feat=True, vote_xyz_range=None, vote_loss=None): super().__init__() self.in_channels = in_channels self.vote_per_seed = vote_per_seed self.gt_per_seed = gt_per_seed self.num_points = num_points self.norm_feats = norm_feats self.with_res_feat = with_res_feat assert vote_xyz_range is None or is_tuple_of(vote_xyz_range, float) self.vote_xyz_range = vote_xyz_range if vote_loss is not None: self.vote_loss = build_loss(vote_loss) prev_channels = in_channels vote_conv_list = list() for k in range(len(conv_channels)): vote_conv_list.append( ConvModule( prev_channels, conv_channels[k], 1, padding=0, conv_cfg=conv_cfg, norm_cfg=norm_cfg, act_cfg=act_cfg, bias=True, inplace=True)) prev_channels = conv_channels[k] self.vote_conv = nn.Sequential(*vote_conv_list) # conv_out predicts coordinate and residual features if with_res_feat: out_channel = (3 + in_channels) * self.vote_per_seed else: out_channel = 3 * self.vote_per_seed self.conv_out = nn.Conv1d(prev_channels, out_channel, 1)
def forward(ctx, rois, pts, pts_feature, out_size, max_pts_per_voxel, mode): """ Args: rois (torch.Tensor): [N, 7], in LiDAR coordinate, (x, y, z) is the bottom center of rois. pts (torch.Tensor): [npoints, 3], coordinates of input points. pts_feature (torch.Tensor): [npoints, C], features of input points. out_size (int or tuple): The size of output features. n or [n1, n2, n3]. max_pts_per_voxel (int): The maximum number of points per voxel. Default: 128. mode (int): Pooling method of RoIAware, 0 (max pool) or 1 (average pool). Returns: pooled_features (torch.Tensor): [N, out_x, out_y, out_z, C], output pooled features. """ if isinstance(out_size, int): out_x = out_y = out_z = out_size else: assert len(out_size) == 3 assert mmcv.is_tuple_of(out_size, int) out_x, out_y, out_z = out_size num_rois = rois.shape[0] num_channels = pts_feature.shape[-1] num_pts = pts.shape[0] pooled_features = pts_feature.new_zeros( (num_rois, out_x, out_y, out_z, num_channels)) argmax = pts_feature.new_zeros( (num_rois, out_x, out_y, out_z, num_channels), dtype=torch.int) pts_idx_of_voxels = pts_feature.new_zeros( (num_rois, out_x, out_y, out_z, max_pts_per_voxel), dtype=torch.int) ext_module.roiaware_pool3d_forward(rois, pts, pts_feature, argmax, pts_idx_of_voxels, pooled_features, pool_method=mode) ctx.roiaware_pool3d_for_backward = (pts_idx_of_voxels, argmax, mode, num_pts, num_channels) return pooled_features
def __init__(self, module_keys, interp_mode='lerp', interp_cfg=None, interval=-1, start_iter=0, momentum_policy='fixed', momentum_cfg=None): super().__init__() # check args assert interp_mode in self._registered_interp_funcs, ( 'Supported ' f'interpolation functions are {self._registered_interp_funcs}, ' f'but got {interp_mode}') assert momentum_policy in self._registered_momentum_updaters, ( 'Supported momentum policy are' f'{self._registered_momentum_updaters},' f' but got {momentum_policy}') assert isinstance(module_keys, str) or mmcv.is_tuple_of( module_keys, str) self.module_keys = (module_keys, ) if isinstance(module_keys, str) else module_keys # sanity check for the format of module keys for k in self.module_keys: assert k.endswith( '_ema'), 'You should give keys that end with "_ema".' self.interp_mode = interp_mode self.interp_cfg = dict() if interp_cfg is None else deepcopy( interp_cfg) self.interval = interval self.start_iter = start_iter assert hasattr( self, interp_mode ), f'Currently, we do not support {self.interp_mode} for EMA.' self.interp_func = getattr(self, interp_mode) self.momentum_cfg = dict() if momentum_cfg is None else deepcopy( momentum_cfg) self.momentum_policy = momentum_policy if momentum_policy != 'fixed': assert hasattr( self, momentum_policy ), f'Currently, we do not support {self.momentum_policy} for EMA.' self.momentum_updater = getattr(self, momentum_policy)
def __init__(self, keys, scale=None, keep_ratio=False, size_factor=None, max_size=None, interpolation='bilinear', backend=None, output_keys=None): assert keys, 'Keys should not be empty.' if output_keys: assert len(output_keys) == len(keys) else: output_keys = keys if size_factor: assert scale is None, ('When size_factor is used, scale should ', f'be None. But received {scale}.') assert keep_ratio is False, ('When size_factor is used, ' 'keep_ratio should be False.') if max_size: assert size_factor is not None, ( 'When max_size is used, ' f'size_factor should also be set. But received {size_factor}.') if isinstance(scale, float): if scale <= 0: raise ValueError(f'Invalid scale {scale}, must be positive.') elif mmcv.is_tuple_of(scale, int): max_long_edge = max(scale) max_short_edge = min(scale) if max_short_edge == -1: # assign np.inf to long edge for rescaling short edge later. scale = (np.inf, max_long_edge) elif scale is not None: raise TypeError( f'Scale must be None, float or tuple of int, but got ' f'{type(scale)}.') self.keys = keys self.output_keys = output_keys self.scale = scale self.size_factor = size_factor self.max_size = max_size self.keep_ratio = keep_ratio self.interpolation = interpolation self.backend = backend