parent
7313fbd58d
commit
14985a70f1
|
|
@ -12,7 +12,9 @@ app = Flask(__name__)
|
||||||
api = Api(app, version='1', contact={"name":""}, license={"name":"Online Dienst Dokumentation"}, api_spec_url='/api/swagger')
|
api = Api(app, version='1', contact={"name":""}, license={"name":"Online Dienst Dokumentation"}, api_spec_url='/api/swagger')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
api.add_resource(endpoints.PersonList,'/api/v1/person/<string:id>', '/api/v1/person/')
|
api.add_resource(endpoints.PersonList,'/api/v1/person/<string:id>', '/api/v1/person/')
|
||||||
|
api.add_resource(endpoints.Camera,'/api/v1/camera/<string:type>', "/api/v1/camera/")
|
||||||
|
|
||||||
@app.route("/")
|
@app.route("/")
|
||||||
def index():
|
def index():
|
||||||
|
|
|
||||||
|
|
@ -12,10 +12,14 @@ connection = engine.connect()
|
||||||
Base = declarative_base()
|
Base = declarative_base()
|
||||||
Session = sessionmaker(bind=engine)
|
Session = sessionmaker(bind=engine)
|
||||||
|
|
||||||
|
lastImage = ""
|
||||||
|
|
||||||
class Gender(enum.Enum):
|
class Gender(enum.Enum):
|
||||||
other = "other"
|
other = "Other"
|
||||||
male = "male"
|
male = "Male"
|
||||||
female = "female"
|
female = "Female"
|
||||||
|
def __str__(self):
|
||||||
|
return str(self.value)
|
||||||
|
|
||||||
class Person(Base):
|
class Person(Base):
|
||||||
__tablename__ = "person"
|
__tablename__ = "person"
|
||||||
|
|
@ -44,7 +48,7 @@ class Person(Base):
|
||||||
"fname": self.fname,
|
"fname": self.fname,
|
||||||
"lname": self.lname,
|
"lname": self.lname,
|
||||||
"yob": self.yob,
|
"yob": self.yob,
|
||||||
"gender": self.gender,
|
"gender": str(self.gender),
|
||||||
"face": face,
|
"face": face,
|
||||||
"fingerprints": prints
|
"fingerprints": prints
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,8 +3,10 @@ import flask
|
||||||
import requests
|
import requests
|
||||||
import application.config as config
|
import application.config as config
|
||||||
import json
|
import json
|
||||||
|
import cv2
|
||||||
from application.db import Session, Person, Fingerprint
|
from application.db import Session, Person, Fingerprint
|
||||||
|
|
||||||
|
lastImage = ""
|
||||||
|
|
||||||
class PersonList(Resource):
|
class PersonList(Resource):
|
||||||
def post(self, id = None):
|
def post(self, id = None):
|
||||||
|
|
@ -41,7 +43,18 @@ class PersonList(Resource):
|
||||||
def get(self, id = None):
|
def get(self, id = None):
|
||||||
""" """
|
""" """
|
||||||
try:
|
try:
|
||||||
|
parser = reqparse.RequestParser()
|
||||||
|
parser.add_argument('useFace', type=bool, required=False)
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
session = Session()
|
session = Session()
|
||||||
|
|
||||||
|
if "useFace" in args and args["useFace"]:
|
||||||
|
|
||||||
|
# replace by Biometric function
|
||||||
|
data = list(session.query(Person).all())[1].serialize()
|
||||||
|
return flask.make_response(flask.jsonify({'data': data}), 200)
|
||||||
|
|
||||||
if id is None:
|
if id is None:
|
||||||
data = list(session.query(Person).all())
|
data = list(session.query(Person).all())
|
||||||
else:
|
else:
|
||||||
|
|
@ -80,3 +93,51 @@ class PersonList(Resource):
|
||||||
print("error: -", e)
|
print("error: -", e)
|
||||||
return flask.make_response(flask.jsonify({'error': str(e)}), 404)
|
return flask.make_response(flask.jsonify({'error': str(e)}), 404)
|
||||||
|
|
||||||
|
class Camera(Resource):
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# provides th function used for the live streams
|
||||||
|
class VideoCamera(object):
|
||||||
|
"""Video stream object"""
|
||||||
|
url = "http://131.95.3.162/mjpg/video.mjpg"
|
||||||
|
def __init__(self):
|
||||||
|
self.video = cv2.VideoCapture(self.url)
|
||||||
|
|
||||||
|
def __del__(self):
|
||||||
|
self.video.release()
|
||||||
|
|
||||||
|
def get_frame(self, ending):
|
||||||
|
success, image = self.video.read()
|
||||||
|
ret, jpeg = cv2.imencode(ending, image)
|
||||||
|
return jpeg.tobytes()
|
||||||
|
|
||||||
|
|
||||||
|
def gen(self, camera):
|
||||||
|
"""Video streaming generator function."""
|
||||||
|
while True:
|
||||||
|
frame = camera.get_frame('.jpg')
|
||||||
|
yield (b'--frame\r\n'
|
||||||
|
b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n')
|
||||||
|
|
||||||
|
def get(self, type = "stream"):
|
||||||
|
global lastImage
|
||||||
|
try:
|
||||||
|
if type == "stream":
|
||||||
|
return flask.Response(self.gen(self.VideoCamera()), mimetype='multipart/x-mixed-replace; boundary=frame')
|
||||||
|
|
||||||
|
elif type == "still":
|
||||||
|
return flask.Response(lastImage, mimetype='image/jpeg')
|
||||||
|
|
||||||
|
return flask.make_response(flask.jsonify({'error': "No idea how you got here"}), 404)
|
||||||
|
except Exception as e:
|
||||||
|
print("error: -", e)
|
||||||
|
return flask.make_response(flask.jsonify({'error': str(e)}), 404)
|
||||||
|
|
||||||
|
def post(self):
|
||||||
|
global lastImage
|
||||||
|
try:
|
||||||
|
lastImage = self.VideoCamera().get_frame('.png')
|
||||||
|
except Exception as e:
|
||||||
|
print("error: -", e)
|
||||||
|
return flask.make_response(flask.jsonify({'error': str(e)}), 404)
|
||||||
|
|
@ -0,0 +1,49 @@
|
||||||
|
function getJSON(url, callback) {
|
||||||
|
var xhr = new XMLHttpRequest();
|
||||||
|
xhr.open('GET', url, true);
|
||||||
|
xhr.responseType = 'json';
|
||||||
|
xhr.onload = function () {
|
||||||
|
var status = xhr.status;
|
||||||
|
if (status < 400) {
|
||||||
|
callback(null, xhr.response);
|
||||||
|
} else {
|
||||||
|
console.log("failed getting");
|
||||||
|
console.log(status);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
xhr.send();
|
||||||
|
};
|
||||||
|
|
||||||
|
function putJSON(url, data, callback) {
|
||||||
|
var xhr = new XMLHttpRequest();
|
||||||
|
xhr.open('PUT', url, true);
|
||||||
|
xhr.responseType = 'json';
|
||||||
|
xhr.setRequestHeader('Content-Type', 'application/json');
|
||||||
|
xhr.onload = function () {
|
||||||
|
var status = xhr.status;
|
||||||
|
if (status < 400) {
|
||||||
|
callback(null, xhr.response);
|
||||||
|
} else {
|
||||||
|
console.log("failed posting");
|
||||||
|
console.log(status);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
xhr.send(data);
|
||||||
|
};
|
||||||
|
|
||||||
|
function postJSON(url, data, callback) {
|
||||||
|
var xhr = new XMLHttpRequest();
|
||||||
|
xhr.open('POST', url, true);
|
||||||
|
xhr.responseType = 'json';
|
||||||
|
xhr.setRequestHeader('Content-Type', 'application/json');
|
||||||
|
xhr.onload = function () {
|
||||||
|
var status = xhr.status;
|
||||||
|
if (status < 400) {
|
||||||
|
callback(null, xhr.response);
|
||||||
|
} else {
|
||||||
|
console.log("failed posting");
|
||||||
|
console.log(status);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
xhr.send(data);
|
||||||
|
};
|
||||||
|
|
@ -15,13 +15,18 @@
|
||||||
left: -50%;
|
left: -50%;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
.navButton{
|
||||||
|
padding-left: 1rem;
|
||||||
|
padding-right: 1rem;
|
||||||
|
margin-right: 0.5rem;
|
||||||
|
}
|
||||||
#main{
|
#main{
|
||||||
width: 65rem;
|
width: 65rem;
|
||||||
height: 38rem;
|
height: 38rem;
|
||||||
position: relative;
|
position: relative;
|
||||||
top: 10rem;
|
top: 10rem;
|
||||||
left: -50%;
|
left: -50%;
|
||||||
|
display: block;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -47,3 +52,33 @@
|
||||||
padding: 0;
|
padding: 0;
|
||||||
height: 0;
|
height: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#middle-left{
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
#middle-right{
|
||||||
|
float:right;
|
||||||
|
}
|
||||||
|
.middle{
|
||||||
|
margin: 0rem 2rem 0 2rem;
|
||||||
|
height: 100%;
|
||||||
|
width: 40%;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
#image-left{
|
||||||
|
width:100%;
|
||||||
|
padding: 1rem;
|
||||||
|
}
|
||||||
|
#image-right{
|
||||||
|
width:100%;
|
||||||
|
padding: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.heroInfo{
|
||||||
|
padding: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.middle-controls{
|
||||||
|
margin-right: 1rem;
|
||||||
|
}
|
||||||
|
|
@ -1,70 +1,142 @@
|
||||||
|
|
||||||
rootKontext = ""
|
rootKontext = ""
|
||||||
|
selected = null
|
||||||
|
var ml = document.getElementById('middle-left');
|
||||||
|
var mr = document.getElementById('middle-right');
|
||||||
|
personData = {}
|
||||||
|
|
||||||
function getJSON(url, callback) {
|
|
||||||
var xhr = new XMLHttpRequest();
|
function focusNav(id) {
|
||||||
xhr.open('GET', url, true);
|
focusedID = id;
|
||||||
xhr.responseType = 'json';
|
$(id).addClass('btn-primary').siblings().removeClass('btn-primary')
|
||||||
xhr.onload = function () {
|
//$(id).removeClass('active').siblings().removeClass('active')
|
||||||
var status = xhr.status;
|
}
|
||||||
if (status < 400) {
|
|
||||||
callback(null, xhr.response);
|
function focusPerson(id) {
|
||||||
} else {
|
selected = id;
|
||||||
console.log("failed getting");
|
$("#person" + id).removeClass('border-light').siblings().addClass('border-light')
|
||||||
console.log(status);
|
$("#person" + id).addClass('border-success').siblings().removeClass('border-success')
|
||||||
|
renderPersonRight()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function loadPersonList(data) {
|
||||||
|
console.log(data)
|
||||||
|
data = data["data"]
|
||||||
|
let el = document.getElementById('list');
|
||||||
|
data.forEach(function (item) {
|
||||||
|
string = `
|
||||||
|
<div class="card border-light" onclick="focusPerson(${item["person_id"]})" id="person${item["person_id"]}">
|
||||||
|
<div class="card-body">
|
||||||
|
<h4 class="card-title">${item["fname"]} ${item["lname"]}</h4>
|
||||||
|
<h6 class="card-subtitle mb-2 text-muted">${item["timestamp"]}</h6>
|
||||||
|
|
||||||
|
<p class="card-text">
|
||||||
|
<img class="listImg" src="${item["face"]}"></img>
|
||||||
|
<div class="personalInfo">
|
||||||
|
Gender: ${item["gender"]} <br>
|
||||||
|
YoB: ${item["yob"]} <br>
|
||||||
|
Available FP: ${item["fingerprints"].length} <br>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
el.innerHTML += string;
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function snapShot(){
|
||||||
|
postJSON(rootKontext + "/api/v1/camera/", {},
|
||||||
|
function (error, data) {
|
||||||
|
document.getElementById('image-left').src = rootKontext + "/api/v1/camera/still";
|
||||||
}
|
}
|
||||||
};
|
);
|
||||||
xhr.send();
|
}
|
||||||
};
|
|
||||||
|
|
||||||
function putJSON(url, data, callback) {
|
function renderPersonRight(data){
|
||||||
var xhr = new XMLHttpRequest();
|
string = `
|
||||||
xhr.open('PUT', url, true);
|
<img src="${data["face"]}" id="image-right"> </img>
|
||||||
xhr.responseType = 'json';
|
|
||||||
xhr.setRequestHeader('Content-Type', 'application/json');
|
<h4 class="heroInfo">
|
||||||
xhr.onload = function () {
|
Gender: ${data["gender"]} <br>
|
||||||
var status = xhr.status;
|
YoB: ${data["yob"]} <br>
|
||||||
if (status < 400) {
|
Available FP: ${data["fingerprints"].length} <br>
|
||||||
callback(null, xhr.response);
|
</div>
|
||||||
} else {
|
`
|
||||||
console.log("failed posting");
|
mr.innerHTML = string;
|
||||||
console.log(status);
|
}
|
||||||
|
|
||||||
|
function identify(){
|
||||||
|
snapShot()
|
||||||
|
getJSON(rootKontext + "/api/v1/person/?useFace=True",
|
||||||
|
function (error, data) {
|
||||||
|
data = data["data"]
|
||||||
|
renderPersonRight(data)
|
||||||
}
|
}
|
||||||
};
|
);
|
||||||
xhr.send(data);
|
}
|
||||||
};
|
|
||||||
|
|
||||||
|
function validate(){
|
||||||
|
snapShot()
|
||||||
|
getJSON(rootKontext + "/api/v1/person/?useFace=True&?validateId="+selected,
|
||||||
|
function (error, data) {
|
||||||
|
data = data["data"]
|
||||||
|
renderPersonRight(data)
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderValidate(){
|
||||||
|
string = `
|
||||||
|
<img src="${rootKontext + "/api/v1/camera/stream"}" id="image-left"> </img>
|
||||||
|
|
||||||
|
<button onclick="validate()" class="btn btn-primary float-right middle-controls">Validate</button>
|
||||||
|
<button onclick="renderValidate()" class="btn btn-warning float-right middle-controls">Retry</button>
|
||||||
|
`
|
||||||
|
ml.innerHTML = string;
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderChange(){
|
||||||
|
console.log("change")
|
||||||
|
}
|
||||||
|
function renderEnrole(){
|
||||||
|
console.log("enrole")
|
||||||
|
}
|
||||||
|
function renderIdentify(){
|
||||||
|
string = `
|
||||||
|
<img src="${rootKontext + "/api/v1/camera/stream"}" id="image-left"> </img>
|
||||||
|
|
||||||
|
<button onclick="identify()" class="btn btn-primary float-right middle-controls">Identify</button>
|
||||||
|
<button onclick="renderIdentify()" class="btn btn-warning float-right middle-controls">Retry</button>
|
||||||
|
`
|
||||||
|
ml.innerHTML = string;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function loadStream() {
|
||||||
|
string = `
|
||||||
|
<img src="${rootKontext + "/api/v1/camera/stream"}" id="image-left"> </img>
|
||||||
|
`
|
||||||
|
ml.innerHTML += string;
|
||||||
|
|
||||||
|
string = `
|
||||||
|
<img src="${rootKontext + "/api/v1/camera/still"}" id="image-right"> </img>
|
||||||
|
`
|
||||||
|
mr.innerHTML += string;
|
||||||
|
}
|
||||||
|
|
||||||
function loadData() {
|
function loadData() {
|
||||||
getJSON(rootKontext + "/api/v1/person/",
|
getJSON(rootKontext + "/api/v1/person/",
|
||||||
function (error, data) {
|
function (error, data) {
|
||||||
console.log(data)
|
ml = document.getElementById('middle-left');
|
||||||
data = data["data"]
|
mr = document.getElementById('middle-right');
|
||||||
let el = document.getElementById('list');
|
personData = data
|
||||||
data.forEach(function (item) {
|
loadPersonList(data)
|
||||||
string = `
|
renderIdentify()
|
||||||
<div class="card border-light">
|
|
||||||
<div class="card-body">
|
|
||||||
<h4 class="card-title">${item["fname"]} ${item["lname"]}</h4>
|
|
||||||
<h6 class="card-subtitle mb-2 text-muted">${item["timestamp"]}</h6>
|
|
||||||
|
|
||||||
<p class="card-text container">
|
|
||||||
<img class="listImg" src="${item["face"]}"></img>
|
|
||||||
<div class="personalInfo">
|
|
||||||
${item["gender"]} <br>
|
|
||||||
${item["yob"]} <br>
|
|
||||||
${item["fingerprints"].length} <br>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
`
|
|
||||||
el.innerHTML += string;
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,25 @@
|
||||||
|
function renderValidate(){
|
||||||
|
string = `
|
||||||
|
<img src="${rootKontext + "/api/v1/camera/stream"}" id="image-left"> </img>
|
||||||
|
|
||||||
|
<button onclick="validate()" class="btn btn-primary float-right middle-controls">Validate</button>
|
||||||
|
<button onclick="renderValidate()" class="btn btn-warning float-right middle-controls">Retry</button>
|
||||||
|
`
|
||||||
|
ml.innerHTML = string;
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderChange(){
|
||||||
|
console.log("change")
|
||||||
|
}
|
||||||
|
function renderEnrole(){
|
||||||
|
console.log("enrole")
|
||||||
|
}
|
||||||
|
function renderIdentify(){
|
||||||
|
string = `
|
||||||
|
<img src="${rootKontext + "/api/v1/camera/stream"}" id="image-left"> </img>
|
||||||
|
|
||||||
|
<button onclick="identify()" class="btn btn-primary float-right middle-controls">Identify</button>
|
||||||
|
<button onclick="renderIdentify()" class="btn btn-warning float-right middle-controls">Retry</button>
|
||||||
|
`
|
||||||
|
ml.innerHTML = string;
|
||||||
|
}
|
||||||
|
|
@ -21,6 +21,7 @@
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-cookie/1.4.1/jquery.cookie.js"></script>
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-cookie/1.4.1/jquery.cookie.js"></script>
|
||||||
|
|
||||||
|
|
||||||
|
<script src="/static/coms.js"></script>
|
||||||
<script src="/static/main.js"></script>
|
<script src="/static/main.js"></script>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
|
|
@ -29,25 +30,24 @@
|
||||||
<div style="position: fixed; left: 50%; z-index: 9999;">
|
<div style="position: fixed; left: 50%; z-index: 9999;">
|
||||||
<div class="navbar navbar-expand-lg navbar-dark bg-dark" id="switch">
|
<div class="navbar navbar-expand-lg navbar-dark bg-dark" id="switch">
|
||||||
<div class="btn-group btn-group-toggle" data-toggle="buttons">
|
<div class="btn-group btn-group-toggle" data-toggle="buttons">
|
||||||
<label class="btn btn-primary active navi">
|
<button type="button" class="btn btn-primary navButton active" id="option1" onclick="focusNav('#option1'); renderIdentify()"> Identify
|
||||||
<input type="radio" name="options" id="option1" autocomplete="off" checked=""> Identify
|
<button type="button" class="btn navButton" id="option2" onclick="focusNav('#option2'); renderValidate()"> Validate
|
||||||
</label>
|
<button type="button" class="btn navButton" id="option3" onclick="focusNav('#option3'); renderEnrole()"> Enrole
|
||||||
<label class="btn btn-primary navi">
|
<button type="button" class="btn navButton" id="option4" onclick="focusNav('#option4'); renderChange()"> Change
|
||||||
<input type="radio" name="options" id="option2" autocomplete="off"> Validate
|
|
||||||
</label>
|
|
||||||
<label class="btn btn-primary navi">
|
|
||||||
<input type="radio" name="options" id="option3" autocomplete="off"> Enrole
|
|
||||||
</label>
|
|
||||||
<label class="btn btn-primary navi">
|
|
||||||
<input type="radio" name="options" id="option4" autocomplete="off"> Change
|
|
||||||
</label>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div style="position: fixed; left: 50%;">
|
<div style="position: fixed; left: 50%;">
|
||||||
<div class="container bg-dark" id="main">
|
<div class="container bg-dark" id="main">
|
||||||
|
<div class="middle" id="middle-left">
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="middle" id="middle-right">
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
hi
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="container bg-dark" id="list">
|
<div class="container bg-dark" id="list">
|
||||||
|
|
|
||||||
2
run.py
2
run.py
|
|
@ -1,5 +1,5 @@
|
||||||
from application import app
|
from application import app
|
||||||
|
|
||||||
app.run(host="localhost",port='10024', debug=True)
|
app.run(host="localhost", port='5001', debug=True)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
BIN
test.sqlite
BIN
test.sqlite
Binary file not shown.
Loading…
Reference in New Issue