Skip to content

Commit dea9dee

Browse files
committed
Start of live demo application
1 parent 087fd25 commit dea9dee

File tree

1 file changed

+142
-0
lines changed

1 file changed

+142
-0
lines changed

microesc/livedemo.py

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
2+
3+
4+
import re
5+
import json
6+
import os
7+
import time
8+
9+
import numpy
10+
import serial
11+
12+
import matplotlib
13+
from matplotlib import pyplot as plt
14+
import gi
15+
gi.require_version('Gtk', '3.0')
16+
from gi.repository import Gtk, GLib
17+
from matplotlib.backends.backend_gtk3agg import FigureCanvasGTK3Agg as FigureCanvas
18+
19+
classes = {
20+
'car_horn': 1,
21+
'dog_bark': 3,
22+
'children_playing': 2,
23+
'engine_idling': 5,
24+
'street_music': 9,
25+
'drilling': 4,
26+
'air_conditioner': 0,
27+
'gun_shot': 6,
28+
'siren': 8,
29+
'jackhammer': 7,
30+
'unknown': 10,
31+
'quiet': 11,
32+
}
33+
classnames = [ ni[0] for ni in sorted(classes.items(), key=lambda kv: kv[1]) ]
34+
35+
def parse_input(line):
36+
37+
line = line.strip()
38+
prefix = 'preds:'
39+
if line.startswith(prefix):
40+
value_str = line.lstrip(prefix).rstrip(',')
41+
values = [ float(s) for s in value_str.split(',') ]
42+
return values
43+
else:
44+
return None
45+
46+
example_input = """
47+
Classifier: 44 ms
48+
preds:0.099867,0.043521,0.233744,0.162579,0.068373,0.049388,0.024437,0.042881,0.046287,0.228922,
49+
MelColumn: 62 ms
50+
LogMelSpec: 3 ms
51+
Classifier: 43 ms
52+
Sending: ASC=2
53+
preds:0.056955,0.022613,0.327033,0.140140,0.028910,0.026387,0.015121,0.012570,0.021695,0.348576,
54+
MelColumn: 31 ms
55+
LogMelSpec: 3 ms
56+
Classifier: 43 ms
57+
"""
58+
59+
def test_parse_preds():
60+
inp = example_input
61+
parsed = [ parse_input(l) for l in inp.split('\n') ]
62+
valid = [ v for v in parsed if v is not None ]
63+
64+
assert len(parsed) == 12, len(parsed) # lines
65+
assert len(valid) == 2 # predictions
66+
assert len(valid[1]) == 10 # classes
67+
assert len(valid[0]) == 10 # classes
68+
assert valid[0][0] == 0.099867, valid[0]
69+
assert valid[1][2] == 0.327033, valid[1]
70+
71+
72+
73+
74+
def create_interactive():
75+
win = Gtk.Window()
76+
win.connect("delete-event", Gtk.main_quit)
77+
win.set_default_size(400, 300)
78+
win.set_title("Embedding in GTK")
79+
80+
f = matplotlib.figure.Figure(figsize=(5, 4), dpi=100)
81+
ax = f.add_subplot(111)
82+
t = numpy.arange(0.0, 3.0, 0.01)
83+
s = numpy.sin(2*numpy.pi*t)
84+
85+
#ax.plot(t, s)
86+
87+
sw = Gtk.ScrolledWindow()
88+
win.add(sw)
89+
# A scrolled window border goes outside the scrollbars and viewport
90+
sw.set_border_width(10)
91+
92+
canvas = FigureCanvas(f) # a Gtk.DrawingArea
93+
canvas.set_size_request(800, 600)
94+
sw.add_with_viewport(canvas)
95+
96+
predictions = numpy.random.random(10)
97+
rects = ax.bar(numpy.arange(len(predictions)), predictions, align='center', alpha=0.5)
98+
99+
return win, f, ax, rects
100+
101+
def update_plot(ser, ax, fig, rects):
102+
raw = ser.readline()
103+
line = raw.decode('utf-8')
104+
predictions = parse_input(line)
105+
106+
if predictions:
107+
best_p = numpy.max(predictions)
108+
best_c = numpy.argmax(predictions)
109+
name = classnames[best_c]
110+
if best_p >= 0.35:
111+
print('p', name, best_p)
112+
113+
for rect, h in zip(rects, predictions):
114+
rect.set_height(h)
115+
116+
fig.canvas.draw()
117+
118+
return True
119+
120+
def main():
121+
test_parse_preds()
122+
123+
device = '/dev/ttyACM1'
124+
baudrate = 115200
125+
126+
window, fig, ax, rects = create_interactive()
127+
window.show_all()
128+
129+
with serial.Serial(device, baudrate, timeout=0.1) as ser:
130+
# avoid reading stale data
131+
thrash = ser.read(10000)
132+
133+
GLib.timeout_add(200.0, update_plot, ser, ax, fig, rects)
134+
135+
Gtk.main() # WARN: blocking
136+
137+
138+
if __name__ == '__main__':
139+
main()
140+
141+
142+

0 commit comments

Comments
 (0)