Added function to draw single bbox figure

Signed-off-by: Jim Martens <github@2martens.de>
This commit is contained in:
2019-09-16 11:39:31 +02:00
parent 554ccc84f9
commit 4fc8bb6f8c

View File

@ -82,10 +82,48 @@ def save_ssd_train_images(images: Union[np.ndarray, Sequence[str]], labels: np.n
]) ])
def draw_bbox_figure(image_filename: str, labels: Sequence[np.ndarray],
instances: Sequence[Sequence[np.ndarray]],
image_size: int,
output_path: str, coco_path: str,
get_coco_cat_maps_func: callable) -> None:
"""
Draws a bounding box figure and saves it under the image file name under the output path.
Args:
image_filename: complete path to image file
labels: ground truth labels for image
instances: list of predictions to be compared against each other
image_size: size of the resized images
output_path: path to save the images in
coco_path: path to the COCO data set
get_coco_cat_maps_func: callable that returns the COCO category maps for a given annotation file
"""
annotation_file_train = f"{coco_path}/annotations/instances_minival2014.json"
_, _, _, classes_to_names = get_coco_cat_maps_func(annotation_file_train)
colors = pyplot.cm.hsv(np.linspace(0, 1, len(instances) + 1)).tolist()
os.makedirs(output_path, exist_ok=True)
with Image.open(image_filename) as _image:
np_image = np.array(_image, dtype=np.uint8)
image = Image.fromarray(np_image)
figure_filename = f"{output_path}/{os.path.basename(image_filename)}_bboxes.png"
drawables = [(colors[i], _instances) for i, _instances in enumerate(instances)]
drawables.append((colors[-1], labels))
_draw_bbox_image(image=image,
filename=figure_filename,
draw_func=functools.partial(
_draw_bboxes,
image_size=image_size,
classes_to_names=classes_to_names
),
drawables=drawables)
def _draw_bbox_image(image: Image, def _draw_bbox_image(image: Image,
filename: str, filename: str,
draw_func: callable, draw_func: callable,
drawables: Sequence[Tuple[Sequence, Sequence[np.ndarray]]]): drawables: Sequence[Tuple[Union[Sequence, float], Sequence[np.ndarray]]]):
figure = pyplot.figure(figsize=(6.4, 4.8)) figure = pyplot.figure(figsize=(6.4, 4.8))
pyplot.imshow(image) pyplot.imshow(image)
@ -107,13 +145,18 @@ def _draw_bboxes(instances: Sequence[np.ndarray], axis: pyplot.Axes,
if not len(instance): if not len(instance):
continue continue
else: else:
class_id, xmin, ymin, xmax, ymax = _get_bbox_info(instance, image_size) class_id, confidence, xmin, ymin, xmax, ymax = _get_bbox_info(instance, image_size)
if class_id == 0: if class_id == 0:
continue continue
color = colors[class_id] if type(colors) is float:
label = f"{classes_to_names[class_id]}" color = colors
else:
color = colors[class_id]
label = f"{classes_to_names[class_id]} - {confidence}" \
if confidence is not None \
else f"{classes_to_names[class_id]}"
axis.add_patch( axis.add_patch(
pyplot.Rectangle((xmin, ymin), xmax - xmin, ymax - ymin, color=color, fill=False, pyplot.Rectangle((xmin, ymin), xmax - xmin, ymax - ymin, color=color, fill=False,
linewidth=2)) linewidth=2))
@ -121,21 +164,24 @@ def _draw_bboxes(instances: Sequence[np.ndarray], axis: pyplot.Axes,
bbox={'facecolor': color, 'alpha': 1.0}) bbox={'facecolor': color, 'alpha': 1.0})
def _get_bbox_info(instance: np.ndarray, image_size: int) -> Tuple[int, float, float, float, float]: def _get_bbox_info(instance: np.ndarray, image_size: int) -> Tuple[int, Union[float, None], float, float, float, float]:
if len(instance) == 5: # ground truth if len(instance) == 5: # ground truth
class_id = int(instance[0]) class_id = int(instance[0])
confidence = None
xmin = instance[1] xmin = instance[1]
ymin = instance[2] ymin = instance[2]
xmax = instance[3] xmax = instance[3]
ymax = instance[4] ymax = instance[4]
elif len(instance) == 7: # predictions elif len(instance) == 7: # predictions
class_id = int(instance[0]) class_id = int(instance[0])
confidence = instance[1]
xmin = instance[3] xmin = instance[3]
ymin = instance[4] ymin = instance[4]
xmax = instance[5] xmax = instance[5]
ymax = instance[6] ymax = instance[6]
elif len(instance) == 6: # predictions using Caffe method elif len(instance) == 6: # predictions using Caffe method
class_id = int(instance[0]) class_id = int(instance[0])
confidence = instance[1]
xmin = instance[2] xmin = instance[2]
ymin = instance[3] ymin = instance[3]
xmax = instance[4] xmax = instance[4]
@ -143,6 +189,7 @@ def _get_bbox_info(instance: np.ndarray, image_size: int) -> Tuple[int, float, f
else: else:
instance = np.copy(instance) instance = np.copy(instance)
class_id = np.argmax(instance[:-12], axis=0) class_id = np.argmax(instance[:-12], axis=0)
confidence = np.amax(instance[:-12], axis=0)
instance[-12:-8] *= instance[-4:] # multiply with variances instance[-12:-8] *= instance[-4:] # multiply with variances
instance[[-11, -9]] *= np.expand_dims(instance[-5] - instance[-7], axis=-1) instance[[-11, -9]] *= np.expand_dims(instance[-5] - instance[-7], axis=-1)
instance[[-12, -10]] *= np.expand_dims(instance[-6] - instance[-8], axis=-1) instance[[-12, -10]] *= np.expand_dims(instance[-6] - instance[-8], axis=-1)
@ -154,4 +201,4 @@ def _get_bbox_info(instance: np.ndarray, image_size: int) -> Tuple[int, float, f
xmax = instance[-10] xmax = instance[-10]
ymax = instance[-9] ymax = instance[-9]
return class_id, xmin, ymin, xmax, ymax return class_id, confidence, xmin, ymin, xmax, ymax