forked from serengil/deepface
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Pei-Yun Sun
committed
Oct 19, 2020
1 parent
f789a9c
commit 11a92a9
Showing
40 changed files
with
17,852 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
export HAP_DB_NAME=hap | ||
export HAP_DB_HOST=localhost | ||
export HAP_DB_PORT=27017 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
from config import create_app, db | ||
from views import public_route_bp | ||
from controller import api_bp_new, api_bp_old | ||
|
||
|
||
app = create_app() | ||
""" | ||
register blueprint | ||
""" | ||
app.register_blueprint(public_route_bp) | ||
app.register_blueprint(api_bp_old) | ||
app.register_blueprint(api_bp_new, url_prefix='/api') | ||
|
||
app.app_context().push() | ||
|
||
|
||
def main(): | ||
app.run(debug=True, host="0.0.0.0", port=5000) # RUNNING APP MAKE debug =FALSE for Production Env | ||
# app.run(debug=True, host="localhost", port=8888) | ||
|
||
|
||
if __name__ == "__main__": | ||
main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
from flask import Flask | ||
from flask_mongoengine import MongoEngine | ||
from deepface import DeepFaceLite | ||
# import tensorflow as tf | ||
# from tensorflow.python.keras.backend import set_session | ||
import os | ||
|
||
""" | ||
initialize the ML engine | ||
""" | ||
db = MongoEngine() | ||
# sess = tf.Session() | ||
# graph = tf.get_default_graph() | ||
# set_session(sess) | ||
deepface = DeepFaceLite() | ||
|
||
""" | ||
database environment variable | ||
""" | ||
DB_NAME = os.environ.get('HAP_DB_NAME') | ||
DB_HOST = os.environ.get('HAP_DB_HOST') | ||
DB_PORT = os.environ.get('HAP_DB_PORT') | ||
DB_USERNAME = os.environ.get('HAP_DB_USERNAME') | ||
DB_PASSWORD = os.environ.get('HAP_DB_PASSWORD') | ||
|
||
|
||
def create_app(): | ||
""" | ||
return app instance | ||
:return: app instance | ||
""" | ||
app = Flask(__name__) | ||
if DB_USERNAME is not None and DB_PASSWORD is not None: | ||
app.config['MONGODB_SETTINGS'] = { | ||
'db': DB_NAME, | ||
'host': DB_HOST, | ||
'port': int(DB_PORT), | ||
'username': DB_USERNAME, | ||
'password': DB_PASSWORD | ||
} | ||
else: | ||
app.config['MONGODB_SETTINGS'] = { | ||
'db': DB_NAME, | ||
'host': DB_HOST, | ||
'port': int(DB_PORT) | ||
} | ||
|
||
db.init_app(app) | ||
|
||
return app |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
from flask_restplus import Api | ||
from flask import Blueprint | ||
from controller.prediction_controller import api as predict_apis | ||
from controller.feedback_controller import api as feedback_apis | ||
from controller.general_controller import api as general_apis | ||
|
||
|
||
# old api, will be discard later | ||
api_bp_old = Blueprint('api_old', __name__) | ||
|
||
api = Api(api_bp_old) | ||
|
||
api.add_namespace(predict_apis) | ||
api.add_namespace(general_apis) | ||
|
||
""" | ||
new api with /api/ path | ||
""" | ||
api_bp_new = Blueprint('api_new', __name__) | ||
|
||
api_new = Api(api_bp_new) | ||
api_new.add_namespace(general_apis) | ||
api_new.add_namespace(predict_apis) | ||
api_new.add_namespace(feedback_apis) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
from flask import request | ||
from extension.utilServices import send_json_response | ||
from flask_restplus import Namespace, Resource | ||
import datetime | ||
api = Namespace('feedback', path='/feedback', description='prediction related operations') | ||
|
||
|
||
@api.route('') | ||
class Feedback(Resource): | ||
@api.doc('feedback related api') | ||
def post(self): | ||
""" | ||
store user feedbacks to the database | ||
:return: operation results | ||
""" | ||
from models.feedback import Feedback, FeedbackContent | ||
|
||
message = request.get_json(force=True) | ||
|
||
try: | ||
new_feedback = Feedback() | ||
new_feedback_content = [] | ||
for each_content in message['data']: | ||
feedback_content = FeedbackContent(**each_content) | ||
new_feedback_content.append(feedback_content) | ||
|
||
new_feedback.content = new_feedback_content | ||
new_feedback.date = datetime.datetime.now() | ||
new_feedback.save() | ||
return send_json_response({}, 200) | ||
except Exception as error: | ||
return send_json_response({'msg': str(error)}, 500) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,190 @@ | ||
from extension.utilServices import (send_json_response) | ||
from extension.constants import CONSTANTS | ||
import csv | ||
import re | ||
from flask_restplus import Namespace, Resource | ||
import datetime | ||
import copy | ||
|
||
api = Namespace('general', path='/', description='general information related to app') | ||
|
||
|
||
# @api.route('/get-breed-info') | ||
# class BreedList(Resource): | ||
# @api.doc('get breed information from csv') | ||
# def get(self): | ||
# """ | ||
# return the breed information, which gets from wikipedia | ||
# :return: list of breed information | ||
# """ | ||
# breed_info = {} | ||
# for animal_type in CONSTANTS['ANIMAL_TYPE']: | ||
# with open('wikiFile/' + animal_type + '.csv') as csv_file: | ||
# csv_reader = csv.reader(csv_file, delimiter=',') | ||
# line_count = 0 | ||
# json_title = [] | ||
# animal_list = [] | ||
# for row in csv_reader: | ||
# if line_count == 0: | ||
# json_title = row | ||
# line_count += 1 | ||
# else: | ||
# info_obj = { | ||
# json_title[0]: row[0], | ||
# json_title[1]: row[1], | ||
# json_title[2]: row[2], | ||
# json_title[3]: row[3], | ||
# json_title[4]: row[4], | ||
# } | ||
# animal_list.append(info_obj) | ||
# line_count += 1 | ||
# csv_file.close() | ||
# breed_info[animal_type] = animal_list | ||
|
||
# return send_json_response(breed_info, 200) | ||
|
||
|
||
@api.route('/get-app-info') | ||
class AppInfo(Resource): | ||
@api.doc('return the app developer information') | ||
def get(self): | ||
""" | ||
return the footer information | ||
:return: return the app related information | ||
""" | ||
app_info = { | ||
'developedBy': 'This app was developed by the Melbourne eResearch Group (www.eresearch.unimelb.edu.au) within the School of Computing and Information Systems (https://cis.unimelb.edu.au) at The University of Melbourne (www.unimelb.edu.au). ', | ||
'description': 'The app uses artificial intelligence (convolutional neural networks) that have been trained on dog/cat images to identify whether a dog/cat is in an image, and if so the species type (breed) and it\'s emotion.', | ||
'contact': 'https://eresearch.unimelb.edu.au', | ||
'developedByHTML': '<p>This app was developed by the Melbourne eResearch Group (<a href=\"www.eresearch.unimelb.edu.au\" target=\"_blank\">www.eresearch.unimelb.edu.au</a>) within the School of Computing and Information Systems (<a href=\"https://cis.unimelb.edu.au\" target=\"_blank\">https://cis.unimelb.edu.au</a>) at The University of Melbourne (<a href=\"www.unimelb.edu.au\" target=\"_blank\">www.unimelb.edu.au</a>).</p>', | ||
'descriptionHTML': '<p>The app uses artificial intelligence (convolutional neural networks) that have been trained on dog/cat images to identify whether a dog/cat is in an image, and if so the species type (breed) and it\'s emotion.</p>', | ||
'contactHTML': '<p>Please contact us at: <a href=\"eresearch.unimelb.edu.au\" target=\"_blank\">eresearch.unimelb.edu.au</a></p>' | ||
} | ||
|
||
return send_json_response(app_info, 200) | ||
|
||
|
||
@api.route('/get-statistical-results') | ||
class StatisticalData(Resource): | ||
@api.doc('return statistical data') | ||
def get(self): | ||
""" | ||
return the statistical information | ||
query across feedback and prediction model | ||
:return: return statistical information | ||
""" | ||
from models.prediction import Prediction | ||
from models.feedback import Feedback | ||
|
||
total_cat_breed = [] | ||
total_dog_breed = [] | ||
prediction_collection = Prediction._get_collection() | ||
feedback_collection = Feedback._get_collection() | ||
statistical_data = copy.deepcopy(CONSTANTS['STATISTICAL_DATA']) | ||
|
||
# initial statistical_data based on breed and alpha order | ||
f = open("model_data/pet_classes.txt", "r") | ||
for each_line in f: | ||
first_char = each_line[0] | ||
if first_char.isupper(): | ||
total_cat_breed.append(re.sub(r"_", " ", each_line.rstrip(), flags=re.IGNORECASE).title()) | ||
else: | ||
total_dog_breed.append(re.sub(r"_", " ", each_line.rstrip(), flags=re.IGNORECASE).title()) | ||
f.close() | ||
total_cat_breed.sort() | ||
total_dog_breed.sort() | ||
|
||
for each_breed in total_cat_breed: | ||
statistical_data['Cat']['prediction_data']['breed'][each_breed] = 0 | ||
statistical_data['Cat']['feedback_data']['breed']['wrong'][each_breed] = 0 | ||
statistical_data['Cat']['feedback_data']['breed']['correct'][each_breed] = 0 | ||
|
||
for each_breed in total_dog_breed: | ||
statistical_data['Dog']['prediction_data']['breed'][each_breed] = 0 | ||
statistical_data['Dog']['feedback_data']['breed']['wrong'][each_breed] = 0 | ||
statistical_data['Dog']['feedback_data']['breed']['correct'][each_breed] = 0 | ||
|
||
# photo by date | ||
today = datetime.datetime.today().replace(hour=0, minute=0, second=0, microsecond=0) | ||
total_number_of_photo_within_one_week = { | ||
(today - datetime.timedelta(days=6)).strftime('%d/%m/%Y'): prediction_collection.count_documents( | ||
{'date': {'$lt': today - datetime.timedelta(days=5), '$gte': today - datetime.timedelta(days=6)}}), | ||
(today - datetime.timedelta(days=5)).strftime('%d/%m/%Y'): prediction_collection.count_documents( | ||
{'date': {'$lt': today - datetime.timedelta(days=4), '$gte': today - datetime.timedelta(days=5)}}), | ||
(today - datetime.timedelta(days=4)).strftime('%d/%m/%Y'): prediction_collection.count_documents( | ||
{'date': {'$lt': today - datetime.timedelta(days=3), '$gte': today - datetime.timedelta(days=4)}}), | ||
(today - datetime.timedelta(days=3)).strftime('%d/%m/%Y'): prediction_collection.count_documents( | ||
{'date': {'$lt': today - datetime.timedelta(days=2), '$gte': today - datetime.timedelta(days=3)}}), | ||
(today - datetime.timedelta(days=2)).strftime('%d/%m/%Y'): prediction_collection.count_documents( | ||
{'date': {'$lt': today - datetime.timedelta(days=1), '$gte': today - datetime.timedelta(days=2)}}), | ||
(today - datetime.timedelta(days=1)).strftime('%d/%m/%Y'): prediction_collection.count_documents( | ||
{'date': {'$lt': today, '$gte': today - datetime.timedelta(days=1)}}), | ||
today.strftime('%d/%m/%Y'): prediction_collection.count_documents( | ||
{'date': {'$gte': today}}), | ||
} | ||
|
||
# prediction | ||
total_prediction = prediction_collection.find({}) | ||
for each_prediction in total_prediction: | ||
prediction_results = each_prediction['predictionResults'] | ||
for each_result in prediction_results: | ||
statistical_data[each_result['type']]['prediction_number'] = statistical_data[each_result['type']].get( | ||
'prediction_number', 0) + 1 | ||
statistical_data[each_result['type']]['prediction_data']['breed'][each_result['breed']] = \ | ||
statistical_data[each_result['type']]['prediction_data']['breed'].get(each_result['breed'], 0) + 1 | ||
statistical_data[each_result['type']]['prediction_data']['emotion'][each_result['emotion']] = \ | ||
statistical_data[each_result['type']]['prediction_data']['emotion'].get(each_result['emotion'], | ||
0) + 1 | ||
# feedback | ||
total_feedback = feedback_collection.find({}) | ||
|
||
for each_feedback in total_feedback: | ||
feedback_content = each_feedback['content'] | ||
for each_content in feedback_content: | ||
statistical_data[each_content['type']]['feedback_number'] = statistical_data[each_content['type']].get( | ||
'feedback_number', 0) + 1 | ||
|
||
if not each_content['breedCorrectness']: | ||
statistical_data[each_content['type']]['feedback_data']['breed']['wrong'][ | ||
each_content['breedFeedback']] = \ | ||
statistical_data[each_content['type']]['feedback_data']['breed'][ | ||
'wrong'].get(each_content['breedFeedback'], 0) + 1 | ||
else: | ||
statistical_data[each_content['type']]['feedback_data']['breed']['correct'][ | ||
each_content['breedFeedback']] = \ | ||
statistical_data[each_content['type']]['feedback_data']['breed']['correct'].get( | ||
each_content['breedFeedback'], 0) + 1 | ||
|
||
if not each_content['emotionCorrectness']: | ||
statistical_data[each_content['type']]['feedback_data']['emotion']['wrong'][ | ||
each_content['emotionFeedback']] = \ | ||
statistical_data[each_content['type']]['feedback_data']['emotion']['wrong'].get( | ||
each_content['emotionFeedback'], 0) + 1 | ||
else: | ||
statistical_data[each_content['type']]['feedback_data']['emotion']['correct'][ | ||
each_content['emotionFeedback']] = \ | ||
statistical_data[each_content['type']]['feedback_data']['emotion']['correct'].get( | ||
each_content['emotionFeedback'], 0) + 1 | ||
|
||
result = { | ||
'totalNumberOfPhotoUploaded': prediction_collection.count_documents({}), | ||
'totalNumberOfCatPrediction': statistical_data['Cat']['prediction_number'], | ||
'totalNumberOfDogPrediction': statistical_data['Dog']['prediction_number'], | ||
'totalNumberOfCatFeedback': statistical_data['Cat']['feedback_number'], | ||
'totalNumberOfDogFeedback': statistical_data['Dog']['feedback_number'], | ||
'totalNumberOfDogBreedPrediction': statistical_data['Dog']['prediction_data']['breed'], | ||
'totalNumberOfDogBreedCorrectFeedback': statistical_data['Dog']['feedback_data']['breed']['correct'], | ||
'totalNumberOfDogBreedWrongFeedback': statistical_data['Dog']['feedback_data']['breed']['wrong'], | ||
'totalNumberOfDogEmotionPrediction': statistical_data['Dog']['prediction_data']['emotion'], | ||
'totalNumberOfDogEmotionCorrectFeedback': statistical_data['Dog']['feedback_data']['emotion']['correct'], | ||
'totalNumberOfDogEmotionWrongFeedback': statistical_data['Dog']['feedback_data']['emotion']['wrong'], | ||
'totalNumberOfCatBreedPrediction': statistical_data['Cat']['prediction_data']['breed'], | ||
'totalNumberOfCatBreedCorrectFeedback': statistical_data['Cat']['feedback_data']['breed']['correct'], | ||
'totalNumberOfCatBreedWrongFeedback': statistical_data['Cat']['feedback_data']['breed']['wrong'], | ||
'totalNumberOfCatEmotionPrediction': statistical_data['Cat']['prediction_data']['emotion'], | ||
'totalNumberOfCatEmotionCorrectFeedback': statistical_data['Cat']['feedback_data']['emotion']['correct'], | ||
'totalNumberOfCatEmotionWrongFeedback': statistical_data['Cat']['feedback_data']['emotion']['wrong'], | ||
'numberOfPhotoByDate': total_number_of_photo_within_one_week | ||
} | ||
|
||
return send_json_response(result, 200) |
Oops, something went wrong.