未验证 提交 356bb7e2 编写于 作者: K Kaipeng Deng 提交者: GitHub

add VOC visualize (#2547)

* add VOC visualize

* fixn ssd_mobilenet_v1_voc.yml

* use default label

* clean TestFeed dataset config

* fix voc default label

* fix format

* fix as review

* revert voc default

* use defult label for all

* enable batch size != 1
上级 32e54ca0
...@@ -135,7 +135,6 @@ FasterRCNNTestFeed: ...@@ -135,7 +135,6 @@ FasterRCNNTestFeed:
pad_to_stride: 32 pad_to_stride: 32
dataset: dataset:
annotation: annotations/instances_val2017.json annotation: annotations/instances_val2017.json
image_dir: val2017
drop_last: false drop_last: false
num_workers: 2 num_workers: 2
shuffle: false shuffle: false
...@@ -112,6 +112,4 @@ FasterRCNNEvalFeed: ...@@ -112,6 +112,4 @@ FasterRCNNEvalFeed:
FasterRCNNTestFeed: FasterRCNNTestFeed:
batch_size: 1 batch_size: 1
dataset: dataset:
dataset_dir: data/coco
annotation: annotations/instances_val2017.json annotation: annotations/instances_val2017.json
image_dir: val2017
...@@ -135,8 +135,6 @@ FasterRCNNTestFeed: ...@@ -135,8 +135,6 @@ FasterRCNNTestFeed:
- !PadBatch - !PadBatch
pad_to_stride: 32 pad_to_stride: 32
dataset: dataset:
dataset_dir: data/coco
annotation: annotations/instances_val2017.json annotation: annotations/instances_val2017.json
image_dir: val2017
num_workers: 2 num_workers: 2
shuffle: False shuffle: False
...@@ -135,8 +135,6 @@ FasterRCNNTestFeed: ...@@ -135,8 +135,6 @@ FasterRCNNTestFeed:
- !PadBatch - !PadBatch
pad_to_stride: 32 pad_to_stride: 32
dataset: dataset:
dataset_dir: data/coco
annotation: annotations/instances_val2017.json annotation: annotations/instances_val2017.json
image_dir: val2017
num_workers: 2 num_workers: 2
shuffle: False shuffle: False
...@@ -136,8 +136,6 @@ FasterRCNNTestFeed: ...@@ -136,8 +136,6 @@ FasterRCNNTestFeed:
- !PadBatch - !PadBatch
pad_to_stride: 32 pad_to_stride: 32
dataset: dataset:
dataset_dir: data/coco
annotation: annotations/instances_val2017.json annotation: annotations/instances_val2017.json
image_dir: val2017
num_workers: 2 num_workers: 2
shuffle: False shuffle: False
...@@ -136,8 +136,6 @@ FasterRCNNTestFeed: ...@@ -136,8 +136,6 @@ FasterRCNNTestFeed:
- !PadBatch - !PadBatch
pad_to_stride: 32 pad_to_stride: 32
dataset: dataset:
dataset_dir: data/coco
annotation: annotations/instances_val2017.json annotation: annotations/instances_val2017.json
image_dir: val2017
num_workers: 2 num_workers: 2
shuffle: False shuffle: False
...@@ -112,6 +112,4 @@ FasterRCNNEvalFeed: ...@@ -112,6 +112,4 @@ FasterRCNNEvalFeed:
FasterRCNNTestFeed: FasterRCNNTestFeed:
batch_size: 1 batch_size: 1
dataset: dataset:
dataset_dir: data/coco
annotation: annotations/instances_val2017.json annotation: annotations/instances_val2017.json
image_dir: val2017
...@@ -112,6 +112,4 @@ FasterRCNNEvalFeed: ...@@ -112,6 +112,4 @@ FasterRCNNEvalFeed:
FasterRCNNTestFeed: FasterRCNNTestFeed:
batch_size: 1 batch_size: 1
dataset: dataset:
dataset_dir: data/coco
annotation: annotations/instances_val2017.json annotation: annotations/instances_val2017.json
image_dir: val2017
...@@ -135,7 +135,6 @@ FasterRCNNTestFeed: ...@@ -135,7 +135,6 @@ FasterRCNNTestFeed:
pad_to_stride: 32 pad_to_stride: 32
dataset: dataset:
annotation: annotations/instances_val2017.json annotation: annotations/instances_val2017.json
image_dir: val2017
drop_last: false drop_last: false
num_workers: 2 num_workers: 2
shuffle: false shuffle: false
...@@ -135,7 +135,6 @@ FasterRCNNTestFeed: ...@@ -135,7 +135,6 @@ FasterRCNNTestFeed:
pad_to_stride: 32 pad_to_stride: 32
dataset: dataset:
annotation: coco/annotations/instances_val2017.json annotation: coco/annotations/instances_val2017.json
image_dir: coco/val2017
drop_last: false drop_last: false
num_workers: 2 num_workers: 2
shuffle: false shuffle: false
...@@ -114,6 +114,4 @@ FasterRCNNEvalFeed: ...@@ -114,6 +114,4 @@ FasterRCNNEvalFeed:
FasterRCNNTestFeed: FasterRCNNTestFeed:
batch_size: 1 batch_size: 1
dataset: dataset:
dataset_dir: data/coco
annotation: annotations/instances_val2017.json annotation: annotations/instances_val2017.json
image_dir: val2017
...@@ -136,8 +136,6 @@ FasterRCNNTestFeed: ...@@ -136,8 +136,6 @@ FasterRCNNTestFeed:
- !PadBatch - !PadBatch
pad_to_stride: 32 pad_to_stride: 32
dataset: dataset:
dataset_dir: data/coco
annotation: annotations/instances_val2017.json annotation: annotations/instances_val2017.json
image_dir: val2017
num_workers: 2 num_workers: 2
shuffle: False shuffle: False
...@@ -121,8 +121,6 @@ FasterRCNNEvalFeed: ...@@ -121,8 +121,6 @@ FasterRCNNEvalFeed:
FasterRCNNTestFeed: FasterRCNNTestFeed:
batch_size: 1 batch_size: 1
dataset: dataset:
dataset_dir: data/coco
annotation: annotations/instances_val2017.json annotation: annotations/instances_val2017.json
image_dir: val2017
num_workers: 2 num_workers: 2
shuffle: False shuffle: False
...@@ -138,8 +138,6 @@ FasterRCNNTestFeed: ...@@ -138,8 +138,6 @@ FasterRCNNTestFeed:
- !PadBatch - !PadBatch
pad_to_stride: 32 pad_to_stride: 32
dataset: dataset:
dataset_dir: data/coco
annotation: annotations/instances_val2017.json annotation: annotations/instances_val2017.json
image_dir: val2017
num_workers: 2 num_workers: 2
shuffle: False shuffle: False
...@@ -138,8 +138,6 @@ FasterRCNNTestFeed: ...@@ -138,8 +138,6 @@ FasterRCNNTestFeed:
- !PadBatch - !PadBatch
pad_to_stride: 32 pad_to_stride: 32
dataset: dataset:
dataset_dir: data/coco
annotation: annotations/instances_val2017.json annotation: annotations/instances_val2017.json
image_dir: val2017
num_workers: 2 num_workers: 2
shuffle: False shuffle: False
...@@ -137,8 +137,6 @@ FasterRCNNTestFeed: ...@@ -137,8 +137,6 @@ FasterRCNNTestFeed:
- !PadBatch - !PadBatch
pad_to_stride: 32 pad_to_stride: 32
dataset: dataset:
dataset_dir: data/coco
annotation: annotations/instances_val2017.json annotation: annotations/instances_val2017.json
image_dir: val2017
num_workers: 2 num_workers: 2
shuffle: False shuffle: False
...@@ -137,8 +137,6 @@ FasterRCNNTestFeed: ...@@ -137,8 +137,6 @@ FasterRCNNTestFeed:
- !PadBatch - !PadBatch
pad_to_stride: 32 pad_to_stride: 32
dataset: dataset:
dataset_dir: data/coco
annotation: annotations/instances_val2017.json annotation: annotations/instances_val2017.json
image_dir: val2017
num_workers: 2 num_workers: 2
shuffle: False shuffle: False
...@@ -144,8 +144,6 @@ MaskRCNNTestFeed: ...@@ -144,8 +144,6 @@ MaskRCNNTestFeed:
- !PadBatch - !PadBatch
pad_to_stride: 32 pad_to_stride: 32
dataset: dataset:
dataset_dir: data/coco
annotation: annotations/instances_val2017.json annotation: annotations/instances_val2017.json
image_dir: val2017
num_workers: 2 num_workers: 2
use_padded_im_info: True use_padded_im_info: True
...@@ -144,8 +144,6 @@ MaskRCNNTestFeed: ...@@ -144,8 +144,6 @@ MaskRCNNTestFeed:
- !PadBatch - !PadBatch
pad_to_stride: 32 pad_to_stride: 32
dataset: dataset:
dataset_dir: data/coco
annotation: annotations/instances_val2017.json annotation: annotations/instances_val2017.json
image_dir: val2017
num_workers: 2 num_workers: 2
use_padded_im_info: True use_padded_im_info: True
...@@ -125,6 +125,4 @@ MaskRCNNEvalFeed: ...@@ -125,6 +125,4 @@ MaskRCNNEvalFeed:
MaskRCNNTestFeed: MaskRCNNTestFeed:
batch_size: 1 batch_size: 1
dataset: dataset:
dataset_dir: data/coco
annotation: annotations/instances_val2017.json annotation: annotations/instances_val2017.json
image_dir: val2017
...@@ -126,6 +126,4 @@ MaskRCNNEvalFeed: ...@@ -126,6 +126,4 @@ MaskRCNNEvalFeed:
MaskRCNNTestFeed: MaskRCNNTestFeed:
batch_size: 1 batch_size: 1
dataset: dataset:
dataset_dir: data/coco
annotation: annotations/instances_val2017.json annotation: annotations/instances_val2017.json
image_dir: val2017
...@@ -144,8 +144,6 @@ MaskRCNNTestFeed: ...@@ -144,8 +144,6 @@ MaskRCNNTestFeed:
- !PadBatch - !PadBatch
pad_to_stride: 32 pad_to_stride: 32
dataset: dataset:
dataset_dir: data/coco
annotation: annotations/instances_val2017.json annotation: annotations/instances_val2017.json
image_dir: val2017
num_workers: 2 num_workers: 2
use_padded_im_info: True use_padded_im_info: True
...@@ -144,8 +144,6 @@ MaskRCNNTestFeed: ...@@ -144,8 +144,6 @@ MaskRCNNTestFeed:
- !PadBatch - !PadBatch
pad_to_stride: 32 pad_to_stride: 32
dataset: dataset:
dataset_dir: data/coco
annotation: annotations/instances_val2017.json annotation: annotations/instances_val2017.json
image_dir: val2017
num_workers: 2 num_workers: 2
use_padded_im_info: True use_padded_im_info: True
...@@ -147,8 +147,6 @@ MaskRCNNTestFeed: ...@@ -147,8 +147,6 @@ MaskRCNNTestFeed:
- !PadBatch - !PadBatch
pad_to_stride: 32 pad_to_stride: 32
dataset: dataset:
dataset_dir: data/coco
annotation: annotations/instances_val2017.json annotation: annotations/instances_val2017.json
image_dir: val2017
num_workers: 2 num_workers: 2
use_padded_im_info: True use_padded_im_info: True
...@@ -149,8 +149,6 @@ MaskRCNNTestFeed: ...@@ -149,8 +149,6 @@ MaskRCNNTestFeed:
- !PadBatch - !PadBatch
pad_to_stride: 32 pad_to_stride: 32
dataset: dataset:
dataset_dir: data/coco
annotation: annotations/instances_val2017.json annotation: annotations/instances_val2017.json
image_dir: val2017
num_workers: 2 num_workers: 2
use_padded_im_info: True use_padded_im_info: True
...@@ -148,9 +148,7 @@ FasterRCNNTestFeed: ...@@ -148,9 +148,7 @@ FasterRCNNTestFeed:
- !PadBatch - !PadBatch
pad_to_stride: 128 pad_to_stride: 128
dataset: dataset:
dataset_dir: data/coco
annotation: annotations/instances_val2017.json annotation: annotations/instances_val2017.json
image_dir: val2017
drop_last: false drop_last: false
image_shape: [3, 1333, 800] image_shape: [3, 1333, 800]
num_workers: 2 num_workers: 2
......
...@@ -65,6 +65,7 @@ SSDTrainFeed: ...@@ -65,6 +65,7 @@ SSDTrainFeed:
dataset_dir: data/voc dataset_dir: data/voc
annotation: VOCdevkit/VOC_all/ImageSets/Main/train.txt annotation: VOCdevkit/VOC_all/ImageSets/Main/train.txt
image_dir: VOCdevkit/VOC_all/JPEGImages image_dir: VOCdevkit/VOC_all/JPEGImages
use_default_label: true
SSDEvalFeed: SSDEvalFeed:
batch_size: 64 batch_size: 64
...@@ -73,14 +74,11 @@ SSDEvalFeed: ...@@ -73,14 +74,11 @@ SSDEvalFeed:
dataset_dir: data/voc dataset_dir: data/voc
annotation: VOCdevkit/VOC_all/ImageSets/Main/val.txt annotation: VOCdevkit/VOC_all/ImageSets/Main/val.txt
image_dir: VOCdevkit/VOC_all/JPEGImages image_dir: VOCdevkit/VOC_all/JPEGImages
use_default_label: false use_default_label: true
drop_last: false drop_last: false
SSDTestFeed: SSDTestFeed:
batch_size: 1 batch_size: 1
dataset: dataset:
dataset_dir: data/voc use_default_label: true
annotation: VOCdevkit/VOC_all/ImageSets/Main/test.txt
image_dir: VOCdevkit/VOC_all/JPEGImages
use_default_label: false
drop_last: false drop_last: false
...@@ -77,6 +77,4 @@ YoloEvalFeed: ...@@ -77,6 +77,4 @@ YoloEvalFeed:
YoloTestFeed: YoloTestFeed:
batch_size: 1 batch_size: 1
dataset: dataset:
dataset_dir: data/coco
annotation: annotations/instances_val2017.json annotation: annotations/instances_val2017.json
image_dir: val2017
...@@ -78,6 +78,4 @@ YoloEvalFeed: ...@@ -78,6 +78,4 @@ YoloEvalFeed:
YoloTestFeed: YoloTestFeed:
batch_size: 1 batch_size: 1
dataset: dataset:
dataset_dir: data/coco
annotation: annotations/instances_val2017.json annotation: annotations/instances_val2017.json
image_dir: val2017
...@@ -80,6 +80,4 @@ YoloEvalFeed: ...@@ -80,6 +80,4 @@ YoloEvalFeed:
YoloTestFeed: YoloTestFeed:
batch_size: 1 batch_size: 1
dataset: dataset:
dataset_dir: data/coco
annotation: annotations/instances_val2017.json annotation: annotations/instances_val2017.json
image_dir: val2017
...@@ -781,7 +781,7 @@ class SSDTestFeed(DataFeed): ...@@ -781,7 +781,7 @@ class SSDTestFeed(DataFeed):
def __init__(self, def __init__(self,
dataset=SimpleDataSet(VOC_TEST_ANNOTATION).__dict__, dataset=SimpleDataSet(VOC_TEST_ANNOTATION).__dict__,
fields=['image'], fields=['image', 'im_id'],
image_shape=[3, 300, 300], image_shape=[3, 300, 300],
sample_transforms=[ sample_transforms=[
DecodeImage(to_rgb=True), DecodeImage(to_rgb=True),
......
...@@ -243,25 +243,25 @@ def load(anno_path, sample_num=-1, use_default_label=True): ...@@ -243,25 +243,25 @@ def load(anno_path, sample_num=-1, use_default_label=True):
def pascalvoc_label(): def pascalvoc_label():
labels_map = { labels_map = {
'aeroplane': 1, 'aeroplane': 1,
'bicycle': 2, 'bicycle': 2,
'bird': 3, 'bird': 3,
'boat': 4, 'boat': 4,
'bottle': 5, 'bottle': 5,
'bus': 6, 'bus': 6,
'car': 7, 'car': 7,
'cat': 8, 'cat': 8,
'chair': 9, 'chair': 9,
'cow': 10, 'cow': 10,
'diningtable': 11, 'diningtable': 11,
'dog': 12, 'dog': 12,
'horse': 13, 'horse': 13,
'motorbike': 14, 'motorbike': 14,
'person': 15, 'person': 15,
'pottedplant': 16, 'pottedplant': 16,
'sheep': 17, 'sheep': 17,
'sofa': 18, 'sofa': 18,
'train': 19, 'train': 19,
'tvmonitor': 20 'tvmonitor': 20
} }
return labels_map return labels_map
...@@ -109,7 +109,7 @@ def dump_voc_as_pickle(args): ...@@ -109,7 +109,7 @@ def dump_voc_as_pickle(args):
if not os.path.exists(save_dir): if not os.path.exists(save_dir):
os.makedirs(save_dir) os.makedirs(save_dir)
save_dir = args.save_dir save_dir = args.save_dir
anno_path = args.annotation anno_path = os.path.expanduser(args.annotation)
roidb, cat2id = loader.load( roidb, cat2id = loader.load(
anno_path, samples, with_cat2id=True, use_default_label=None) anno_path, samples, with_cat2id=True, use_default_label=None)
samples = len(roidb) samples = len(roidb)
......
...@@ -183,7 +183,8 @@ class ArrangeTestSSD(BaseOperator): ...@@ -183,7 +183,8 @@ class ArrangeTestSSD(BaseOperator):
sample: a tuple containing the following items: (image) sample: a tuple containing the following items: (image)
""" """
im = sample['image'] im = sample['image']
outs = (im) im_id = sample['im_id']
outs = (im, im_id)
return outs return outs
......
...@@ -31,7 +31,7 @@ feed_var_def = [ ...@@ -31,7 +31,7 @@ feed_var_def = [
{'name': 'is_crowd', 'shape': [1], 'dtype': 'int32', 'lod_level': 1}, {'name': 'is_crowd', 'shape': [1], 'dtype': 'int32', 'lod_level': 1},
{'name': 'gt_mask', 'shape': [2], 'dtype': 'float32', 'lod_level': 3}, {'name': 'gt_mask', 'shape': [2], 'dtype': 'float32', 'lod_level': 3},
{'name': 'is_difficult', 'shape': [1], 'dtype': 'int32', 'lod_level': 1}, {'name': 'is_difficult', 'shape': [1], 'dtype': 'int32', 'lod_level': 1},
{'name': 'gt_score', 'shape': None, 'dtype': 'float32', 'lod_level': 0}, {'name': 'gt_score', 'shape': [1], 'dtype': 'float32', 'lod_level': 0},
{'name': 'im_shape', 'shape': [3], 'dtype': 'float32', 'lod_level': 0}, {'name': 'im_shape', 'shape': [3], 'dtype': 'float32', 'lod_level': 0},
] ]
# yapf: enable # yapf: enable
......
...@@ -34,6 +34,14 @@ __all__ = [ ...@@ -34,6 +34,14 @@ __all__ = [
] ]
def clip_bbox(bbox):
xmin = max(min(bbox[0], 1.), 0.)
ymin = max(min(bbox[1], 1.), 0.)
xmax = max(min(bbox[2], 1.), 0.)
ymax = max(min(bbox[3], 1.), 0.)
return xmin, ymin, xmax, ymax
def bbox_eval(results, anno_file, outfile, with_background=True): def bbox_eval(results, anno_file, outfile, with_background=True):
assert 'bbox' in results[0] assert 'bbox' in results[0]
assert outfile.endswith('.json') assert outfile.endswith('.json')
...@@ -80,7 +88,7 @@ def mask_eval(results, anno_file, outfile, resolution, thresh_binarize=0.5): ...@@ -80,7 +88,7 @@ def mask_eval(results, anno_file, outfile, resolution, thresh_binarize=0.5):
coco_ev.summarize() coco_ev.summarize()
def bbox2out(results, clsid2catid): def bbox2out(results, clsid2catid, is_bbox_normalized=False):
xywh_res = [] xywh_res = []
for t in results: for t in results:
bboxes = t['bbox'][0] bboxes = t['bbox'][0]
...@@ -97,8 +105,16 @@ def bbox2out(results, clsid2catid): ...@@ -97,8 +105,16 @@ def bbox2out(results, clsid2catid):
dt = bboxes[k] dt = bboxes[k]
clsid, score, xmin, ymin, xmax, ymax = dt.tolist() clsid, score, xmin, ymin, xmax, ymax = dt.tolist()
catid = clsid2catid[clsid] catid = clsid2catid[clsid]
w = xmax - xmin + 1
h = ymax - ymin + 1 if is_bbox_normalized:
xmin, ymin, xmax, ymax = \
clip_bbox([xmin, ymin, xmax, ymax])
w = xmax - xmin
h = ymax - ymin
else:
w = xmax - xmin + 1
h = ymax - ymin + 1
bbox = [xmin, ymin, w, h] bbox = [xmin, ymin, w, h]
coco_res = { coco_res = {
'image_id': im_id, 'image_id': im_id,
...@@ -211,8 +227,11 @@ def expand_boxes(boxes, scale): ...@@ -211,8 +227,11 @@ def expand_boxes(boxes, scale):
return boxes_exp return boxes_exp
def get_category_info(anno_file=None, with_background=True): def get_category_info(anno_file=None,
if anno_file is None or not os.path.exists(anno_file): with_background=True,
use_default_label=False):
if use_default_label or anno_file is None \
or not os.path.exists(anno_file):
logger.info("Not found annotation file {}, load " logger.info("Not found annotation file {}, load "
"coco17 categories.".format(anno_file)) "coco17 categories.".format(anno_file))
return coco17_category_info(with_background) return coco17_category_info(with_background)
......
...@@ -17,6 +17,7 @@ from __future__ import division ...@@ -17,6 +17,7 @@ from __future__ import division
from __future__ import print_function from __future__ import print_function
from __future__ import unicode_literals from __future__ import unicode_literals
import logging
import numpy as np import numpy as np
import pycocotools.mask as mask_util import pycocotools.mask as mask_util
from PIL import Image, ImageDraw from PIL import Image, ImageDraw
...@@ -25,23 +26,28 @@ from .colormap import colormap ...@@ -25,23 +26,28 @@ from .colormap import colormap
__all__ = ['visualize_results'] __all__ = ['visualize_results']
logger = logging.getLogger(__name__)
def visualize_results(image, def visualize_results(image,
im_id,
catid2name, catid2name,
threshold=0.5, threshold=0.5,
bbox_results=None, bbox_results=None,
mask_results=None): mask_results=None,
is_bbox_normalized=False):
""" """
Visualize bbox and mask results Visualize bbox and mask results
""" """
if mask_results: if mask_results:
image = draw_mask(image, mask_results, threshold) image = draw_mask(image, im_id, mask_results, threshold)
if bbox_results: if bbox_results:
image = draw_bbox(image, catid2name, bbox_results, threshold) image = draw_bbox(image, im_id, catid2name, bbox_results,
threshold, is_bbox_normalized)
return image return image
def draw_mask(image, segms, threshold, alpha=0.7): def draw_mask(image, im_id, segms, threshold, alpha=0.7):
""" """
Draw mask on image Draw mask on image
""" """
...@@ -50,6 +56,8 @@ def draw_mask(image, segms, threshold, alpha=0.7): ...@@ -50,6 +56,8 @@ def draw_mask(image, segms, threshold, alpha=0.7):
w_ratio = .4 w_ratio = .4
img_array = np.array(image).astype('float32') img_array = np.array(image).astype('float32')
for dt in np.array(segms): for dt in np.array(segms):
if im_id != dt['image_id']:
continue
segm, score = dt['segmentation'], dt['score'] segm, score = dt['segmentation'], dt['score']
if score < threshold: if score < threshold:
continue continue
...@@ -65,18 +73,28 @@ def draw_mask(image, segms, threshold, alpha=0.7): ...@@ -65,18 +73,28 @@ def draw_mask(image, segms, threshold, alpha=0.7):
return Image.fromarray(img_array.astype('uint8')) return Image.fromarray(img_array.astype('uint8'))
def draw_bbox(image, catid2name, bboxes, threshold): def draw_bbox(image, im_id, catid2name, bboxes, threshold,
is_bbox_normalized=False):
""" """
Draw bbox on image Draw bbox on image
""" """
draw = ImageDraw.Draw(image) draw = ImageDraw.Draw(image)
im_width, im_height = image.size
for dt in np.array(bboxes): for dt in np.array(bboxes):
if im_id != dt['image_id']:
continue
catid, bbox, score = dt['category_id'], dt['bbox'], dt['score'] catid, bbox, score = dt['category_id'], dt['bbox'], dt['score']
if score < threshold: if score < threshold:
continue continue
xmin, ymin, w, h = bbox xmin, ymin, w, h = bbox
if is_bbox_normalized:
im_width, im_height = image.size
xmin *= im_width
ymin *= im_height
w *= im_width
h *= im_height
xmax = xmin + w xmax = xmin + w
ymax = ymin + h ymax = ymin + h
draw.line( draw.line(
...@@ -86,5 +104,7 @@ def draw_bbox(image, catid2name, bboxes, threshold): ...@@ -86,5 +104,7 @@ def draw_bbox(image, catid2name, bboxes, threshold):
fill='red') fill='red')
if image.mode == 'RGB': if image.mode == 'RGB':
draw.text((xmin, ymin), catid2name[catid], (255, 255, 0)) draw.text((xmin, ymin), catid2name[catid], (255, 255, 0))
logger.debug("\t {:15s} at {:25} score: {:.5f}".format(catid2name[catid],
str(list(map(int, list([xmin, ymin, xmax, ymax])))), score))
return image return image
# Copyright (c) 2019 PaddlePaddle Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals
import os
import sys
import numpy as np
from ..data.source.voc_loader import pascalvoc_label
from .coco_eval import bbox2out
import logging
logger = logging.getLogger(__name__)
__all__ = [
'bbox2out', 'get_category_info'
]
def get_category_info(anno_file=None,
with_background=True,
use_default_label=False):
if use_default_label or anno_file is None \
or not os.path.exists(anno_file):
logger.info("Not found annotation file {}, load "
"voc2012 categories.".format(anno_file))
return vocall_category_info(with_background)
else:
logger.info("Load categories from {}".format(anno_file))
return get_category_info_from_anno(anno_file, with_background)
def get_category_info_from_anno(anno_file, with_background=True):
"""
Get class id to category id map and category id
to category name map from annotation file.
Args:
anno_file (str): annotation file path
with_background (bool, default True):
whether load background as class 0.
"""
cats = []
with open(anno_file) as f:
for line in f.readlines():
cats.append(line.strip())
if cats[0] != 'background' and with_background:
cats.insert(0, 'background')
if cats[0] == 'background' and not with_background:
cats = cats[1:]
clsid2catid = {i: i for i in range(len(cats))}
catid2name = {i: name for i, name in enumerate(cats)}
return clsid2catid, catid2name
def vocall_category_info(with_background=True):
"""
Get class id to category id map and category id
to category name map of mixup voc dataset
Args:
with_background (bool, default True):
whether load background as class 0.
"""
label_map = pascalvoc_label()
label_map = sorted(label_map.items(), key=lambda x: x[1])
cats = [l[0] for l in label_map]
if with_background:
cats.insert(0, 'background')
clsid2catid = {i: i for i in range(len(cats))}
catid2name = {i: name for i, name in enumerate(cats)}
return clsid2catid, catid2name
...@@ -119,18 +119,21 @@ def main(): ...@@ -119,18 +119,21 @@ def main():
extra_keys = [] extra_keys = []
if cfg['metric'] == 'COCO': if cfg['metric'] == 'COCO':
extra_keys = ['im_info', 'im_id', 'im_shape'] extra_keys = ['im_info', 'im_id', 'im_shape']
if cfg['metric'] == 'VOC':
extra_keys = ['im_id']
keys, values, _ = parse_fetches(test_fetches, infer_prog, extra_keys) keys, values, _ = parse_fetches(test_fetches, infer_prog, extra_keys)
# 6. Parse dataset category # 6. Parse dataset category
if cfg.metric == 'COCO': if cfg.metric == 'COCO':
from ppdet.utils.coco_eval import bbox2out, mask2out, get_category_info from ppdet.utils.coco_eval import bbox2out, mask2out, get_category_info
if cfg.metric == "VOC": if cfg.metric == "VOC":
# TODO(dengkaipeng): add VOC metric process from ppdet.utils.voc_eval import bbox2out, get_category_info
pass
anno_file = getattr(test_feed.dataset, 'annotation', None) anno_file = getattr(test_feed.dataset, 'annotation', None)
with_background = getattr(test_feed, 'with_background', True) with_background = getattr(test_feed, 'with_background', True)
clsid2catid, catid2name = get_category_info(anno_file, with_background) use_default_label = getattr(test_feed, 'use_default_label', False)
clsid2catid, catid2name = get_category_info(anno_file, with_background,
use_default_label)
imid2path = reader.imid2path imid2path = reader.imid2path
for iter_id, data in enumerate(reader()): for iter_id, data in enumerate(reader()):
...@@ -144,27 +147,27 @@ def main(): ...@@ -144,27 +147,27 @@ def main():
} }
logger.info('Infer iter {}'.format(iter_id)) logger.info('Infer iter {}'.format(iter_id))
im_id = int(res['im_id'][0]) bbox_results = None
image_path = imid2path[im_id] mask_results = None
if cfg.metric == 'COCO': is_bbox_normalized = True if cfg.metric == 'VOC' else False
bbox_results = None if 'bbox' in res:
mask_results = None bbox_results = bbox2out([res], clsid2catid,
if 'bbox' in res: is_bbox_normalized)
bbox_results = bbox2out([res], clsid2catid) if 'mask' in res:
if 'mask' in res: mask_results = mask2out([res], clsid2catid,
mask_results = mask2out([res], clsid2catid, cfg.MaskHead['resolution'])
cfg.MaskHead.resolution)
image = Image.open(image_path) # visualize result
image = visualize_results(image, catid2name, 0.5, im_ids = res['im_id'][0]
bbox_results, mask_results) for im_id in im_ids:
image_path = imid2path[int(im_id)]
image = Image.open(image_path).convert('RGB')
visualize_results(image, int(im_id), catid2name, 0.5, bbox_results,
mask_results, is_bbox_normalized)
save_name = get_save_image_name(FLAGS.output_dir, image_path) save_name = get_save_image_name(FLAGS.output_dir, image_path)
logger.info("Detection bbox results save in {}".format(save_name)) logger.info("Detection bbox results save in {}".format(save_name))
image.save(save_name) image.save(save_name)
if cfg.metric == "VOC":
# TODO(dengkaipeng): add VOC metric process
pass
if __name__ == '__main__': if __name__ == '__main__':
parser = ArgsParser() parser = ArgsParser()
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册