Update classification overlay rendering.
Change-Id: Id3898eb83aee6e87fd9b99b291dc30f729df96ca
diff --git a/edgetpuvision/classify.py b/edgetpuvision/classify.py
index 88e6147..11f6d29 100644
--- a/edgetpuvision/classify.py
+++ b/edgetpuvision/classify.py
@@ -18,26 +18,57 @@
from .utils import load_labels, input_image_size, same_input_image_sizes, avg_fps_counter
-CSS_STYLES = str(svg.CssStyle({'.txt': svg.Style(fill='white'),
- '.shd': svg.Style(fill='black', fill_opacity=0.6)}))
+CSS_STYLES = str(svg.CssStyle({'.back': svg.Style(fill='black',
+ stroke='black',
+ stroke_width='1em')}))
-def overlay(results, inference_time, inference_rate, layout):
- x0, y0, w, h = layout.window
+def size_em(length):
+ return '%sem' % str(0.6 * length)
- lines = [
- 'Inference time: %.2f ms (%.2f fps)' % (inference_time * 1000, 1.0 / inference_time),
- 'Inference frame rate: %.2f fps' % inference_rate
- ]
-
- for i, (label, score) in enumerate(results):
- lines.append('%s (%.2f)' % (label, score))
+def overlay(title, results, inference_time, inference_rate, layout):
+ x0, y0, width, height = layout.window
defs = svg.Defs()
defs += CSS_STYLES
- doc = svg.Svg(width=w, height=h, viewBox='%s %s %s %s' % layout.window, font_size='26px')
+ doc = svg.Svg(width=width, height=height,
+ viewBox='%s %s %s %s' % layout.window,
+ font_size='1em', font_family='monospace', font_weight=500)
doc += defs
- doc += svg.normal_text(lines, x=x0 + 10, y=y0 + 10, font_size_em=1.1)
+
+ ox1, ox2 = x0 + 20, x0 + width - 20
+ oy1, oy2 = y0 + 20, y0 + height - 20
+
+ # Classes
+ lines = ['%s (%.2f)' % pair for pair in results]
+ if lines:
+ text_width = size_em(max(len(line) for line in lines))
+ text_height = '%sem' % len(lines)
+ doc += svg.Rect(x=0, y=0, width=text_width, height=text_height,
+ transform='translate(%s, %s) scale(-1,-1)' % (ox2, oy2),
+ _class='back')
+ t = svg.Text(y=oy2, fill='white', text_anchor='end')
+ for i, line in enumerate(lines):
+ dy = '-1em' if i > 0 else '0em'
+ t += svg.TSpan(line, x=ox2, dy=dy)
+ doc += t
+
+ # Title
+ if title:
+ doc += svg.Rect(x=ox1, y=oy1,
+ width=size_em(len(title)), height='1em',
+ _class='back')
+ t = svg.Text(x=ox1, y=oy1, fill='white')
+ t += svg.TSpan(title, dy='1em')
+ doc +=t
+
+ # Info
+ line = 'Inference time: %.2f ms (%.2f fps)' % (inference_time * 1000, 1.0 / inference_time)
+ doc += svg.Rect(x=0, y=0, width=size_em(len(line)), height='1em',
+ transform='translate(%s, %s) scale(1,-1)' % (ox1, oy2),
+ _class='back')
+ doc += svg.Text(line, x=ox1, y=oy2, fill='white')
+
return str(doc)
def top_results(window, top_k):
@@ -90,7 +121,7 @@
if args.print:
print_results(inference_rate, results)
- output = overlay(results, inference_time, inference_rate, layout)
+ output = overlay(None, results, inference_time, inference_rate, layout)
else:
output = None
diff --git a/edgetpuvision/svg.py b/edgetpuvision/svg.py
index 18733b8..84f712a 100644
--- a/edgetpuvision/svg.py
+++ b/edgetpuvision/svg.py
@@ -7,24 +7,6 @@
def rgb(color):
return 'rgb(%s, %s, %s)' % color
-def em(value):
- return '%sem' % value
-
-def px(value):
- return '%spx' % value
-
-def pt(value):
- return '%spt' % value
-
-def mm(value):
- return '%smm' % value
-
-def cm(value):
- return '%scm' % value
-
-def inch(value):
- return '%sin' % value
-
class Style:
def __init__(self, **attrs):
self._attrs = attrs
@@ -143,36 +125,3 @@
@property
def value(self):
return '<![CDATA[%s]]>' % '\n'.join('%s {%s}' % (k, v) for k, v in self._styles.items())
-
-
-
-def shadow_text(arg, x, y, font_size_em=1.0, text_class='txt', shadow_class='shd'):
- lines = arg.split('\n') if isinstance(arg, str) else arg
- g = Group()
- if len(lines) == 1:
- g += Text(lines[0], x=x, y=y, dx=1, dy=1, _class=shadow_class, font_size=em(font_size_em))
- g += Text(lines[0], x=x, y=y, _class=text_class, font_size=em(font_size_em))
- elif len(lines) > 1:
- t = Text(y=y, dy=1, _class=shadow_class, font_size=em(font_size_em))
- for line in lines:
- t += TSpan(line, x=x, dx=1, dy=em(1.0))
- g += t
-
- t = Text(y=y, _class=text_class, font_size=em(font_size_em))
- for line in lines:
- t += TSpan(line, x=x, dy=em(1.0))
- g += t
- return g
-
-def normal_text(arg, x, y, font_size_em=1.0, text_class='txt'):
- lines = arg.split('\n') if isinstance(arg, str) else arg
-
- if len(lines) == 1:
- return Text(lines[0], x=x, y=y, _class=text_class, font_size=em(font_size_em))
- elif len(lines) > 1:
- t = Text(y=y, _class='txt', font_size=em(font_size_em))
- for line in lines:
- t += TSpan(line, x=x, dy=em(1.0))
- return t
- else:
- raise ValueError('No text lines')