ai stats has divs not tables, so more compact/responsive, also stats now have clickable link to appropriate AI:<tag> search
This commit is contained in:
6
TODO
6
TODO
@@ -1,15 +1,9 @@
|
|||||||
## GENERAL
|
## GENERAL
|
||||||
* get build process to create a random string for secret for PROD, otherwise use builtin for dev
|
* get build process to create a random string for secret for PROD, otherwise use builtin for dev
|
||||||
|
|
||||||
* lighthouse -> check in PROD, all ssl / viewer works?
|
|
||||||
|
|
||||||
* comment your code
|
* comment your code
|
||||||
* html files?
|
* html files?
|
||||||
|
|
||||||
* person->ai stats...
|
|
||||||
* definitely make <tag> be a clickable link to search on AI:<tag>
|
|
||||||
* probably more cols of data to squish more on a page?
|
|
||||||
|
|
||||||
* per file you could select an unknown face and add it as a ref img to an existing person, or make a new person and attach?
|
* per file you could select an unknown face and add it as a ref img to an existing person, or make a new person and attach?
|
||||||
* from menu, we could try to get smart/fancy... say find face with largest size, check it vs. other faces, if it matches more than say 10? we offer it up as a required ref img, then cut that face (with margin) out and use it is a new ref image / person
|
* from menu, we could try to get smart/fancy... say find face with largest size, check it vs. other faces, if it matches more than say 10? we offer it up as a required ref img, then cut that face (with margin) out and use it is a new ref image / person
|
||||||
- read that guys face matching / clustering / nearest neighbour examples, for a whole new AI capability
|
- read that guys face matching / clustering / nearest neighbour examples, for a whole new AI capability
|
||||||
|
|||||||
5
ai.py
5
ai.py
@@ -22,6 +22,9 @@ from face import Face, FaceFileLink, FaceRefimgLink
|
|||||||
@login_required
|
@login_required
|
||||||
def aistats():
|
def aistats():
|
||||||
stats = db.session.execute( "select p.tag, count(f.id) from person p, face f, face_file_link ffl, face_refimg_link frl, person_refimg_link prl where p.id = prl.person_id and prl.refimg_id = frl.refimg_id and frl.face_id = ffl.face_id and ffl.face_id = f.id group by p.tag" )
|
stats = db.session.execute( "select p.tag, count(f.id) from person p, face f, face_file_link ffl, face_refimg_link frl, person_refimg_link prl where p.id = prl.person_id and prl.refimg_id = frl.refimg_id and frl.face_id = ffl.face_id and ffl.face_id = f.id group by p.tag" )
|
||||||
|
cnt_res = db.session.execute( "select count(1) from ( select p.tag from person p, face f, face_file_link ffl, face_refimg_link frl, person_refimg_link prl where p.id = prl.person_id and prl.refimg_id = frl.refimg_id and frl.face_id = ffl.face_id and ffl.face_id = f.id group by p.tag ) as foo" )
|
||||||
|
num_stats=cnt_res.first()[0]
|
||||||
|
|
||||||
fstats={}
|
fstats={}
|
||||||
fstats['files_with_a_face'] = db.session.execute( "select count(distinct file_eid) as count from face_file_link" ).first()[0]
|
fstats['files_with_a_face'] = db.session.execute( "select count(distinct file_eid) as count from face_file_link" ).first()[0]
|
||||||
fstats['files_with_a_match'] = db.session.execute( "select count(distinct ffl.file_eid) as count from face_file_link ffl, face_refimg_link frl where frl.face_id = ffl.face_id" ).first()[0]
|
fstats['files_with_a_match'] = db.session.execute( "select count(distinct ffl.file_eid) as count from face_file_link ffl, face_refimg_link frl where frl.face_id = ffl.face_id" ).first()[0]
|
||||||
@@ -33,7 +36,7 @@ def aistats():
|
|||||||
fstats['all_matched_faces'] = db.session.execute( "select count(distinct face_id) as count from face_refimg_link" ).first()[0]
|
fstats['all_matched_faces'] = db.session.execute( "select count(distinct face_id) as count from face_refimg_link" ).first()[0]
|
||||||
fstats['all_unmatched_faces'] = db.session.execute( "select count(f.id) from face f left join face_refimg_link frl on f.id = frl.face_id where frl.refimg_id is null" ).first()[0]
|
fstats['all_unmatched_faces'] = db.session.execute( "select count(f.id) from face f left join face_refimg_link frl on f.id = frl.face_id where frl.refimg_id is null" ).first()[0]
|
||||||
|
|
||||||
return render_template("aistats.html", page_title='AI Statistics', stats=stats, fstats=fstats )
|
return render_template("aistats.html", page_title='AI Statistics', stats=stats, num_stats=num_stats, fstats=fstats )
|
||||||
|
|
||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
|
|||||||
@@ -147,7 +147,6 @@ def person(id):
|
|||||||
new_refs.append(ref_img)
|
new_refs.append(ref_img)
|
||||||
if new_refs != person.refimg:
|
if new_refs != person.refimg:
|
||||||
deld = list(set(person.refimg) - set(new_refs));
|
deld = list(set(person.refimg) - set(new_refs));
|
||||||
print(deld)
|
|
||||||
person.refimg = new_refs
|
person.refimg = new_refs
|
||||||
Refimg.query.filter(Refimg.id==deld[0].id).delete()
|
Refimg.query.filter(Refimg.id==deld[0].id).delete()
|
||||||
st.SetMessage( f"Successfully Updated Person: removed reference image {deld[0].fname}" )
|
st.SetMessage( f"Successfully Updated Person: removed reference image {deld[0].fname}" )
|
||||||
|
|||||||
@@ -1,21 +1,63 @@
|
|||||||
{% extends "base.html" %}
|
{% extends "base.html" %}
|
||||||
|
|
||||||
{% block main_content %}
|
{% block main_content %}
|
||||||
|
<style>
|
||||||
|
.bgb {
|
||||||
|
background: #cfe2ff
|
||||||
|
}
|
||||||
|
</style>
|
||||||
<h3>Basic AI stats</h3>
|
<h3>Basic AI stats</h3>
|
||||||
<table class="table table-striped table-sm">
|
<div class="row mt-3">
|
||||||
<tbody><thead class="table-primary"><tr><th>What</th><th>Amount</th></tr></thead>
|
<div class="col-3 bgb"><b>What</b></div><div class="col-1 bgb"><center><b>Amount</b></center></div>
|
||||||
<tr><td>Files with a face</td><td>{{fstats['files_with_a_face']}}</td></tr>
|
</div> <div class="row">
|
||||||
<tr><td>Files with a matched face</td><td>{{fstats['files_with_a_match']}}</td></tr>
|
<div class="col-3">Files with a face</div><div class="col-1"><center>{{fstats['files_with_a_face']}}</center></div>
|
||||||
<tr><td>Files with missing matches</td><td>{{fstats['files_with_missing_matches']}}</td></tr>
|
</div> <div class="row">
|
||||||
<tr><td>All faces found</td><td>{{fstats['all_faces']}}</td></tr>
|
<div class="col-3">Files with a face</div><div class="col-1"><center>{{fstats['files_with_a_face']}}</center></div>
|
||||||
<tr><td>All faces matched</td><td>{{fstats['all_matched_faces']}}</td></tr>
|
</div> <div class="row">
|
||||||
<tr><td>All faces unmatched</td><td>{{fstats['all_unmatched_faces']}}</td></tr>
|
<div class="col-3">Files with a matched face</div><div class="col-1"><center>{{fstats['files_with_a_match']}}</center></div>
|
||||||
</tbody></table>
|
</div> <div class="row">
|
||||||
|
<div class="col-3">Files with missing matches</div><div class="col-1"><center>{{fstats['files_with_missing_matches']}}</center></div>
|
||||||
|
</div> <div class="row">
|
||||||
|
<div class="col-3">All faces found</div><div class="col-1"><center>{{fstats['all_faces']}}</center></div>
|
||||||
|
</div> <div class="row">
|
||||||
|
<div class="col-3">All faces matched</div><div class="col-1"><center>{{fstats['all_matched_faces']}}</center></div>
|
||||||
|
</div> <div class="row">
|
||||||
|
<div class="col-3">All faces unmatched</div><div class="col-1"><center>{{fstats['all_unmatched_faces']}}</center></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<table class="table table-striped table-sm">
|
<div class="row mt-4">
|
||||||
<tbody><thead class="table-primary"><tr><th>Person (tag)</th><th>Number of files matched</th></thead>
|
{% if num_stats > 0 %}
|
||||||
|
<div class="col-1 bgb"><b>Person</b></div><div class="col-1 bgb"><center><b># matches</b></center></div><div class="col-1"> </div>
|
||||||
|
{% endif %}
|
||||||
|
{% if num_stats > 1 %}
|
||||||
|
<div class="col-1 bgb"><b>Person</b></div><div class="col-1 bgb"><center><b># matches</b></center></div><div class="col-1"> </div>
|
||||||
|
{% endif %}
|
||||||
|
{% if num_stats > 2 %}
|
||||||
|
<div class="col-1 bgb"><b>Person</b></div><div class="col-1 bgb"><center><b># matches</b></center></div><div class="col-1"> </div>
|
||||||
|
{% endif %}
|
||||||
|
{% if num_stats > 3 %}
|
||||||
|
<div class="col-1 bgb"><b>Person</b></div><div class="col-1 bgb"><center><b># matches</b></center></div>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
{% for s in stats %}
|
{% for s in stats %}
|
||||||
<tr><td>{{s[0]}}</td><td>{{s[1]}}</td></tr>
|
<div class="col-1">
|
||||||
|
<form id="_{{s[0]}}" method="POST" action="{{url_for('search')}}">
|
||||||
|
<input type="hidden" name="search_term" value="AI:{{s[0]}}">
|
||||||
|
<input type="hidden" name="noo" value="Oldest">
|
||||||
|
<input type="hidden" name="grouping" value="None">
|
||||||
|
<input type="hidden" name="how_many" value="50">
|
||||||
|
<input type="hidden" name="offset" value="0">
|
||||||
|
<input type="hidden" name="size" value="128">
|
||||||
|
<input type="hidden" name="folders" value="False">
|
||||||
|
<input type="hidden" name="cwd" value="/">
|
||||||
|
<a href="javascript:$('#_{{s[0]}}').submit()">{{s[0]}}</a></form>
|
||||||
|
</div>
|
||||||
|
<div class="col-1"><center>{{s[1]}}</center></div>
|
||||||
|
<div class="col-1"> </div>
|
||||||
|
{% if loop.index + 1 % 3 == 0 %}
|
||||||
|
</div><div class="row">
|
||||||
|
{% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</tbody></table>
|
</div>
|
||||||
{% endblock main_content %}
|
{% endblock main_content %}
|
||||||
|
|||||||
Reference in New Issue
Block a user