예제 #1
0
def nms(y_pred_conf, y_pred_loc, prob):
    """
	Non-Maximum Suppression (NMS)
	Performs NMS on all boxes of each class where predicted probability > CONF_THRES
	For all boxes exceeding IOU threshold, select the box with highest confidence
	Returns a lsit of box coordinates post-NMS

	Arguments:
		* y_pred_conf: Class predictions, numpy array of shape (num_feature_map_cells * num_defaul_boxes,)
		* y_pred_loc: Bounding box coordinates, numpy array of shape (num_feature_map_cells * num_defaul_boxes * 4,)
			These coordinates are normalized coordinates relative to center of feature map cell
		* prob: Class probabilities, numpy array of shape (num_feature_map_cells * num_defaul_boxes,)

	Returns:
		* boxes: Numpy array of boxes, with shape (num_boxes, 6). shape[0] is interpreted as:
			[x1, y1, x2, y2, class, probability], where x1/y1/x2/y2 are the coordinates of the
			upper-left and lower-right corners. Box coordinates assume the image size is IMG_W x IMG_H.
			Remember to rescale box coordinates if your target image has different dimensions.
	"""
    # Keep track of boxes for each class
    class_boxes = {}  # class -> [(x1, y1, x2, y2, prob), (...), ...]
    with open('signnames.csv', 'r') as f:
        for line in f:
            cls, _ = line.split(',')
            class_boxes[float(cls)] = []

    # Go through all possible boxes and perform class-based greedy NMS (greedy based on class prediction confidence)
    y_idx = 0
    for fm_size in FM_SIZES:
        fm_h, fm_w = fm_size  # feature map height and width
        for row in range(fm_h):
            for col in range(fm_w):
                for db in DEFAULT_BOXES:
                    # Only perform calculations if class confidence > CONF_THRESH and not background class
                    if prob[y_idx] > CONF_THRESH and y_pred_conf[y_idx] > 0.:
                        # Calculate absolute coordinates of predicted bounding box
                        xc, yc = col + 0.5, row + 0.5  # center of current feature map cell
                        center_coords = np.array([xc, yc, xc, yc])
                        abs_box_coords = center_coords + y_pred_loc[
                            y_idx * 4:y_idx * 4 +
                            4]  # predictions are offsets to center of fm cell

                        # Calculate predicted box coordinates in actual image
                        scale = np.array([
                            IMG_W / fm_w, IMG_H / fm_h, IMG_W / fm_w,
                            IMG_H / fm_h
                        ])
                        box_coords = abs_box_coords * scale
                        box_coords = [int(round(x)) for x in box_coords]

                        # Compare this box to all previous boxes of this class
                        cls = y_pred_conf[y_idx]
                        cls_prob = prob[y_idx]
                        box = (*box_coords, cls, cls_prob)
                        if len(class_boxes[cls]) == 0:
                            class_boxes[cls].append(box)
                        else:
                            suppressed = False  # did this box suppress other box(es)?
                            overlapped = False  # did this box overlap with other box(es)?
                            for other_box in class_boxes[cls]:
                                iou = calc_iou(box[:4], other_box[:4])
                                if iou > NMS_IOU_THRESH:
                                    overlapped = True
                                    # If current box has higher confidence than other box
                                    if box[5] > other_box[5]:
                                        class_boxes[cls].remove(other_box)
                                        suppressed = True
                            if suppressed or not overlapped:
                                class_boxes[cls].append(box)

                    y_idx += 1

    # Gather all the pruned boxes and return them
    boxes = []
    for cls in class_boxes.keys():
        for class_box in class_boxes[cls]:
            boxes.append(class_box)
    boxes = np.array(boxes)

    return boxes
def nms(y_pred_conf, y_pred_loc, prob):
	"""
	Non-Maximum Suppression (NMS)
	Performs NMS on all boxes of each class where predicted probability > CONF_THRES
	For all boxes exceeding IOU threshold, select the box with highest confidence
	Returns a lsit of box coordinates post-NMS

	Arguments:
		* y_pred_conf: Class predictions, numpy array of shape (num_feature_map_cells * num_defaul_boxes,)
		* y_pred_loc: Bounding box coordinates, numpy array of shape (num_feature_map_cells * num_defaul_boxes * 4,)
			These coordinates are normalized coordinates relative to center of feature map cell
		* prob: Class probabilities, numpy array of shape (num_feature_map_cells * num_defaul_boxes,)

	Returns:
		* boxes: Numpy array of boxes, with shape (num_boxes, 6). shape[0] is interpreted as:
			[x1, y1, x2, y2, class, probability], where x1/y1/x2/y2 are the coordinates of the
			upper-left and lower-right corners. Box coordinates assume the image size is IMG_W x IMG_H.
			Remember to rescale box coordinates if your target image has different dimensions.
	"""
	# Keep track of boxes for each class
	class_boxes = {}  # class -> [(x1, y1, x2, y2, prob), (...), ...]
	with open('signnames.csv', 'r') as f:
		for line in f:
			cls, _ = line.split(',')
			class_boxes[float(cls)] = []

	# Go through all possible boxes and perform class-based greedy NMS (greedy based on class prediction confidence)
	y_idx = 0
	for fm_size in FM_SIZES:
		fm_h, fm_w = fm_size  # feature map height and width
		for row in range(fm_h):
			for col in range(fm_w):
				for db in DEFAULT_BOXES:
					# Only perform calculations if class confidence > CONF_THRESH and not background class
					if prob[y_idx] > CONF_THRESH and y_pred_conf[y_idx] > 0.:
						# Calculate absolute coordinates of predicted bounding box
						xc, yc = col + 0.5, row + 0.5  # center of current feature map cell
						center_coords = np.array([xc, yc, xc, yc])
						abs_box_coords = center_coords + y_pred_loc[y_idx*4 : y_idx*4 + 4]  # predictions are offsets to center of fm cell

						# Calculate predicted box coordinates in actual image
						scale = np.array([IMG_W/fm_w, IMG_H/fm_h, IMG_W/fm_w, IMG_H/fm_h])
						box_coords = abs_box_coords * scale
						box_coords = [int(round(x)) for x in box_coords]

						# Compare this box to all previous boxes of this class
						cls = y_pred_conf[y_idx]
						cls_prob = prob[y_idx]
						box = (*box_coords, cls, cls_prob)
						if len(class_boxes[cls]) == 0:
							class_boxes[cls].append(box)
						else:
							suppressed = False  # did this box suppress other box(es)?
							overlapped = False  # did this box overlap with other box(es)?
							for other_box in class_boxes[cls]:
								iou = calc_iou(box[:4], other_box[:4])
								if iou > NMS_IOU_THRESH:
									overlapped = True
									# If current box has higher confidence than other box
									if box[5] > other_box[5]:
										class_boxes[cls].remove(other_box)
										suppressed = True
							if suppressed or not overlapped:
								class_boxes[cls].append(box)

					y_idx += 1

	# Gather all the pruned boxes and return them
	boxes = []
	for cls in class_boxes.keys():
		for class_box in class_boxes[cls]:
			boxes.append(class_box)
	boxes = np.array(boxes)

	return boxes