166 lines
3.9 KiB
Python
166 lines
3.9 KiB
Python
import sqlite3
|
|
from sqlite3 import Error
|
|
import numpy as np
|
|
|
|
sqlite3.register_adapter(np.array, lambda arr: arr.tobytes())
|
|
sqlite3.register_converter("array", np.frombuffer)
|
|
|
|
def create_connection(db_file):
|
|
""" create a database connection to the SQLite database
|
|
specified by db_file
|
|
:param db_file: database file
|
|
:return: Connection object or None
|
|
"""
|
|
conn = None
|
|
try:
|
|
conn = sqlite3.connect(db_file)
|
|
except Error as e:
|
|
print(e)
|
|
|
|
return conn
|
|
|
|
def create_face(conn, face):
|
|
"""
|
|
Create a new face in the faces table
|
|
:param conn:
|
|
:param face:
|
|
:return: face id
|
|
"""
|
|
sql = '''
|
|
INSERT INTO faces(photoId,scanVersion,faceConfidence,focus,top,left,bottom,right,descriptorId)
|
|
VALUES(?,?,?,?,?,?,?,?,?)
|
|
'''
|
|
cur = conn.cursor()
|
|
cur.execute(sql, (
|
|
face['photoId'],
|
|
face['scanVersion'],
|
|
face['faceConfidence'],
|
|
face['focus'],
|
|
face['top'],
|
|
face['left'],
|
|
face['bottom'],
|
|
face['right'],
|
|
face['descriptorId']
|
|
))
|
|
conn.commit()
|
|
return cur.lastrowid
|
|
|
|
def create_face_descriptor(conn, face):
|
|
"""
|
|
Create a new face in the faces table
|
|
:param conn:
|
|
:param face:
|
|
:return: descriptor id
|
|
"""
|
|
sql = '''
|
|
INSERT INTO facedescriptors(descriptors)
|
|
VALUES(?)
|
|
'''
|
|
cur = conn.cursor()
|
|
cur.execute(sql, (np.array(face['vector']),))
|
|
conn.commit()
|
|
return cur.lastrowid
|
|
|
|
def update_face_count(conn, photoId, faces):
|
|
"""
|
|
Update the number of faces that have been matched on a photo
|
|
:param conn:
|
|
:param photoId:
|
|
:param faces:
|
|
:return: None
|
|
"""
|
|
sql = '''
|
|
UPDATE photos SET faces=? WHERE id=?
|
|
'''
|
|
cur = conn.cursor()
|
|
cur.execute(sql, (faces, photoId))
|
|
conn.commit()
|
|
return None
|
|
|
|
|
|
import sys
|
|
import json
|
|
import os
|
|
import piexif
|
|
import sqlite3
|
|
from sqlite3 import Error
|
|
from PIL import Image
|
|
import numpy as np
|
|
|
|
def load_faces(db_path ):
|
|
print(f'Connecting to database: {db_path}')
|
|
conn = create_connection(db_path)
|
|
faces = []
|
|
with conn:
|
|
print('Querying faces')
|
|
cur = conn.cursor()
|
|
res = cur.execute('''
|
|
SELECT faces.id,facedescriptors.descriptors,faces.faceConfidence,faces.photoId,faces.focus
|
|
FROM faces
|
|
INNER JOIN photos ON (photos.duplicate == 0 OR photos.duplicate IS NULL)
|
|
JOIN facedescriptors ON (faces.descriptorId=facedescriptors.id)
|
|
WHERE faces.identityId IS null
|
|
AND faces.classifiedBy != 'not-a-face'
|
|
AND faces.classifiedBy != 'forget'
|
|
AND faces.photoId=photos.id
|
|
''')
|
|
for row in res.fetchall():
|
|
id, descriptors, confidence, photoId, focus = row
|
|
if focus is None:
|
|
focus = 100 # Assume full focus if focus not set
|
|
face = {
|
|
'id': id,
|
|
'type': 'face',
|
|
'confidence': confidence,
|
|
'distance': 0,
|
|
'photoId': photoId,
|
|
'descriptors': np.frombuffer(descriptors),
|
|
'cluster': 0, # Undefined from dbscan.py
|
|
'focus': focus
|
|
}
|
|
face['faces'] = [ face ]
|
|
face['sqrtsummul'] = np.sqrt(np.sum(np.multiply(
|
|
face['descriptors'], face['descriptors'])))
|
|
faces.append(face)
|
|
return faces
|
|
|
|
def create_identity(conn, identity):
|
|
"""
|
|
Create a new identity in the identities table
|
|
:param conn:
|
|
:param identity:
|
|
:return: identity id
|
|
"""
|
|
sql = '''
|
|
INSERT INTO identities(descriptors,displayName)
|
|
VALUES(?,?)
|
|
'''
|
|
cur = conn.cursor()
|
|
cur.execute(sql, (
|
|
np.array(identity['descriptors']),
|
|
f'cluster-{identity["id"]}'
|
|
))
|
|
conn.commit()
|
|
return cur.lastrowid
|
|
|
|
def update_face_identity(conn, faceId, identityId = None, first = False):
|
|
"""
|
|
Update the identity associated with this face
|
|
:param conn:
|
|
:param faceId:
|
|
:param identityId:
|
|
:return: None
|
|
"""
|
|
sql = '''
|
|
UPDATE faces SET identityId=? WHERE id=?
|
|
'''
|
|
cur = conn.cursor()
|
|
cur.execute(sql, (identityId, faceId))
|
|
if first:
|
|
sql = '''
|
|
UPDATE identities SET faceId=? WHERE id=?
|
|
'''
|
|
cur.execute(sql, (faceId, identityId))
|
|
conn.commit()
|
|
return None
|