|
- # Copyright 2022 Huawei Technologies Co., Ltd
- #
- # 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.
- # ============================================================================
-
- from itertools import product
- from math import sqrt
- import math
- import numpy as np
-
- def reglayer_scale(size, num_layer, size_the):
- reg_layer_size = []
- for i in range(num_layer + 1):
- size = math.ceil(size / 2.)
- if i >= 2:
- reg_layer_size += [size]
- if i == num_layer and size_the != 0:
- reg_layer_size += [size - size_the]
- return reg_layer_size
-
- def get_scales(size, size_pattern):
- size_list = []
- for x in size_pattern:
- size_list += [round(x * size, 2)]
- return size_list
-
- def aspect_ratio(num):
- as_ra = []
- for _ in range(num):
- as_ra += [[2, 3]]
- return as_ra
-
- def mk_anchors(size, multiscale_size, size_pattern, step_pattern, num_reglayer=6, param=2):
- cfg = dict()
- # cfg['feature_maps'] = reglayer_scale(size, num_reglayer, param if size >= multiscale_size else 0)
- cfg['feature_maps'] = reglayer_scale(size, num_reglayer, 2)
- cfg['min_dim'] = size
- cfg['steps'] = step_pattern
- cfg['min_sizes'] = get_scales(multiscale_size, size_pattern[:-1])
- cfg['max_sizes'] = get_scales(multiscale_size, size_pattern[1:])
- cfg['aspect_ratios'] = aspect_ratio(num_reglayer)
- cfg['variance'] = [0.1, 0.2]
- cfg['clip'] = True
- return cfg
-
- def anchors(cfg):
- return mk_anchors(cfg.model['input_size'],
- cfg.model['input_size'],
- cfg.model['anchor_config']['size_pattern'],
- cfg.model['anchor_config']['step_pattern'])
-
-
- class PriorBox():
- """Compute priorbox coordinates in center-offset form for each source
- feature map.
- Note:
- This 'layer' has changed between versions of the original SSD
- paper, so we include both versions, but note v2 is the most tested and most
- recent version of the paper.
- """
-
- def __init__(self, config):
- super().__init__()
- cfg = anchors(config)
- self.image_size = cfg['min_dim']
- # number of priors for feature map location (either 4 or 6)
- self.num_priors = len(cfg['aspect_ratios'])
- self.variance = cfg['variance'] or [0.1]
- self.feature_maps = cfg['feature_maps']
- self.min_sizes = cfg['min_sizes']
- self.max_sizes = cfg['max_sizes']
- self.steps = cfg['steps']
- self.aspect_ratios = cfg['aspect_ratios']
- self.clip = cfg['clip']
- for v in self.variance:
- if v <= 0:
- raise ValueError('Variances must be greater than 0')
-
- def forward(self):
- mean = []
- for k, f in enumerate(self.feature_maps):
- for i, j in product(range(f), repeat=2):
- f_k = self.image_size / self.steps[k]
- cx = (j + 0.5) / f_k
- cy = (i + 0.5) / f_k
-
- s_k = self.min_sizes[k]/self.image_size
- mean += [cx, cy, s_k, s_k]
-
- # aspect_ratio: 1
- # rel size: sqrt(s_k * s_(k+1))
- s_k_prime = sqrt(s_k * (self.max_sizes[k]/self.image_size))
- mean += [cx, cy, s_k_prime, s_k_prime]
-
- # rest of aspect ratios
- for ar in self.aspect_ratios[k]:
- mean += [cx, cy, s_k * sqrt(ar), s_k / sqrt(ar)]
- mean += [cx, cy, s_k / sqrt(ar), s_k * sqrt(ar)]
-
- # output = mindspore.Tensor(mean, dtype=mindspore.float32).view(-1, 4)
- output = np.asarray(mean).reshape([-1, 4]).astype(np.float32)
- if self.clip:
- # output = mindspore.ops.clip_by_value(output, clip_value_max=1, clip_value_min=0)
- output = np.clip(output, 0, 1)
- return output
|