diff --git a/.gitignore b/.gitignore index b557859..d1b5010 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,3 @@ build affdex-sdk - +uploadkey.json diff --git a/echoserver.py b/echoserver.py index 879d323..f3f00a9 100644 --- a/echoserver.py +++ b/echoserver.py @@ -2,6 +2,10 @@ import tornado.websocket import tornado.web import tornado.ioloop import os +from PIL import Image +import numpy as np +from blend_modes import blend_modes +from io import BytesIO web_dir = os.path.join(os.path.split(__file__)[0], 'www') output_dir = os.path.join(os.path.split(__file__)[0], 'output') @@ -26,9 +30,33 @@ class WebSocketHandler(tornado.websocket.WebSocketHandler): self.connections.remove(self) print ("Client disconnected") +class CompositeHandler(tornado.web.RequestHandler): + def get(self, img1, img2): + # images can only be in the output dir + img1 = os.path.join(output_dir, os.path.basename(img1)) + img2 = os.path.join(output_dir, os.path.basename(img2)) + + i1 = np.asarray(Image.open(img1).convert('RGBA'), dtype=float) + i2 = np.asarray(Image.open(img2).convert('RGBA'), dtype=float) + + diffI = blend_modes.difference(i1,i2, opacity=1) + noAlpha = diffI[:,:,0:3] + maxValue = np.max(noAlpha) + # make sure a black image wont crash the system + factor = 255/maxValue if maxValue>0 else 0 + composite = Image.fromarray(np.uint8(noAlpha * factor)) + byteImgIO = BytesIO() + composite.save(byteImgIO, format="png") + byteImgIO.seek(0) + # print(len(byteImgIO.read())) + self.write(byteImgIO.read()) + self.set_header("Content-type", "image/png") + + application = tornado.web.Application([ (r"/ws", WebSocketHandler), (r"/output/(.*)", tornado.web.StaticFileHandler, {"path": output_dir}), + (r"/composite/(.*)/(.*)", CompositeHandler), (r"/(.*)", tornado.web.StaticFileHandler, {"path": web_dir, "default_filename": 'index.html'}), ],debug=True) diff --git a/portrait_compositor.py b/portrait_compositor.py index 5b1ddae..8995886 100644 --- a/portrait_compositor.py +++ b/portrait_compositor.py @@ -49,12 +49,16 @@ environment = { updateGoesOk = True; +with open(os.path.join(curdir, 'uploadkey.json')) as fp: + uploadkey = json.load(fp) + def updateStats(type, name, count, image_filename): params = { 'type': type, 'name': name, 'time': int(time.time()), 'case_count': int(count), + 'key': uploadkey, } # try: # ws = create_connection("ws://localhost:8888/ws") diff --git a/requirements.txt b/requirements.txt index 4d9cfc2..f6010d8 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,4 @@ websocket-client==0.54 requests==2.12 tornado==5.1 +blend_modes diff --git a/www/composite_loader.js b/www/composite_loader.js index 8dda78e..a368903 100644 --- a/www/composite_loader.js +++ b/www/composite_loader.js @@ -6,6 +6,8 @@ class Face { this.imgEls = []; this.valueEls = []; + this.img = ""; + let els = document.querySelectorAll(`[data-face='${this.id}']`); for(let el of els) { if(el.tagName == 'IMG') { @@ -25,11 +27,12 @@ class Face { } update(imgUrl, value) { + this.img = imgUrl for(let el of this.valueEls) { el.textContent = new Intl.NumberFormat("nl").format(value); } for(let el of this.imgEls) { - el.src = imgUrl; + el.src = '/output/'+imgUrl; } } } @@ -61,6 +64,18 @@ class Bar { } +class CompositeImage { + constructor(elId, face1, face2) { + this.el = document.getElementById(elId); + this.face1 = face1; + this.face2 = face2; + } + + update() { + this.el.src = `/composite/${this.face1.img}/${this.face2.img}`; + } +} + var bar = new Bar(document.getElementById('graph')); var faces = { @@ -74,13 +89,26 @@ var faces = { 'unknown_side': new Face('unknown_side') } +var composites = [ + new CompositeImage('composite-male_front', faces['male_front'], faces['front']), + new CompositeImage('composite-male_side', faces['male_side'], faces['side']), + new CompositeImage('composite-unknown_front', faces['unknown_front'], faces['front']), + new CompositeImage('composite-unknown_side', faces['unknown_side'], faces['side']), + new CompositeImage('composite-female_front', faces['female_front'], faces['front']), + new CompositeImage('composite-female_side', faces['female_side'], faces['side']), +]; + var update = function() { let req = new XMLHttpRequest(); req.addEventListener("load", function(e){ let data = JSON.parse(this.responseText); console.log(data); for(let name in data){ - faces[name].update('/output/'+data[name]['img'], data[name]['count']); + faces[name].update(data[name]['img'], data[name]['count']); + } + + for(let composite of composites) { + composite.update(); } bar.setValue('male', data['male_front']['count'] + data['male_side']['count']) diff --git a/www/index.html b/www/index.html index 44a5a4e..ac0258f 100644 --- a/www/index.html +++ b/www/index.html @@ -110,10 +110,7 @@
- -
-
- +
Male
@@ -121,19 +118,13 @@
- -
-
- +
Unknown
- -
-
- +
Female
diff --git a/www/styles.css b/www/styles.css index aeabca0..9fdc2ff 100644 --- a/www/styles.css +++ b/www/styles.css @@ -227,18 +227,7 @@ html{ margin-top: 40px; } - #differences .gender .diff-layer{ - position: absolute; - top:0; - right:0; - left:0; - mix-blend-mode: difference; - } - - #differences .gender .original-layer img{ - /* black yields no difference for blend-mode */ - border-color: black; - } + #differences .gender img{ width: 170px;