def __data_generation(self, keys): """Generate train data: images and object detection ground truth labels Arguments: keys (array): Randomly sampled keys (key is image filename) Returns: x (tensor): Batch images y (tensor): Batch classes, offsets, and masks """ # train input data x = np.zeros((self.args.batch_size, *self.input_shape)) dim = (self.args.batch_size, self.n_boxes, self.n_classes) # class ground truth gt_class = np.zeros(dim) dim = (self.args.batch_size, self.n_boxes, 4) # offsets ground truth gt_offset = np.zeros(dim) # masks of valid bounding boxes gt_mask = np.zeros(dim) for i, key in enumerate(keys): # images are assumed to be stored in self.args.data_path # key is the image filename image_path = os.path.join(self.args.data_path, key) image = skimage.img_as_float(imread(image_path)) # assign image to a batch index x[i] = image # a label entry is made of 4-dim bounding box coords # and 1-dim class label labels = self.dictionary[key] labels = np.array(labels) # 4 bounding box coords are 1st four items of labels # last item is object class label boxes = labels[:,0:-1] for index, feature_shape in enumerate(self.feature_shapes): # generate anchor boxes anchors = anchor_boxes(feature_shape, image.shape, index=index, n_layers=self.args.layers) # each feature layer has a row of anchor boxes anchors = np.reshape(anchors, [-1, 4]) # compute IoU of each anchor box # with respect to each bounding boxes iou = layer_utils.iou(anchors, boxes) # generate ground truth class, offsets & mask gt = get_gt_data(iou, n_classes=self.n_classes, anchors=anchors, labels=labels, normalize=self.args.normalize, threshold=self.args.threshold) gt_cls, gt_off, gt_msk = gt if index == 0: cls = np.array(gt_cls) off = np.array(gt_off) msk = np.array(gt_msk) else: cls = np.append(cls, gt_cls, axis=0) off = np.append(off, gt_off, axis=0) msk = np.append(msk, gt_msk, axis=0) gt_class[i] = cls gt_offset[i] = off gt_mask[i] = msk y = [gt_class, np.concatenate((gt_offset, gt_mask), axis=-1)] return x, y
def __data_generation(self, keys): data_path = config.params['data_path'] x = np.empty((self.batch_size, *self.input_shape)) dim = (self.batch_size, self.n_boxes, self.n_classes) gt_class = np.empty(dim) dim = (self.batch_size, self.n_boxes, 4) gt_offset = np.empty(dim) gt_mask = np.empty(dim) for i, key in enumerate(keys): # images are assumed to be stored in config data_path # key is the image filename image_path = os.path.join(data_path, key) image = skimage.img_as_float(imread(image_path)) # if augment data is enabled if self.aug_data: image = self.apply_random_noise(image) image = self.apply_random_intensity_rescale(image) image = self.apply_random_exposure_adjust(image) x[i] = image labels = self.dictionary[key] labels = np.array(labels) # 4 boxes coords are 1st four items of labels boxes = labels[:,0:-1] for index, shape in enumerate(self.feature_shapes): shape = (1, *shape) # generate anchor boxes anchors = anchor_boxes(shape, image.shape, index=index, n_layers=self.n_layers) anchors = np.reshape(anchors, [-1, 4]) # compute IoU of each anchor box # with respect to each bounding boxes iou = layer_utils.iou(anchors, boxes) # generate ground truth class and offsets ret = get_gt_data(iou, n_classes=self.n_classes, anchors=anchors, labels=labels, normalize=self.normalize) gt_cls, gt_off, gt_msk = ret if index == 0: cls = np.array(gt_cls) off = np.array(gt_off) msk = np.array(gt_msk) else: cls = np.append(cls, gt_cls, axis=0) off = np.append(off, gt_off, axis=0) msk = np.append(msk, gt_msk, axis=0) gt_class[i] = cls gt_offset[i] = off gt_mask[i] = msk y = [gt_class, np.concatenate((gt_offset, gt_mask), axis=-1)] return x, y
def show_boxes(image, classes, offsets, feature_shapes, show=True, normalize=False): # generate all anchors per feature map anchors = [] n_layers = len(feature_shapes) for index, shape in enumerate(feature_shapes): shape = (1, *shape) anchor = anchor_boxes(shape, image.shape, index=index) anchor = np.reshape(anchor, [-1, 4]) if index == 0: anchors = anchor else: anchors = np.concatenate((anchors, anchor), axis=0) # get all non-zero (non-background) objects # objects = np.argmax(classes, axis=1) # print(np.unique(objects, return_counts=True)) # nonbg = np.nonzero(objects)[0] if normalize: print("Normalize") anchors_centroid = minmax2centroid(anchors) offsets[:, 0:2] *= 0.1 offsets[:, 0:2] *= anchors_centroid[:, 2:4] offsets[:, 0:2] += anchors_centroid[:, 0:2] offsets[:, 2:4] *= 0.2 offsets[:, 2:4] = np.exp(offsets[:, 2:4]) offsets[:, 2:4] *= anchors_centroid[:, 2:4] offsets = centroid2minmax(offsets) # convert fr cx,cy,w,h to real offsets offsets[:, 0:4] = offsets[:, 0:4] - anchors objects, indexes, scores = nms(classes, offsets, anchors, is_soft=True) class_names = [] rects = [] if show: fig, ax = plt.subplots(1) ax.imshow(image) for idx in indexes: #batch, row, col, box anchor = anchors[idx] offset = offsets[idx] anchor += offset[0:4] # default anchor box format is # xmin, xmax, ymin, ymax w = anchor[1] - anchor[0] h = anchor[3] - anchor[2] x = anchor[0] y = anchor[2] category = int(objects[idx]) class_name = index2class(category) class_name = "%s: %0.2f" % (class_name, scores[idx]) class_names.append(class_name) rect = (x, y, w, h) print(class_name, rect) rects.append(rect) if show: color = get_box_color(category) rect = Rectangle((x, y), w, h, linewidth=2, edgecolor=color, facecolor='none') ax.add_patch(rect) bbox = dict(color='none', alpha=1.0) ax.text(anchor[0] + 2, anchor[2] - 16, class_name, color=color, fontweight='bold', bbox=bbox, fontsize=8, verticalalignment='top') if show: plt.show() return class_names, rects
def show_boxes(args, image, classes, offsets, feature_shapes, show=True): """Show detected objects on an image. Show bounding boxes and class names. Arguments: image (tensor): Image to show detected objects (0.0 to 1.0) classes (tensor): Predicted classes offsets (tensor): Predicted offsets feature_shapes (tensor): SSD head feature maps show (bool): Whether to show bounding boxes or not Returns: class_names (list): List of object class names rects (list): Bounding box rectangles of detected objects class_ids (list): Class ids of detected objects boxes (list): Anchor boxes of detected objects """ # generate all anchor boxes per feature map anchors = [] n_layers = len(feature_shapes) for index, feature_shape in enumerate(feature_shapes): anchor = anchor_boxes(feature_shape, image.shape, index=index) anchor = np.reshape(anchor, [-1, 4]) if index == 0: anchors = anchor else: anchors = np.concatenate((anchors, anchor), axis=0) # get all non-zero (non-background) objects # objects = np.argmax(classes, axis=1) # print(np.unique(objects, return_counts=True)) # nonbg = np.nonzero(objects)[0] if args.normalize: print("Normalize") anchors_centroid = minmax2centroid(anchors) offsets[:, 0:2] *= 0.1 offsets[:, 0:2] *= anchors_centroid[:, 2:4] offsets[:, 0:2] += anchors_centroid[:, 0:2] offsets[:, 2:4] *= 0.2 offsets[:, 2:4] = np.exp(offsets[:, 2:4]) offsets[:, 2:4] *= anchors_centroid[:, 2:4] offsets = centroid2minmax(offsets) # convert fr cx,cy,w,h to real offsets offsets[:, 0:4] = offsets[:, 0:4] - anchors objects, indexes, scores = nms(args, classes, offsets, anchors) class_names = [] rects = [] class_ids = [] boxes = [] if show: fig, ax = plt.subplots(1) ax.imshow(image) yoff = 1 for idx in indexes: #batch, row, col, box anchor = anchors[idx] offset = offsets[idx] anchor += offset[0:4] # default anchor box format is # xmin, xmax, ymin, ymax boxes.append(anchor) w = anchor[1] - anchor[0] h = anchor[3] - anchor[2] x = anchor[0] y = anchor[2] category = int(objects[idx]) class_ids.append(category) class_name = index2class(category) class_name = "%s: %0.2f" % (class_name, scores[idx]) class_names.append(class_name) rect = (x, y, w, h) print(class_name, rect) rects.append(rect) if show: color = get_box_color(category) rect = Rectangle((x, y), w, h, linewidth=2, edgecolor=color, facecolor='none') ax.add_patch(rect) bbox = dict(color='white', alpha=1.0) ax.text( anchor[0] + 2, anchor[2] - 16 + np.random.randint(0, yoff), class_name, color=color, #fontweight='bold', bbox=bbox, fontsize=10, verticalalignment='top') yoff += 50 #t.set_bbox(dict(facecolor='red', alpha=0.5, edgecolor='red')) if show: plt.savefig("detection.png", dpi=600) plt.show() return class_names, rects, class_ids, boxes