Files
insightface/detection/retinaface/rcnn/io/rpn.py
2021-06-19 23:57:15 +08:00

888 lines
37 KiB
Python

"""
RPN:
data =
{'data': [num_images, c, h, w],
'im_info': [num_images, 4] (optional)}
label =
{'gt_boxes': [num_boxes, 5] (optional),
'label': [batch_size, 1] <- [batch_size, num_anchors, feat_height, feat_width],
'bbox_target': [batch_size, num_anchors, feat_height, feat_width],
'bbox_weight': [batch_size, num_anchors, feat_height, feat_width]}
"""
from __future__ import print_function
import sys
import logging
import datetime
import numpy as np
import numpy.random as npr
from ..logger import logger
from ..config import config
from .image import get_image, tensor_vstack, get_crop_image
from ..processing.generate_anchor import generate_anchors, anchors_plane
from ..processing.bbox_transform import bbox_overlaps, bbox_transform, landmark_transform
STAT = {0: 0, 8: 0, 16: 0, 32: 0}
def get_rpn_testbatch(roidb):
"""
return a dict of testbatch
:param roidb: ['image', 'flipped']
:return: data, label, im_info
"""
assert len(roidb) == 1, 'Single batch only'
imgs, roidb = get_image(roidb)
im_array = imgs[0]
im_info = np.array([roidb[0]['im_info']], dtype=np.float32)
data = {'data': im_array, 'im_info': im_info}
label = {}
return data, label, im_info
def get_rpn_batch(roidb):
"""
prototype for rpn batch: data, im_info, gt_boxes
:param roidb: ['image', 'flipped'] + ['gt_boxes', 'boxes', 'gt_classes']
:return: data, label
"""
assert len(roidb) == 1, 'Single batch only'
imgs, roidb = get_image(roidb)
im_array = imgs[0]
im_info = np.array([roidb[0]['im_info']], dtype=np.float32)
# gt boxes: (x1, y1, x2, y2, cls)
if roidb[0]['gt_classes'].size > 0:
gt_inds = np.where(roidb[0]['gt_classes'] != 0)[0]
gt_boxes = np.empty((roidb[0]['boxes'].shape[0], 5), dtype=np.float32)
gt_boxes[:, 0:4] = roidb[0]['boxes'][gt_inds, :]
gt_boxes[:, 4] = roidb[0]['gt_classes'][gt_inds]
else:
gt_boxes = np.empty((0, 5), dtype=np.float32)
data = {'data': im_array, 'im_info': im_info}
label = {'gt_boxes': gt_boxes}
return data, label
def get_crop_batch(roidb):
"""
prototype for rpn batch: data, im_info, gt_boxes
:param roidb: ['image', 'flipped'] + ['gt_boxes', 'boxes', 'gt_classes']
:return: data, label
"""
#assert len(roidb) == 1, 'Single batch only'
data_list = []
label_list = []
imgs, roidb = get_crop_image(roidb)
assert len(imgs) == len(roidb)
for i in range(len(imgs)):
im_array = imgs[i]
im_info = np.array([roidb[i]['im_info']], dtype=np.float32)
# gt boxes: (x1, y1, x2, y2, cls)
if roidb[i]['gt_classes'].size > 0:
gt_inds = np.where(roidb[i]['gt_classes'] != 0)[0]
gt_boxes = np.empty((roidb[i]['boxes'].shape[0], 5),
dtype=np.float32)
gt_boxes[:, 0:4] = roidb[i]['boxes'][gt_inds, :]
gt_boxes[:, 4] = roidb[i]['gt_classes'][gt_inds]
if config.USE_BLUR:
gt_blur = roidb[i]['blur']
if config.FACE_LANDMARK:
#gt_landmarks = np.empty((roidb[i]['landmarks'].shape[0], 11), dtype=np.float32)
gt_landmarks = roidb[i]['landmarks'][gt_inds, :, :]
if config.HEAD_BOX:
gt_boxes_head = np.empty((roidb[i]['boxes_head'].shape[0], 5),
dtype=np.float32)
gt_boxes_head[:, 0:4] = roidb[i]['boxes_head'][gt_inds, :]
gt_boxes_head[:, 4] = roidb[i]['gt_classes'][gt_inds]
else:
gt_boxes = np.empty((0, 5), dtype=np.float32)
if config.USE_BLUR:
gt_blur = np.empty((0, ), dtype=np.float32)
if config.FACE_LANDMARK:
gt_landmarks = np.empty((0, 5, 3), dtype=np.float32)
if config.HEAD_BOX:
gt_boxes_head = np.empty((0, 5), dtype=np.float32)
data = {'data': im_array, 'im_info': im_info}
label = {'gt_boxes': gt_boxes}
if config.USE_BLUR:
label['gt_blur'] = gt_blur
if config.FACE_LANDMARK:
label['gt_landmarks'] = gt_landmarks
if config.HEAD_BOX:
label['gt_boxes_head'] = gt_boxes_head
data_list.append(data)
label_list.append(label)
return data_list, label_list
def assign_anchor_fpn(feat_shape,
gt_label,
im_info,
landmark=False,
prefix='face',
select_stride=0):
"""
assign ground truth boxes to anchor positions
:param feat_shape: infer output shape
:param gt_boxes: assign ground truth
:param im_info: filter out anchors overlapped with edges
:return: tuple
labels: of shape (batch_size, 1) <- (batch_size, num_anchors, feat_height, feat_width)
bbox_targets: of shape (batch_size, num_anchors * 4, feat_height, feat_width)
bbox_weights: mark the assigned anchors
"""
def _unmap(data, count, inds, fill=0):
"""" unmap a subset inds of data into original data of size count """
if len(data.shape) == 1:
ret = np.empty((count, ), dtype=np.float32)
ret.fill(fill)
ret[inds] = data
else:
ret = np.empty((count, ) + data.shape[1:], dtype=np.float32)
ret.fill(fill)
ret[inds, :] = data
return ret
global STAT
DEBUG = False
im_info = im_info[0]
gt_boxes = gt_label['gt_boxes']
# clean up boxes
nonneg = np.where(gt_boxes[:, 4] != -1)[0]
gt_boxes = gt_boxes[nonneg]
if config.USE_BLUR:
gt_blur = gt_label['gt_blur']
gt_blur = gt_blur[nonneg]
if landmark:
gt_landmarks = gt_label['gt_landmarks']
gt_landmarks = gt_landmarks[nonneg]
assert gt_boxes.shape[0] == gt_landmarks.shape[0]
#scales = np.array(scales, dtype=np.float32)
feat_strides = config.RPN_FEAT_STRIDE
bbox_pred_len = 4
landmark_pred_len = 10
if config.USE_BLUR:
gt_boxes[:, 4] = gt_blur
bbox_pred_len = 5
if config.USE_OCCLUSION:
landmark_pred_len = 15
anchors_list = []
anchors_num_list = []
inds_inside_list = []
feat_infos = []
A_list = []
for i in range(len(feat_strides)):
stride = feat_strides[i]
sstride = str(stride)
base_size = config.RPN_ANCHOR_CFG[sstride]['BASE_SIZE']
allowed_border = config.RPN_ANCHOR_CFG[sstride]['ALLOWED_BORDER']
ratios = config.RPN_ANCHOR_CFG[sstride]['RATIOS']
scales = config.RPN_ANCHOR_CFG[sstride]['SCALES']
base_anchors = generate_anchors(base_size=base_size,
ratios=list(ratios),
scales=np.array(scales,
dtype=np.float32),
stride=stride,
dense_anchor=config.DENSE_ANCHOR)
num_anchors = base_anchors.shape[0]
feat_height, feat_width = feat_shape[i][-2:]
feat_stride = feat_strides[i]
feat_infos.append([feat_height, feat_width])
A = num_anchors
A_list.append(A)
K = feat_height * feat_width
all_anchors = anchors_plane(feat_height, feat_width, feat_stride,
base_anchors)
all_anchors = all_anchors.reshape((K * A, 4))
#print('anchor0', stride, all_anchors[0])
total_anchors = int(K * A)
anchors_num_list.append(total_anchors)
# only keep anchors inside the image
inds_inside = np.where(
(all_anchors[:, 0] >= -allowed_border)
& (all_anchors[:, 1] >= -allowed_border)
& (all_anchors[:, 2] < im_info[1] + allowed_border)
& (all_anchors[:, 3] < im_info[0] + allowed_border))[0]
if DEBUG:
print('total_anchors', total_anchors)
print('inds_inside', len(inds_inside))
# keep only inside anchors
anchors = all_anchors[inds_inside, :]
#print('AA', anchors.shape, len(inds_inside))
anchors_list.append(anchors)
inds_inside_list.append(inds_inside)
# Concat anchors from each level
anchors = np.concatenate(anchors_list)
for i in range(1, len(inds_inside_list)):
inds_inside_list[i] = inds_inside_list[i] + sum(anchors_num_list[:i])
inds_inside = np.concatenate(inds_inside_list)
total_anchors = sum(anchors_num_list)
#print('total_anchors', anchors.shape[0], len(inds_inside), file=sys.stderr)
# label: 1 is positive, 0 is negative, -1 is dont care
labels = np.empty((len(inds_inside), ), dtype=np.float32)
labels.fill(-1)
#print('BB', anchors.shape, len(inds_inside))
#print('gt_boxes', gt_boxes.shape, file=sys.stderr)
if gt_boxes.size > 0:
# overlap between the anchors and the gt boxes
# overlaps (ex, gt)
overlaps = bbox_overlaps(anchors.astype(np.float),
gt_boxes.astype(np.float))
argmax_overlaps = overlaps.argmax(axis=1)
#print('AAA', argmax_overlaps.shape)
max_overlaps = overlaps[np.arange(len(inds_inside)), argmax_overlaps]
gt_argmax_overlaps = overlaps.argmax(axis=0)
gt_max_overlaps = overlaps[gt_argmax_overlaps,
np.arange(overlaps.shape[1])]
gt_argmax_overlaps = np.where(overlaps == gt_max_overlaps)[0]
if not config.TRAIN.RPN_CLOBBER_POSITIVES:
# assign bg labels first so that positive labels can clobber them
labels[max_overlaps < config.TRAIN.RPN_NEGATIVE_OVERLAP] = 0
# fg label: for each gt, anchor with highest overlap
if config.TRAIN.RPN_FORCE_POSITIVE:
labels[gt_argmax_overlaps] = 1
# fg label: above threshold IoU
labels[max_overlaps >= config.TRAIN.RPN_POSITIVE_OVERLAP] = 1
if config.TRAIN.RPN_CLOBBER_POSITIVES:
# assign bg labels last so that negative labels can clobber positives
labels[max_overlaps < config.TRAIN.RPN_NEGATIVE_OVERLAP] = 0
else:
labels[:] = 0
fg_inds = np.where(labels == 1)[0]
#print('fg count', len(fg_inds))
# subsample positive labels if we have too many
if config.TRAIN.RPN_ENABLE_OHEM == 0:
fg_inds = np.where(labels == 1)[0]
num_fg = int(config.TRAIN.RPN_FG_FRACTION *
config.TRAIN.RPN_BATCH_SIZE)
if len(fg_inds) > num_fg:
disable_inds = npr.choice(fg_inds,
size=(len(fg_inds) - num_fg),
replace=False)
if DEBUG:
disable_inds = fg_inds[:(len(fg_inds) - num_fg)]
labels[disable_inds] = -1
# subsample negative labels if we have too many
num_bg = config.TRAIN.RPN_BATCH_SIZE - np.sum(labels == 1)
bg_inds = np.where(labels == 0)[0]
if len(bg_inds) > num_bg:
disable_inds = npr.choice(bg_inds,
size=(len(bg_inds) - num_bg),
replace=False)
if DEBUG:
disable_inds = bg_inds[:(len(bg_inds) - num_bg)]
labels[disable_inds] = -1
#fg_inds = np.where(labels == 1)[0]
#num_fg = len(fg_inds)
#num_bg = num_fg*int(1.0/config.TRAIN.RPN_FG_FRACTION-1)
#bg_inds = np.where(labels == 0)[0]
#if len(bg_inds) > num_bg:
# disable_inds = npr.choice(bg_inds, size=(len(bg_inds) - num_bg), replace=False)
# if DEBUG:
# disable_inds = bg_inds[:(len(bg_inds) - num_bg)]
# labels[disable_inds] = -1
else:
fg_inds = np.where(labels == 1)[0]
num_fg = len(fg_inds)
bg_inds = np.where(labels == 0)[0]
num_bg = len(bg_inds)
#print('anchor stat', num_fg, num_bg)
bbox_targets = np.zeros((len(inds_inside), bbox_pred_len),
dtype=np.float32)
if gt_boxes.size > 0:
#print('GT', gt_boxes.shape, gt_boxes[argmax_overlaps, :4].shape)
bbox_targets[:, :] = bbox_transform(anchors,
gt_boxes[argmax_overlaps, :])
#bbox_targets[:,4] = gt_blur
bbox_weights = np.zeros((len(inds_inside), bbox_pred_len),
dtype=np.float32)
#bbox_weights[labels == 1, :] = np.array(config.TRAIN.RPN_BBOX_WEIGHTS)
bbox_weights[labels == 1, 0:4] = 1.0
if bbox_pred_len > 4:
bbox_weights[labels == 1, 4:bbox_pred_len] = 0.1
if landmark:
landmark_targets = np.zeros((len(inds_inside), landmark_pred_len),
dtype=np.float32)
#landmark_weights = np.zeros((len(inds_inside), 10), dtype=np.float32)
landmark_weights = np.zeros((len(inds_inside), landmark_pred_len),
dtype=np.float32)
#landmark_weights[labels == 1, :] = np.array(config.TRAIN.RPN_LANDMARK_WEIGHTS)
if landmark_pred_len == 10:
landmark_weights[labels == 1, :] = 1.0
elif landmark_pred_len == 15:
v = [1.0, 1.0, 0.1] * 5
assert len(v) == 15
landmark_weights[labels == 1, :] = np.array(v)
else:
assert False
#TODO here
if gt_landmarks.size > 0:
#print('AAA',argmax_overlaps)
a_landmarks = gt_landmarks[argmax_overlaps, :, :]
landmark_targets[:] = landmark_transform(anchors, a_landmarks)
invalid = np.where(a_landmarks[:, 0, 2] < 0.0)[0]
#assert len(invalid)==0
#landmark_weights[invalid, :] = np.array(config.TRAIN.RPN_INVALID_LANDMARK_WEIGHTS)
landmark_weights[invalid, :] = 0.0
#if DEBUG:
# _sums = bbox_targets[labels == 1, :].sum(axis=0)
# _squared_sums = (bbox_targets[labels == 1, :] ** 2).sum(axis=0)
# _counts = np.sum(labels == 1)
# means = _sums / (_counts + 1e-14)
# stds = np.sqrt(_squared_sums / _counts - means ** 2)
# print 'means', means
# print 'stdevs', stds
# map up to original set of anchors
#print(labels.shape, total_anchors, inds_inside.shape, inds_inside[0], inds_inside[-1])
labels = _unmap(labels, total_anchors, inds_inside, fill=-1)
bbox_targets = _unmap(bbox_targets, total_anchors, inds_inside, fill=0)
bbox_weights = _unmap(bbox_weights, total_anchors, inds_inside, fill=0)
if landmark:
landmark_targets = _unmap(landmark_targets,
total_anchors,
inds_inside,
fill=0)
landmark_weights = _unmap(landmark_weights,
total_anchors,
inds_inside,
fill=0)
#print('CC', anchors.shape, len(inds_inside))
#if DEBUG:
# if gt_boxes.size > 0:
# print 'rpn: max max_overlaps', np.max(max_overlaps)
# print 'rpn: num_positives', np.sum(labels == 1)
# print 'rpn: num_negatives', np.sum(labels == 0)
# _fg_sum = np.sum(labels == 1)
# _bg_sum = np.sum(labels == 0)
# _count = 1
# print 'rpn: num_positive avg', _fg_sum / _count
# print 'rpn: num_negative avg', _bg_sum / _count
# resahpe
label_list = list()
bbox_target_list = list()
bbox_weight_list = list()
if landmark:
landmark_target_list = list()
landmark_weight_list = list()
anchors_num_range = [0] + anchors_num_list
label = {}
for i in range(len(feat_strides)):
stride = feat_strides[i]
feat_height, feat_width = feat_infos[i]
A = A_list[i]
_label = labels[sum(anchors_num_range[:i +
1]):sum(anchors_num_range[:i +
1]) +
anchors_num_range[i + 1]]
if select_stride > 0 and stride != select_stride:
#print('set', stride, select_stride)
_label[:] = -1
#print('_label', _label.shape, select_stride)
#_fg_inds = np.where(_label == 1)[0]
#n_fg = len(_fg_inds)
#STAT[0]+=1
#STAT[stride]+=n_fg
#if STAT[0]%100==0:
# print('rpn_stat', STAT, file=sys.stderr)
bbox_target = bbox_targets[sum(anchors_num_range[:i + 1]
):sum(anchors_num_range[:i + 1]) +
anchors_num_range[i + 1]]
bbox_weight = bbox_weights[sum(anchors_num_range[:i + 1]
):sum(anchors_num_range[:i + 1]) +
anchors_num_range[i + 1]]
if landmark:
landmark_target = landmark_targets[
sum(anchors_num_range[:i + 1]):sum(anchors_num_range[:i + 1]) +
anchors_num_range[i + 1]]
landmark_weight = landmark_weights[
sum(anchors_num_range[:i + 1]):sum(anchors_num_range[:i + 1]) +
anchors_num_range[i + 1]]
_label = _label.reshape(
(1, feat_height, feat_width, A)).transpose(0, 3, 1, 2)
_label = _label.reshape((1, A * feat_height * feat_width))
bbox_target = bbox_target.reshape(
(1, feat_height * feat_width,
A * bbox_pred_len)).transpose(0, 2, 1)
bbox_weight = bbox_weight.reshape(
(1, feat_height * feat_width, A * bbox_pred_len)).transpose(
(0, 2, 1))
label['%s_label_stride%d' % (prefix, stride)] = _label
label['%s_bbox_target_stride%d' % (prefix, stride)] = bbox_target
label['%s_bbox_weight_stride%d' % (prefix, stride)] = bbox_weight
if landmark:
landmark_target = landmark_target.reshape(
(1, feat_height * feat_width,
A * landmark_pred_len)).transpose(0, 2, 1)
landmark_weight = landmark_weight.reshape(
(1, feat_height * feat_width,
A * landmark_pred_len)).transpose((0, 2, 1))
label['%s_landmark_target_stride%d' %
(prefix, stride)] = landmark_target
label['%s_landmark_weight_stride%d' %
(prefix, stride)] = landmark_weight
#print('in_rpn', stride,_label.shape, bbox_target.shape, bbox_weight.shape, file=sys.stderr)
label_list.append(_label)
#print('DD', _label.shape)
bbox_target_list.append(bbox_target)
bbox_weight_list.append(bbox_weight)
if landmark:
landmark_target_list.append(landmark_target)
landmark_weight_list.append(landmark_weight)
label_concat = np.concatenate(label_list, axis=1)
bbox_target_concat = np.concatenate(bbox_target_list, axis=2)
bbox_weight_concat = np.concatenate(bbox_weight_list, axis=2)
#fg_inds = np.where(label_concat[0] == 1)[0]
#print('fg_inds_in_rpn2', fg_inds, file=sys.stderr)
label.update({
'%s_label' % prefix: label_concat,
'%s_bbox_target' % prefix: bbox_target_concat,
'%s_bbox_weight' % prefix: bbox_weight_concat
})
if landmark:
landmark_target_concat = np.concatenate(landmark_target_list, axis=2)
landmark_weight_concat = np.concatenate(landmark_weight_list, axis=2)
label['%s_landmark_target' % prefix] = landmark_target_concat
label['%s_landmark_weight' % prefix] = landmark_weight_concat
return label
class AA:
def __init__(self, feat_shape):
self.feat_shape = feat_shape
feat_strides = config.RPN_FEAT_STRIDE
anchors_list = []
anchors_num_list = []
inds_inside_list = []
feat_infos = []
A_list = []
DEBUG = False
for i in range(len(feat_strides)):
stride = feat_strides[i]
sstride = str(stride)
base_size = config.RPN_ANCHOR_CFG[sstride]['BASE_SIZE']
allowed_border = config.RPN_ANCHOR_CFG[sstride]['ALLOWED_BORDER']
ratios = config.RPN_ANCHOR_CFG[sstride]['RATIOS']
scales = config.RPN_ANCHOR_CFG[sstride]['SCALES']
base_anchors = generate_anchors(base_size=base_size,
ratios=list(ratios),
scales=np.array(scales,
dtype=np.float32),
stride=stride,
dense_anchor=config.DENSE_ANCHOR)
num_anchors = base_anchors.shape[0]
feat_height, feat_width = feat_shape[i][-2:]
feat_stride = feat_strides[i]
feat_infos.append([feat_height, feat_width])
A = num_anchors
A_list.append(A)
K = feat_height * feat_width
all_anchors = anchors_plane(feat_height, feat_width, feat_stride,
base_anchors)
all_anchors = all_anchors.reshape((K * A, 4))
#print('anchor0', stride, all_anchors[0])
total_anchors = int(K * A)
anchors_num_list.append(total_anchors)
# only keep anchors inside the image
inds_inside = np.where(
(all_anchors[:, 0] >= -allowed_border)
& (all_anchors[:, 1] >= -allowed_border)
& (all_anchors[:, 2] < config.SCALES[0][1] + allowed_border) &
(all_anchors[:, 3] < config.SCALES[0][1] + allowed_border))[0]
if DEBUG:
print('total_anchors', total_anchors)
print('inds_inside', len(inds_inside))
# keep only inside anchors
anchors = all_anchors[inds_inside, :]
#print('AA', anchors.shape, len(inds_inside))
anchors_list.append(anchors)
inds_inside_list.append(inds_inside)
anchors = np.concatenate(anchors_list)
for i in range(1, len(inds_inside_list)):
inds_inside_list[i] = inds_inside_list[i] + sum(
anchors_num_list[:i])
inds_inside = np.concatenate(inds_inside_list)
#self.anchors_list = anchors_list
#self.inds_inside_list = inds_inside_list
self.anchors = anchors
self.inds_inside = inds_inside
self.anchors_num_list = anchors_num_list
self.feat_infos = feat_infos
self.A_list = A_list
self._times = [0.0, 0.0, 0.0, 0.0]
@staticmethod
def _unmap(data, count, inds, fill=0):
"""" unmap a subset inds of data into original data of size count """
if len(data.shape) == 1:
ret = np.empty((count, ), dtype=np.float32)
ret.fill(fill)
ret[inds] = data
else:
ret = np.empty((count, ) + data.shape[1:], dtype=np.float32)
ret.fill(fill)
ret[inds, :] = data
return ret
def assign_anchor_fpn(self,
gt_label,
im_info,
landmark=False,
prefix='face',
select_stride=0):
#ta = datetime.datetime.now()
im_info = im_info[0]
gt_boxes = gt_label['gt_boxes']
# clean up boxes
nonneg = np.where(gt_boxes[:, 4] != -1)[0]
gt_boxes = gt_boxes[nonneg]
if config.USE_BLUR:
gt_blur = gt_label['gt_blur']
gt_blur = gt_blur[nonneg]
if landmark:
gt_landmarks = gt_label['gt_landmarks']
gt_landmarks = gt_landmarks[nonneg]
assert gt_boxes.shape[0] == gt_landmarks.shape[0]
#scales = np.array(scales, dtype=np.float32)
feat_strides = config.RPN_FEAT_STRIDE
bbox_pred_len = 4
landmark_pred_len = 10
if config.USE_BLUR:
gt_boxes[:, 4] = gt_blur
bbox_pred_len = 5
if config.USE_OCCLUSION:
landmark_pred_len = 15
#anchors_list = self.anchors_list
#inds_inside_list = self.inds_inside_list
anchors = self.anchors
inds_inside = self.inds_inside
anchors_num_list = self.anchors_num_list
feat_infos = self.feat_infos
A_list = self.A_list
total_anchors = sum(anchors_num_list)
#print('total_anchors', anchors.shape[0], len(inds_inside), file=sys.stderr)
# label: 1 is positive, 0 is negative, -1 is dont care
labels = np.empty((len(inds_inside), ), dtype=np.float32)
labels.fill(-1)
#print('BB', anchors.shape, len(inds_inside))
#print('gt_boxes', gt_boxes.shape, file=sys.stderr)
#tb = datetime.datetime.now()
#self._times[0] += (tb-ta).total_seconds()
#ta = datetime.datetime.now()
if gt_boxes.size > 0:
# overlap between the anchors and the gt boxes
# overlaps (ex, gt)
overlaps = bbox_overlaps(anchors.astype(np.float),
gt_boxes.astype(np.float))
argmax_overlaps = overlaps.argmax(axis=1)
#print('AAA', argmax_overlaps.shape)
max_overlaps = overlaps[np.arange(len(inds_inside)),
argmax_overlaps]
gt_argmax_overlaps = overlaps.argmax(axis=0)
gt_max_overlaps = overlaps[gt_argmax_overlaps,
np.arange(overlaps.shape[1])]
gt_argmax_overlaps = np.where(overlaps == gt_max_overlaps)[0]
if not config.TRAIN.RPN_CLOBBER_POSITIVES:
# assign bg labels first so that positive labels can clobber them
labels[max_overlaps < config.TRAIN.RPN_NEGATIVE_OVERLAP] = 0
# fg label: for each gt, anchor with highest overlap
if config.TRAIN.RPN_FORCE_POSITIVE:
labels[gt_argmax_overlaps] = 1
# fg label: above threshold IoU
labels[max_overlaps >= config.TRAIN.RPN_POSITIVE_OVERLAP] = 1
if config.TRAIN.RPN_CLOBBER_POSITIVES:
# assign bg labels last so that negative labels can clobber positives
labels[max_overlaps < config.TRAIN.RPN_NEGATIVE_OVERLAP] = 0
else:
labels[:] = 0
fg_inds = np.where(labels == 1)[0]
#print('fg count', len(fg_inds))
# subsample positive labels if we have too many
if config.TRAIN.RPN_ENABLE_OHEM == 0:
fg_inds = np.where(labels == 1)[0]
num_fg = int(config.TRAIN.RPN_FG_FRACTION *
config.TRAIN.RPN_BATCH_SIZE)
if len(fg_inds) > num_fg:
disable_inds = npr.choice(fg_inds,
size=(len(fg_inds) - num_fg),
replace=False)
if DEBUG:
disable_inds = fg_inds[:(len(fg_inds) - num_fg)]
labels[disable_inds] = -1
# subsample negative labels if we have too many
num_bg = config.TRAIN.RPN_BATCH_SIZE - np.sum(labels == 1)
bg_inds = np.where(labels == 0)[0]
if len(bg_inds) > num_bg:
disable_inds = npr.choice(bg_inds,
size=(len(bg_inds) - num_bg),
replace=False)
if DEBUG:
disable_inds = bg_inds[:(len(bg_inds) - num_bg)]
labels[disable_inds] = -1
#fg_inds = np.where(labels == 1)[0]
#num_fg = len(fg_inds)
#num_bg = num_fg*int(1.0/config.TRAIN.RPN_FG_FRACTION-1)
#bg_inds = np.where(labels == 0)[0]
#if len(bg_inds) > num_bg:
# disable_inds = npr.choice(bg_inds, size=(len(bg_inds) - num_bg), replace=False)
# if DEBUG:
# disable_inds = bg_inds[:(len(bg_inds) - num_bg)]
# labels[disable_inds] = -1
else:
fg_inds = np.where(labels == 1)[0]
num_fg = len(fg_inds)
bg_inds = np.where(labels == 0)[0]
num_bg = len(bg_inds)
#print('anchor stat', num_fg, num_bg)
bbox_targets = np.zeros((len(inds_inside), bbox_pred_len),
dtype=np.float32)
if gt_boxes.size > 0:
#print('GT', gt_boxes.shape, gt_boxes[argmax_overlaps, :4].shape)
bbox_targets[:, :] = bbox_transform(anchors,
gt_boxes[argmax_overlaps, :])
#bbox_targets[:,4] = gt_blur
#tb = datetime.datetime.now()
#self._times[1] += (tb-ta).total_seconds()
#ta = datetime.datetime.now()
bbox_weights = np.zeros((len(inds_inside), bbox_pred_len),
dtype=np.float32)
#bbox_weights[labels == 1, :] = np.array(config.TRAIN.RPN_BBOX_WEIGHTS)
bbox_weights[labels == 1, 0:4] = 1.0
if bbox_pred_len > 4:
bbox_weights[labels == 1, 4:bbox_pred_len] = 0.1
if landmark:
landmark_targets = np.zeros((len(inds_inside), landmark_pred_len),
dtype=np.float32)
#landmark_weights = np.zeros((len(inds_inside), 10), dtype=np.float32)
landmark_weights = np.zeros((len(inds_inside), landmark_pred_len),
dtype=np.float32)
#landmark_weights[labels == 1, :] = np.array(config.TRAIN.RPN_LANDMARK_WEIGHTS)
if landmark_pred_len == 10:
landmark_weights[labels == 1, :] = 1.0
elif landmark_pred_len == 15:
v = [1.0, 1.0, 0.1] * 5
assert len(v) == 15
landmark_weights[labels == 1, :] = np.array(v)
else:
assert False
#TODO here
if gt_landmarks.size > 0:
#print('AAA',argmax_overlaps)
a_landmarks = gt_landmarks[argmax_overlaps, :, :]
landmark_targets[:] = landmark_transform(anchors, a_landmarks)
invalid = np.where(a_landmarks[:, 0, 2] < 0.0)[0]
#assert len(invalid)==0
#landmark_weights[invalid, :] = np.array(config.TRAIN.RPN_INVALID_LANDMARK_WEIGHTS)
landmark_weights[invalid, :] = 0.0
#tb = datetime.datetime.now()
#self._times[2] += (tb-ta).total_seconds()
#ta = datetime.datetime.now()
#if DEBUG:
# _sums = bbox_targets[labels == 1, :].sum(axis=0)
# _squared_sums = (bbox_targets[labels == 1, :] ** 2).sum(axis=0)
# _counts = np.sum(labels == 1)
# means = _sums / (_counts + 1e-14)
# stds = np.sqrt(_squared_sums / _counts - means ** 2)
# print 'means', means
# print 'stdevs', stds
# map up to original set of anchors
#print(labels.shape, total_anchors, inds_inside.shape, inds_inside[0], inds_inside[-1])
labels = AA._unmap(labels, total_anchors, inds_inside, fill=-1)
bbox_targets = AA._unmap(bbox_targets,
total_anchors,
inds_inside,
fill=0)
bbox_weights = AA._unmap(bbox_weights,
total_anchors,
inds_inside,
fill=0)
if landmark:
landmark_targets = AA._unmap(landmark_targets,
total_anchors,
inds_inside,
fill=0)
landmark_weights = AA._unmap(landmark_weights,
total_anchors,
inds_inside,
fill=0)
#print('CC', anchors.shape, len(inds_inside))
bbox_targets[:,
0::4] = bbox_targets[:, 0::4] / config.TRAIN.BBOX_STDS[0]
bbox_targets[:,
1::4] = bbox_targets[:, 1::4] / config.TRAIN.BBOX_STDS[1]
bbox_targets[:,
2::4] = bbox_targets[:, 2::4] / config.TRAIN.BBOX_STDS[2]
bbox_targets[:,
3::4] = bbox_targets[:, 3::4] / config.TRAIN.BBOX_STDS[3]
landmark_targets /= config.TRAIN.LANDMARK_STD
#print('applied STD')
#if DEBUG:
# if gt_boxes.size > 0:
# print 'rpn: max max_overlaps', np.max(max_overlaps)
# print 'rpn: num_positives', np.sum(labels == 1)
# print 'rpn: num_negatives', np.sum(labels == 0)
# _fg_sum = np.sum(labels == 1)
# _bg_sum = np.sum(labels == 0)
# _count = 1
# print 'rpn: num_positive avg', _fg_sum / _count
# print 'rpn: num_negative avg', _bg_sum / _count
# resahpe
label_list = list()
bbox_target_list = list()
bbox_weight_list = list()
if landmark:
landmark_target_list = list()
landmark_weight_list = list()
anchors_num_range = [0] + anchors_num_list
label = {}
for i in range(len(feat_strides)):
stride = feat_strides[i]
feat_height, feat_width = feat_infos[i]
A = A_list[i]
_label = labels[sum(anchors_num_range[:i + 1]
):sum(anchors_num_range[:i + 1]) +
anchors_num_range[i + 1]]
if select_stride > 0 and stride != select_stride:
#print('set', stride, select_stride)
_label[:] = -1
#print('_label', _label.shape, select_stride)
#_fg_inds = np.where(_label == 1)[0]
#n_fg = len(_fg_inds)
#STAT[0]+=1
#STAT[stride]+=n_fg
#if STAT[0]%100==0:
# print('rpn_stat', STAT, file=sys.stderr)
bbox_target = bbox_targets[sum(anchors_num_range[:i + 1]
):sum(anchors_num_range[:i + 1]) +
anchors_num_range[i + 1]]
bbox_weight = bbox_weights[sum(anchors_num_range[:i + 1]
):sum(anchors_num_range[:i + 1]) +
anchors_num_range[i + 1]]
if landmark:
landmark_target = landmark_targets[
sum(anchors_num_range[:i +
1]):sum(anchors_num_range[:i + 1]) +
anchors_num_range[i + 1]]
landmark_weight = landmark_weights[
sum(anchors_num_range[:i +
1]):sum(anchors_num_range[:i + 1]) +
anchors_num_range[i + 1]]
_label = _label.reshape(
(1, feat_height, feat_width, A)).transpose(0, 3, 1, 2)
_label = _label.reshape((1, A * feat_height * feat_width))
bbox_target = bbox_target.reshape(
(1, feat_height * feat_width,
A * bbox_pred_len)).transpose(0, 2, 1)
bbox_weight = bbox_weight.reshape(
(1, feat_height * feat_width, A * bbox_pred_len)).transpose(
(0, 2, 1))
label['%s_label_stride%d' % (prefix, stride)] = _label
label['%s_bbox_target_stride%d' % (prefix, stride)] = bbox_target
label['%s_bbox_weight_stride%d' % (prefix, stride)] = bbox_weight
if landmark:
landmark_target = landmark_target.reshape(
(1, feat_height * feat_width,
A * landmark_pred_len)).transpose(0, 2, 1)
landmark_weight = landmark_weight.reshape(
(1, feat_height * feat_width,
A * landmark_pred_len)).transpose((0, 2, 1))
label['%s_landmark_target_stride%d' %
(prefix, stride)] = landmark_target
label['%s_landmark_weight_stride%d' %
(prefix, stride)] = landmark_weight
#print('in_rpn', stride,_label.shape, bbox_target.shape, bbox_weight.shape, file=sys.stderr)
label_list.append(_label)
#print('DD', _label.shape)
bbox_target_list.append(bbox_target)
bbox_weight_list.append(bbox_weight)
if landmark:
landmark_target_list.append(landmark_target)
landmark_weight_list.append(landmark_weight)
label_concat = np.concatenate(label_list, axis=1)
bbox_target_concat = np.concatenate(bbox_target_list, axis=2)
bbox_weight_concat = np.concatenate(bbox_weight_list, axis=2)
#fg_inds = np.where(label_concat[0] == 1)[0]
#print('fg_inds_in_rpn2', fg_inds, file=sys.stderr)
label.update({
'%s_label' % prefix: label_concat,
'%s_bbox_target' % prefix: bbox_target_concat,
'%s_bbox_weight' % prefix: bbox_weight_concat
})
if landmark:
landmark_target_concat = np.concatenate(landmark_target_list,
axis=2)
landmark_weight_concat = np.concatenate(landmark_weight_list,
axis=2)
label['%s_landmark_target' % prefix] = landmark_target_concat
label['%s_landmark_weight' % prefix] = landmark_weight_concat
#tb = datetime.datetime.now()
#self._times[3] += (tb-ta).total_seconds()
#ta = datetime.datetime.now()
#print(self._times)
return label