Werking van de Web-App

Op deze pagina wordt uitgelegd hoe deze webapp tot stand is gekomen en hoe de achterliggende werking is hoe de emotie herkent kan worden. Tevens is de code van de webapp te vinden op de GitHub van ZuydUniversity: Github ZuydUniversity

Flask

Vanuit de opdrachtgever zijn meerdere requirements vergaard. Twee van deze requirements waren: het realiseren van de functionaliteit binnen een webapp en het gebruik maken van Python als programmeertaal. Door o.a. deze requirements heeft de casusgroep een productonderzoek verricht voor mogelijke pakket-keuzes die gebruikt kunnen worden om een webapp te realiseren met Python. Uit dit onderzoek is de conclusie getrokken om gebruik te maken van Flask. Flask is een micro-webframework geschreven in Python. Het is geclassificeerd als een microframework omdat er geen specifieke tools of bibliotheken voor nodig zijn. Het heeft geen database-abstractielaag, formuliervalidatie of andere componenten waar reeds bestaande bibliotheken van derden gemeenschappelijke functies bieden. Flask ondersteunt echter extensies die applicatiefuncties kunnen toevoegen alsof ze in Flask zelf zijn geïmplementeerd. Een van de belangrijke functies die bestaan binnen Flask is het gebruik van templates. Hierdoor kan gebruik gemaakt worden van .html pages in combinatie met .css en .js files. Om de Flask webapp te runnen bestaat de app.py file. Dit is de main-file wat de web-app service draait.


          from logging import debug
          from flask import Flask
          from api import api
          from views import views
          
          app = Flask(__name__, static_url_path="/static")
          app.register_blueprint(views, url_prefix="/views")
          app.register_blueprint(api, url_prefix="/api")
          
          if __name__ == '__main__':
              app.run(debug=True, port=5000)
        

CamFeed

De doelstelling van deze casus is het lezen en herkennen van de emotie van de enduser. Om de emotie te kunnen lezen is het van belang dat er op de webapp een live camfeed aamwezig is waarvan de emotie herkend kan worden. Een belangrijk aspect hierbij is, is dat de web-app zal draaien op een VPS. Hier betekend dat de live camfeed niet gerealiseerd kan worden via de back-end maar hij moet gerealiseerd worden via de frontend zodat de live camfeed vanaf de sessie van de enduser gerealiseerd wordt. Dit is gerealiseerd door gebruik te maken van een JavaScript script wat op de html page toestemming vraagt om gebruik te maken van de webcam van de enduser en deze dan, wanneer er toestemming is gegeven, toonbaar maakt op de webapp.

 // Configure camera settings and attach camera to element ID on webpage
            Webcam.set({
              width: 640,
              height: 480,
              dest_width: 640,
              dest_height: 480,
              image_format: 'jpeg',
              jpeg_quality: 90
            });

            Webcam.on('error', function (err) {
              console.log(err)
              alert("De gebruiker heeft geen toestemming gegeven tot gebruik van de webcam. Geef alsjeblieft toestemming tot het gebruik van de webcam")
              // an error occurred (see 'err')
            });
            Webcam.attach('#my_camera');
          
        

API / Endpoint

Binnen de webapp is het van belang dat er vanaf de live camfeed de emotie gelezen en herkend kan worden. De emotie die wordt herkend d.m.v. de CNN die gerealiseerd is. Hier zal later verdere informatie over te lezen zijn. Deze CNN staat lokaal op de VPS en draait niet binnen de webapp. Hierdoor moet er een snippet van de camfeed verstuurd worden naar de CNN om hiervan de emotie te herkennen en deze terug te sturen. Om dit te realiseren heeft de casusgroep een Flask Api gerealiseerd binnen Flask om HTTP requests te sturen naar de CNN en binnen de response de emotie terug te krijgen. Deze API is als volgende opgebouwd:


          import flask
          from flask import request, jsonify, Blueprint, render_template, Response
          from static.cnn.facial_emotion_image import recognise, readb64

          api = Blueprint(__name__, "api")

          @api.route('/v1/recognise', methods=['POST'])
          def cnn():
  	 	    if not request.json:
        		return "error", 400
   		  print(request.json['img'])
          return recognise(request.json['img']), 200
        

Binnen deze request wordt de afbeelding toegevoegd, deze afbeelding wordt als een base64 encoded. Via deze encoding is het mogelijke de snippet te versturen over het netwerk naar de CNN. Dit wordt als volgende uitgevoerd:


        def readb64(uri):
   	    encoded_data = uri.split(',')[1]
   	    nparr = np.fromstring(base64.b64decode(encoded_data), np.uint8)
   	    img = cv2.imdecode(nparr, cv2.IMREAD_COLOR)
   	    return img
      
    

Hierna doet de gerealiseerde CNN zijn acties en wordt de emotie herkend van de snippet en deze wordt teruggestuurd in een JSON-format naar de webapp. Deze heeft nog 2 scenario’s. De mogelijkheid zal bestaan dat er geen gezicht herkend wordt. Hierdoor zal er een none emotie response terug gestuurd worden. Indien de CNN wel een gezicht herkend heeft zal een een reponse teruggestuurd worden waarbij de herkende emotie vermeld staat.

  1. HTTP 200 : {"Emotion": ["de herkende emote"]}
  2. HTTP 200: {"Emotion": ["none"]}