Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: Update COCO showAnns function to add useful features like Category-wise Color, etc. #574

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
148 changes: 148 additions & 0 deletions PythonAPI/pycocotools/ColorLookUp.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
color_lut = {1: '#000080',
2: '#00008B',
3: '#0000CD',
4: '#0000FF',
5: '#006400',
6: '#008000',
7: '#008080',
8: '#008B8B',
9: '#00BFFF',
10: '#00CED1',
11: '#00FA9A',
12: '#00FF00',
13: '#00FF7F',
14: '#00FFFF',
15: '#00FFFF',
16: '#191970',
17: '#1E90FF',
18: '#20B2AA',
19: '#228B22',
20: '#2E8B57',
21: '#2F4F4F',
22: '#2F4F4F',
23: '#32CD32',
24: '#3CB371',
25: '#40E0D0',
26: '#4169E1',
27: '#4682B4',
28: '#483D8B',
29: '#48D1CC',
30: '#4B0082',
31: '#556B2F',
32: '#5F9EA0',
33: '#6495ED',
34: '#663399',
35: '#66CDAA',
36: '#696969',
37: '#696969',
38: '#6A5ACD',
39: '#6B8E23',
40: '#708090',
41: '#708090',
42: '#778899',
43: '#778899',
44: '#7B68EE',
45: '#7CFC00',
46: '#7FFF00',
47: '#7FFFD4',
48: '#800000',
49: '#800080',
50: '#808000',
51: '#808080',
52: '#808080',
53: '#87CEEB',
54: '#87CEFA',
55: '#8A2BE2',
56: '#8B0000',
57: '#8B008B',
58: '#8B4513',
59: '#8FBC8F',
60: '#90EE90',
61: '#9370DB',
62: '#9400D3',
63: '#98FB98',
64: '#9932CC',
65: '#9ACD32',
66: '#A0522D',
67: '#A52A2A',
68: '#A9A9A9',
69: '#A9A9A9',
70: '#ADD8E6',
71: '#ADFF2F',
72: '#AFEEEE',
73: '#B0C4DE',
74: '#B0E0E6',
75: '#B22222',
76: '#B8860B',
77: '#BA55D3',
78: '#BC8F8F',
79: '#BDB76B',
80: '#C0C0C0',
81: '#C71585',
82: '#CD5C5C',
83: '#CD853F',
84: '#D2691E',
85: '#D2B48C',
86: '#D3D3D3',
87: '#D3D3D3',
88: '#D8BFD8',
89: '#DA70D6',
90: '#DAA520',
91: '#DB7093',
92: '#DC143C',
93: '#DCDCDC',
94: '#DDA0DD',
95: '#DEB887',
96: '#E0FFFF',
97: '#E6E6FA',
98: '#E9967A',
99: '#EE82EE',
100: '#EEE8AA',
101: '#F08080',
102: '#F0E68C',
103: '#F0F8FF',
104: '#F0FFF0',
105: '#F0FFFF',
106: '#F4A460',
107: '#F5DEB3',
108: '#F5F5DC',
109: '#F5F5F5',
110: '#F5FFFA',
111: '#F8F8FF',
112: '#FA8072',
113: '#FAEBD7',
114: '#FAF0E6',
115: '#FAFAD2',
116: '#FDF5E6',
117: '#FF0000',
118: '#FF00FF',
119: '#FF00FF',
120: '#FF1493',
121: '#FF4500',
122: '#FF6347',
123: '#FF69B4',
124: '#FF7F50',
125: '#FF8C00',
126: '#FFA07A',
127: '#FFA500',
128: '#FFB6C1',
129: '#FFC0CB',
130: '#FFD700',
131: '#FFDAB9',
132: '#FFDEAD',
133: '#FFE4B5',
134: '#FFE4C4',
135: '#FFE4E1',
136: '#FFEBCD',
137: '#FFEFD5',
138: '#FFF0F5',
139: '#FFF5EE',
140: '#FFF8DC',
141: '#FFFACD',
142: '#FFFAF0',
143: '#FFFAFA',
144: '#FFFF00',
145: '#FFFFE0',
146: '#FFFFF0',
147: '#FFFFFF',
148: ''}
59 changes: 48 additions & 11 deletions PythonAPI/pycocotools/coco.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,12 @@
import numpy as np
import copy
import itertools
from . import mask as maskUtils
import mask as maskUtils
import os
from collections import defaultdict
import sys
from ColorLookUp import color_lut as color_code

PYTHON_VERSION = sys.version_info[0]
if PYTHON_VERSION == 2:
from urllib import urlretrieve
Expand All @@ -81,7 +83,8 @@ def __init__(self, annotation_file=None):
if not annotation_file == None:
print('loading annotations into memory...')
tic = time.time()
dataset = json.load(open(annotation_file, 'r'))
with open(annotation_file, 'r') as f:
dataset = json.load(f)
assert type(dataset)==dict, 'annotation file format {} not supported'.format(type(dataset))
print('Done (t={:0.2f}s)'.format(time.time()- tic))
self.dataset = dataset
Expand Down Expand Up @@ -230,12 +233,32 @@ def loadImgs(self, ids=[]):
elif type(ids) == int:
return [self.imgs[ids]]

def showAnns(self, anns, draw_bbox=False):
def showAnns(self, anns, cats, draw_bbox=False, bbox_line_width=2, class_based_colors=False, label_polygons=False, label_font_size=5, draw_mask=False):
"""
Display the specified annotations.
:param anns (array of object): annotations to display
:param cats (array of object): categories to be considered
:param draw_bbox (bool): weather to draw bboxes while showing anns
:param bbox_line_width (int): line width while drawing bbox
:param class_based_colors (bool): draw bboxes/masks with colors specific to each category
:param label_polygons (bool): label category name next to the polygons
:param label_font_size (int): change the font-size for labels
:param draw_mask (bool): Disable auto drawing of mask and allow the used to choose.
:return: None
"""

def getCategoryName(cats, cat_id):
"""
get Category name given a category id.
:cats (dictionary) : Dictionary containing all the categories.
:cat_id (integer) : Category ID of which the name is required.
:return: imgs (object array) : loaded img objects
"""
cat = [cat["name"] for cat in cats if cat["id"] == cat_id]
return cat[0]



if len(anns) == 0:
return 0
if 'segmentation' in anns[0] or 'keypoints' in anns[0]:
Expand All @@ -248,9 +271,15 @@ def showAnns(self, anns, draw_bbox=False):
ax = plt.gca()
ax.set_autoscale_on(False)
polygons = []
labels = []
color = []

for ann in anns:
c = (np.random.random((1, 3))*0.6+0.4).tolist()[0]
if class_based_colors:
c = color_code[ann["category_id"]]
else:
c = (np.random.random((1, 3))*0.6+0.4).tolist()[0]

if 'segmentation' in ann:
if type(ann['segmentation']) == list:
# polygon
Expand Down Expand Up @@ -292,12 +321,19 @@ def showAnns(self, anns, draw_bbox=False):
poly = [[bbox_x, bbox_y], [bbox_x, bbox_y+bbox_h], [bbox_x+bbox_w, bbox_y+bbox_h], [bbox_x+bbox_w, bbox_y]]
np_poly = np.array(poly).reshape((4,2))
polygons.append(Polygon(np_poly))
color.append(c)

p = PatchCollection(polygons, facecolor=color, linewidths=0, alpha=0.4)
ax.add_collection(p)
p = PatchCollection(polygons, facecolor='none', edgecolors=color, linewidths=2)
#color.append(c)
if label_polygons:
labels.append([ann["bbox"][0]-2, ann["bbox"][1]-5, getCategoryName(cats, ann["category_id"])])

if draw_mask:
p = PatchCollection(polygons, facecolor=color, linewidths=0, alpha=0.4)
ax.add_collection(p)
p = PatchCollection(polygons, facecolor='none', edgecolors=color, linewidths=bbox_line_width)
ax.add_collection(p)

for label in labels:
ax.annotate(label[2], (label[0], label[1]), size=label_font_size)

elif datasetType == 'captions':
for ann in anns:
print(ann['caption'])
Expand All @@ -314,7 +350,8 @@ def loadRes(self, resFile):
print('Loading and preparing results...')
tic = time.time()
if type(resFile) == str or (PYTHON_VERSION == 2 and type(resFile) == unicode):
anns = json.load(open(resFile))
with open(resFile) as f:
anns = json.load(f)
elif type(resFile) == np.ndarray:
anns = self.loadNumpyAnnotations(resFile)
else:
Expand Down Expand Up @@ -438,4 +475,4 @@ def annToMask(self, ann):
"""
rle = self.annToRLE(ann)
m = maskUtils.decode(rle)
return m
return m