def __init__(self, batch_label, feature_maps): self.batch_size = batch_label.shape[0] self.num_predict_features = 6#一共有6个FeatureMap self.read_dataset = ReadDataset() self.iou_threshold = IOU_THRESHOLD self.default_boxes = DefaultBoxes(feature_maps)#从feeture Map中提取出Default box self.boxes = batch_label self.predict_boxes = self.default_boxes.generate_default_boxes()
def __init__(self, batch_data, output_features): self.batch_data = batch_data self.batch_size = batch_data.shape[0] self.num_predict_features = 6 self.read_dataset = ReadDataset() self.default_boxes = DefaultBoxes(feature_map_list=output_features) self.images, self.boxes = self.read_dataset.read(self.batch_data) self.predict_boxes = self.default_boxes.generate_default_boxes()
def __offsets_to_true_coordinates(self, pred_boxes, ssd_output): pred_classes = tf.reshape(tensor=pred_boxes[..., :self.num_classes], shape=(-1, self.num_classes)) pred_coords = tf.reshape(tensor=pred_boxes[..., self.num_classes:], shape=(-1, 4)) default_boxes = DefaultBoxes( feature_map_list=ssd_output).generate_default_boxes() d_cx, d_cy, d_w, d_h = default_boxes[:, 0: 1], default_boxes[:, 1: 2], default_boxes[:, 2: 3], default_boxes[:, 3: 4] offset_cx, offset_cy, offset_w, offset_h = pred_coords[:, 0: 1], pred_coords[:, 1: 2], pred_coords[:, 2: 3], pred_coords[:, 3: 4] true_cx = offset_cx * d_w + d_cx true_cy = offset_cy * d_h + d_cy true_w = tf.math.exp(offset_w) * d_w true_h = tf.math.exp(offset_h) * d_h true_coords = tf.concat(values=[true_cx, true_cy, true_w, true_h], axis=-1) true_classes_and_coords = tf.concat(values=[pred_classes, true_coords], axis=-1) true_classes_and_coords = tf.expand_dims(input=true_classes_and_coords, axis=0) return true_classes_and_coords
class MakeGT(object): def __init__(self, batch_data, output_features): self.batch_data = batch_data self.batch_size = batch_data.shape[0] self.num_predict_features = 6 self.read_dataset = ReadDataset() self.default_boxes = DefaultBoxes(feature_map_list=output_features) self.images, self.boxes = self.read_dataset.read(self.batch_data) self.predict_boxes = self.default_boxes.generate_default_boxes() def ___transform_true_boxes(self): boxes_xywhc = self.__to_xywhc(self.boxes) true_boxes_x = boxes_xywhc[..., 0] / IMAGE_WIDTH true_boxes_y = boxes_xywhc[..., 1] / IMAGE_HEIGHT true_boxes_w = boxes_xywhc[..., 2] / IMAGE_WIDTH true_boxes_h = boxes_xywhc[..., 3] / IMAGE_HEIGHT true_boxes_c = boxes_xywhc[..., -1] true_boxes = np.stack((true_boxes_x, true_boxes_y, true_boxes_w, true_boxes_h, true_boxes_c), axis=-1) return true_boxes @staticmethod def __to_xywhc(boxes): xy = 0.5 * (boxes[..., 0:2] + boxes[..., 2:4]) wh = boxes[..., 2:4] - boxes[..., 0:2] c = boxes[..., -1:] return np.concatenate((xy, wh, c), axis=-1) # (center_x, center_y, w, h, c) @staticmethod def __get_valid_boxes(boxes): num_of_boxes = boxes.shape[0] valid_boxes = [] for i in range(num_of_boxes): if boxes[i, -1] > 0.0: valid_boxes.append(boxes[i]) valid_boxes = np.array(valid_boxes, dtype=np.float32) return valid_boxes def __max_iou(self, box_true, box_pred): iou_outside = [] for i in range(box_true.shape[0]): iou_inside = [] for j in range(box_pred.shape[0]): iou = IOU(box_1=box_true[i], box_2=box_pred[j]).calculate_iou() iou_inside.append(iou) iou_outside.append(iou_inside) iou_array = np.array(iou_outside, dtype=np.float32) pos_index = np.argmax(iou_array, axis=1) return pos_index def label_positive_and_negative_predicted_boxes(self): true_boxes = self.___transform_true_boxes() for n in range(self.batch_size): # shape : (N, 5), where N is the number of valid true boxes for each input image. valid_true_boxes = self.__get_valid_boxes(true_boxes[n]) true_boxes_for_iou = valid_true_boxes[..., :4] pos_index = self.__max_iou(true_boxes_for_iou, self.predict_boxes)
def __init__(self, num_classes, overlap_thresh, neg_pos): self.default_boxes = tf.convert_to_tensor( DefaultBoxes().generate_boxes()) # Tensor, shape: (先验框总数(8732), 4) self.num_classes = num_classes self.threshold = overlap_thresh self.variance = VARIANCE self.negpos_ratio = neg_pos
def __init__(self, model, num_classes): self.model = model self.priors = DefaultBoxes().generate_boxes( ) # (num_priors,4) num_priors表示anchor总数,在SSD300中为8732 self.top_k = MAX_BOXES_NUM self.num_classes = num_classes self.variance = VARIANCE self.conf_thresh = CONFIDENCE_THRESHOLD self.nms_thresh = NMS_THRESHOLD
class MakeGT(object): def __init__(self, batch_label, feature_maps): self.batch_size = batch_label.shape[0] self.num_predict_features = 6#一共有6个FeatureMap self.read_dataset = ReadDataset() self.iou_threshold = IOU_THRESHOLD self.default_boxes = DefaultBoxes(feature_maps)#从feeture Map中提取出Default box self.boxes = batch_label self.predict_boxes = self.default_boxes.generate_default_boxes() def ___transform_true_boxes(self):#将ground Truth的Lable的位置转换成Tensor boxes_xywhc = self.__to_xywhc(self.boxes) true_boxes_x = boxes_xywhc[..., 0] / IMAGE_WIDTH true_boxes_y = boxes_xywhc[..., 1] / IMAGE_HEIGHT true_boxes_w = boxes_xywhc[..., 2] / IMAGE_WIDTH true_boxes_h = boxes_xywhc[..., 3] / IMAGE_HEIGHT true_boxes_c = boxes_xywhc[..., -1] true_boxes = np.stack((true_boxes_x, true_boxes_y, true_boxes_w, true_boxes_h, true_boxes_c), axis=-1) return true_boxes @staticmethod def __to_xywhc(boxes): xy = 0.5 * (boxes[..., 0:2] + boxes[..., 2:4]) wh = boxes[..., 2:4] - boxes[..., 0:2] c = boxes[..., -1:] return np.concatenate((xy, wh, c), axis=-1) # (center_x, center_y, w, h, c) @staticmethod def __get_valid_boxes(boxes):#计算出有效的box,也就是Box的各个参数都能在feature Map中找到 num_of_boxes = boxes.shape[0] valid_boxes = [] for i in range(num_of_boxes): if boxes[i, -1] > 0.0: valid_boxes.append(boxes[i]) valid_boxes = np.array(valid_boxes, dtype=np.float32) return valid_boxes def __label_positive_and_negative_predicted_boxes(self, box_true, box_pred):#通过IoU的计算,来其确定pred中有多少是Positiv的 box_true_coord = box_true[..., :4]#box的[cx,cy,w,h] box_true_class = box_true[..., -1]#class Lable box_pred_assigned = np.zeros_like(box_pred, dtype=np.float32) iou_outside = [] for i in range(box_true_coord.shape[0]): iou_inside = [] for j in range(box_pred.shape[0]): iou = IOU(box_1=box_true_coord[i], box_2=box_pred[j]).calculate_iou() iou_inside.append(iou) iou_outside.append(iou_inside) iou_array = np.array(iou_outside, dtype=np.float32) # shape: (num_of_true_boxes, total_num_of_default_boxes) iou_max = np.max(iou_array, axis=0)#计算出各个列中,最大的IoU值 max_index = np.argmax(iou_array, axis=0)#找出最大值对应的Index,在哪一列 max_index_class = np.zeros_like(max_index, dtype=np.float32)#生成形状类似的全0 数组 for k in range(max_index.shape[0]): max_index_class[k] = box_true_class[max_index[k]] box_pred_assigned[k] = self.__get_offset(box_true=box_true_coord[max_index[k]], box_pred=box_pred[k]) pos_boolean = np.where(iou_max > self.iou_threshold, 1.0, 0.0) # 1 for positive, 0 for negative pos_class_index = max_index_class * pos_boolean pos_class_index = pos_class_index.reshape((-1, 1)) labeled_box_pred = np.concatenate((box_pred_assigned, pos_class_index), axis=-1) return labeled_box_pred @staticmethod def __get_offset(box_true, box_pred): d_cx, d_cy, d_w, d_h = box_pred g_cx, g_cy, g_w, g_h = box_true g_cx = (g_cx - d_cx) / d_w g_cy = (g_cy - d_cy) / d_h g_w = np.log(g_w / d_w) g_h = np.log(g_h / d_h) return np.stack([g_cx, g_cy, g_w, g_h], axis=0) def generate_gt_boxes(self): true_boxes = self.___transform_true_boxes() # shape: (batch_size, MAX_BOXES_PER_IMAGE, 5) gt_boxes_list = [] for n in range(self.batch_size): # shape : (N, 5), where N is the number of valid true boxes for each input image. valid_true_boxes = self.__get_valid_boxes(true_boxes[n]) gt_boxes = self.__label_positive_and_negative_predicted_boxes(valid_true_boxes, self.predict_boxes) gt_boxes_list.append(gt_boxes) batch_gt_boxes = np.stack(gt_boxes_list, axis=0) # shape: (batch_size, total_num_of_default_boxes, 5) return tf.convert_to_tensor(value=batch_gt_boxes, dtype=tf.dtypes.float32)
class MakeGT(object): def __init__(self, batch_label, feature_maps): self.batch_size = batch_label.shape[0] self.num_predict_features = 6 self.read_dataset = ReadDataset() self.iou_threshold = IOU_THRESHOLD self.default_boxes = DefaultBoxes(feature_maps) self.boxes = batch_label self.predict_boxes = self.default_boxes.generate_default_boxes() def ___transform_true_boxes(self): boxes_xywhc = self.__to_xywhc(self.boxes) true_boxes_x = boxes_xywhc[..., 0] / IMAGE_WIDTH true_boxes_y = boxes_xywhc[..., 1] / IMAGE_HEIGHT true_boxes_w = boxes_xywhc[..., 2] / IMAGE_WIDTH true_boxes_h = boxes_xywhc[..., 3] / IMAGE_HEIGHT true_boxes_c = boxes_xywhc[..., -1] true_boxes = np.stack((true_boxes_x, true_boxes_y, true_boxes_w, true_boxes_h, true_boxes_c), axis=-1) return true_boxes @staticmethod def __to_xywhc(boxes): xy = 0.5 * (boxes[..., 0:2] + boxes[..., 2:4]) wh = boxes[..., 2:4] - boxes[..., 0:2] c = boxes[..., -1:] return np.concatenate((xy, wh, c), axis=-1) # (center_x, center_y, w, h, c) @staticmethod def __get_valid_boxes(boxes): num_of_boxes = boxes.shape[0] valid_boxes = [] for i in range(num_of_boxes): if boxes[i, -1] > 0.0: valid_boxes.append(boxes[i]) valid_boxes = np.array(valid_boxes, dtype=np.float32) return valid_boxes def __label_positive_and_negative_predicted_boxes(self, box_true, box_pred): box_true_coord = box_true[..., :4] box_true_class = box_true[..., -1] box_pred_assigned = np.zeros_like(box_pred, dtype=np.float32) iou_outside = [] for i in range(box_true_coord.shape[0]): iou_inside = [] for j in range(box_pred.shape[0]): iou = IOU(box_1=box_true_coord[i], box_2=box_pred[j]).calculate_iou() iou_inside.append(iou) iou_outside.append(iou_inside) iou_array = np.array( iou_outside, dtype=np.float32 ) # shape: (num_of_true_boxes, total_num_of_default_boxes) iou_max = np.max(iou_array, axis=0) max_index = np.argmax(iou_array, axis=0) max_index_class = np.zeros_like(max_index, dtype=np.float32) for k in range(max_index.shape[0]): max_index_class[k] = box_true_class[max_index[k]] box_pred_assigned[k] = box_true_coord[max_index[k]] pos_boolean = np.where(iou_max > self.iou_threshold, 1, 0) # 1 for positive, 0 for negative pos_class_index = max_index_class * pos_boolean pos_class_index = pos_class_index.reshape((-1, 1)) labeled_box_pred = np.concatenate((box_pred_assigned, pos_class_index), axis=-1) return labeled_box_pred def generate_gt_boxes(self): true_boxes = self.___transform_true_boxes( ) # shape: (batch_size, MAX_BOXES_PER_IMAGE, 5) gt_boxes_list = [] for n in range(self.batch_size): # shape : (N, 5), where N is the number of valid true boxes for each input image. valid_true_boxes = self.__get_valid_boxes(true_boxes[n]) gt_boxes = self.__label_positive_and_negative_predicted_boxes( valid_true_boxes, self.predict_boxes) gt_boxes_list.append(gt_boxes) batch_gt_boxes = np.stack( gt_boxes_list, axis=0) # shape: (batch_size, total_num_of_default_boxes, 5) return tf.convert_to_tensor(value=batch_gt_boxes, dtype=tf.dtypes.float32)