Refactor
This commit is contained in:
153
main.py
153
main.py
@@ -4,7 +4,6 @@ import json
|
||||
import logging
|
||||
import math
|
||||
import os
|
||||
import string
|
||||
import subprocess
|
||||
import threading
|
||||
import time
|
||||
@@ -12,13 +11,12 @@ from collections import OrderedDict
|
||||
|
||||
import bottle
|
||||
import numpy as np
|
||||
import scipy.misc
|
||||
import serial
|
||||
|
||||
import config
|
||||
import filters
|
||||
|
||||
logging.basicConfig(filename='pixelserver.log', level=config.LogLevel)
|
||||
running = True
|
||||
|
||||
|
||||
########################################################################
|
||||
@@ -151,7 +149,7 @@ if config.UseGui:
|
||||
def join(self, **kwargs):
|
||||
with self.cv:
|
||||
self.cv.notify_all()
|
||||
super().join()
|
||||
super().join(**kwargs)
|
||||
|
||||
|
||||
########################################################################
|
||||
@@ -162,6 +160,7 @@ class SerialWriter(threading.Thread):
|
||||
super().__init__(daemon=True)
|
||||
self.cv = threading.Condition()
|
||||
self.datasource = datasource.addListener(self.cv)
|
||||
self.gamma_rgbw = 0, 0, 0, 0
|
||||
self.updateGamma = False
|
||||
|
||||
def run(self):
|
||||
@@ -179,13 +178,15 @@ class SerialWriter(threading.Thread):
|
||||
frame = self.datasource.getData()
|
||||
data = frame.buffer.reshape((config.ScreenX * config.ScreenY * frame.channels,)).astype(np.uint8).tobytes()
|
||||
if self.updateGamma:
|
||||
buf = bytearray(b"\x00") * 4 * 256
|
||||
r, g, b, w = self.gamma_rgbw
|
||||
apply = lambda x, g: max(0, min(255, int(math.pow(x / 255, g) * 255)))
|
||||
|
||||
buf = bytearray(4 * 256)
|
||||
for i in range(256):
|
||||
apply = lambda x, g: max(0, min(255, int(math.pow(x / 255, g) * 255)))
|
||||
buf[i] = apply(i, self.r)
|
||||
buf[i + 256] = apply(i, self.g)
|
||||
buf[i + 512] = apply(i, self.b)
|
||||
buf[i + 512 + 256] = apply(i, self.w)
|
||||
buf[i] = apply(i, r)
|
||||
buf[i + 256] = apply(i, g)
|
||||
buf[i + 256 * 2] = apply(i, b)
|
||||
buf[i + 256 * 3] = apply(i, w)
|
||||
ser.write(b"\x02")
|
||||
ser.write(buf)
|
||||
self.updateGamma = False
|
||||
@@ -195,7 +196,7 @@ class SerialWriter(threading.Thread):
|
||||
elif frame.channels == 4:
|
||||
ser.write(b"\03")
|
||||
ser.write(data)
|
||||
logging.debug("Time to gui: " + str(time.time() - frame.created))
|
||||
logging.debug(f"Time to gui: {time.time() - frame.created}")
|
||||
ser.flush()
|
||||
except Exception as e:
|
||||
if ser is not None:
|
||||
@@ -209,11 +210,11 @@ class SerialWriter(threading.Thread):
|
||||
def join(self, **kwargs):
|
||||
with self.cv:
|
||||
self.cv.notify_all()
|
||||
super().join()
|
||||
super().join(**kwargs)
|
||||
|
||||
def setGamma(self, r, g, b, w):
|
||||
with self.cv:
|
||||
self.r, self.g, self.b, self.w = r, g, b, w
|
||||
self.gamma_rgbw = r, g, b, w
|
||||
self.updateGamma = True
|
||||
self.cv.notify_all()
|
||||
|
||||
@@ -317,7 +318,7 @@ class AppRunner(threading.Thread):
|
||||
self.requestedApp = app
|
||||
self.param = param
|
||||
self.cv.notify_all()
|
||||
logging.info("Requesting app: " + str(app))
|
||||
logging.info(f"Requesting app: {app}")
|
||||
|
||||
def startApp(self, i, param=""):
|
||||
app = config.Apps[i]
|
||||
@@ -373,90 +374,14 @@ class AppRunner(threading.Thread):
|
||||
def setGamma(self, r, g, b, w):
|
||||
self.serial.setGamma(r, g, b, w)
|
||||
|
||||
def setFilter(self, name, filter):
|
||||
self.filters[name] = filter
|
||||
def setFilter(self, name, filter_):
|
||||
self.filters[name] = filter_
|
||||
|
||||
def removeFilter(self, name):
|
||||
if name in self.filters.keys():
|
||||
del self.filters[name]
|
||||
|
||||
|
||||
########################################################################
|
||||
# Filter Api #
|
||||
########################################################################
|
||||
def MakeBrightnessFilter(intensity):
|
||||
def filter(img):
|
||||
return (img * intensity).astype(np.uint8)
|
||||
|
||||
return filter
|
||||
|
||||
|
||||
def FlipXFilter(intensity):
|
||||
return intensity[:, ::-1, :]
|
||||
|
||||
|
||||
def FlipYFilter(intensity):
|
||||
return intensity[::-1, :, :]
|
||||
|
||||
|
||||
def MakeBrightnessImageFilter(name):
|
||||
img = scipy.misc.imread("filter/" + name + ".png", flatten=True) / 255
|
||||
|
||||
# img = np.transpose(img)
|
||||
def filter(intensity):
|
||||
intensity = intensity.astype(float)
|
||||
for i in range(intensity.shape[2]):
|
||||
intensity[:, :, i] *= img
|
||||
return intensity.astype(np.uint8)
|
||||
|
||||
return filter
|
||||
|
||||
|
||||
def strings(s):
|
||||
allowed_chars = string.ascii_letters + string.digits + "+-*/()."
|
||||
i = 0
|
||||
outlist = []
|
||||
while i != len(s):
|
||||
if s[i] not in allowed_chars:
|
||||
raise Exception("Unexpected char " + s[i])
|
||||
if s[i] not in string.ascii_letters:
|
||||
i += 1
|
||||
continue
|
||||
out = ""
|
||||
while i != len(s) and s[i] in string.ascii_letters + string.digits:
|
||||
out += s[i]
|
||||
i += 1
|
||||
outlist.append(out)
|
||||
return outlist
|
||||
|
||||
|
||||
def eval_safer(expr, x, y, t):
|
||||
symbols = {"x": x, "y": y, "t": t,
|
||||
"sin": np.sin, "cos": np.cos, "exp": np.exp, "tan": np.tan}
|
||||
strs = strings(expr)
|
||||
for s in strs:
|
||||
if s not in symbols.keys():
|
||||
raise Exception("unexpected symbol: " + s)
|
||||
return eval(expr, {}, symbols)
|
||||
|
||||
|
||||
def MakeBrightnessExprFilter(expr):
|
||||
t0 = time.time()
|
||||
x, y = np.meshgrid(np.arange(config.ScreenX), np.arange(config.ScreenY))
|
||||
eval_safer(expr, 0, 0, 0)
|
||||
|
||||
def filter(intensity):
|
||||
t = time.time() - t0
|
||||
intensity = intensity.astype(float)
|
||||
filter = 0 * x + eval_safer(expr, x, y, t)
|
||||
filter = np.clip(np.nan_to_num(filter), 0, 1)
|
||||
for i in range(intensity.shape[2]):
|
||||
intensity[:, :, i] *= filter
|
||||
return intensity.astype(np.uint8)
|
||||
|
||||
return filter
|
||||
|
||||
|
||||
########################################################################
|
||||
# Web Api #
|
||||
########################################################################
|
||||
@@ -530,17 +455,15 @@ def apps_running():
|
||||
def index():
|
||||
return bottle.static_file("index.html", root='html')
|
||||
|
||||
|
||||
@bottle.route("/<filepath:path>")
|
||||
def serve_static(filepath):
|
||||
return bottle.static_file(filepath, root='html')
|
||||
|
||||
|
||||
@bottle.route("/setgamma/<r>/<g>/<b>/<w>")
|
||||
def setGamma(r, g, b, w):
|
||||
r = float(r)
|
||||
g = float(g)
|
||||
b = float(b)
|
||||
w = float(w)
|
||||
runner.setGamma(r, g, b, w)
|
||||
runner.setGamma(float(r), float(g), float(b), float(w))
|
||||
return "ok"
|
||||
|
||||
|
||||
@@ -549,14 +472,14 @@ def setIntensity(i):
|
||||
i = float(i)
|
||||
if not 0 <= i <= 1:
|
||||
return "bad_value"
|
||||
runner.setFilter("0_intensity", MakeBrightnessFilter(i))
|
||||
runner.setFilter("0_intensity", filters.MakeBrightnessFilter(i))
|
||||
return "ok"
|
||||
|
||||
|
||||
@bottle.route("/filter/flipx/<do>")
|
||||
def flipx(do):
|
||||
if do == "true":
|
||||
runner.setFilter("1_flipx", FlipXFilter)
|
||||
runner.setFilter("1_flipx", filters.FlipXFilter)
|
||||
else:
|
||||
runner.removeFilter("1_flipx")
|
||||
return "ok"
|
||||
@@ -565,7 +488,7 @@ def flipx(do):
|
||||
@bottle.route("/filter/flipy/<do>")
|
||||
def flipy(do):
|
||||
if do == "true":
|
||||
runner.setFilter("1_flipy", FlipYFilter)
|
||||
runner.setFilter("1_flipy", filters.FlipYFilter)
|
||||
else:
|
||||
runner.removeFilter("1_flipy")
|
||||
return "ok"
|
||||
@@ -576,7 +499,7 @@ def setfilter(name):
|
||||
if name == "none":
|
||||
runner.removeFilter("3_imgfilter")
|
||||
else:
|
||||
runner.setFilter("3_imgfilter", MakeBrightnessImageFilter(name))
|
||||
runner.setFilter("3_imgfilter", filters.MakeBrightnessImageFilter(name))
|
||||
return "ok"
|
||||
|
||||
|
||||
@@ -586,21 +509,23 @@ def filter_expr():
|
||||
if expr == "" or expr == "none":
|
||||
runner.removeFilter("5_brightnessfunction")
|
||||
else:
|
||||
runner.setFilter("5_brightnessfunction", MakeBrightnessExprFilter(expr))
|
||||
runner.setFilter("5_brightnessfunction", filters.MakeBrightnessExprFilter(expr))
|
||||
return "ok"
|
||||
|
||||
|
||||
########################################################################
|
||||
# Startup #
|
||||
########################################################################
|
||||
runner = AppRunner()
|
||||
runner.start()
|
||||
if __name__ == '__main__':
|
||||
########################################################################
|
||||
# Startup #
|
||||
########################################################################
|
||||
running = True
|
||||
runner = AppRunner()
|
||||
runner.start()
|
||||
|
||||
# runner.setFilter("5_crazy", MakeBrightnessExprFilter("0.5+0.25*sin(x/3)/x"))
|
||||
bottle.run(host=config.WebHost, port=config.WebPort)
|
||||
# runner.setFilter("5_crazy", MakeBrightnessExprFilter("0.5+0.25*sin(x/3)/x"))
|
||||
bottle.run(host=config.WebHost, port=config.WebPort)
|
||||
|
||||
########################################################################
|
||||
# Shutdown #
|
||||
########################################################################
|
||||
running = False
|
||||
runner.join()
|
||||
########################################################################
|
||||
# Shutdown #
|
||||
########################################################################
|
||||
running = False
|
||||
runner.join()
|
||||
|
Reference in New Issue
Block a user