implemented ai in our pa_job_manager, with refimgs, a job, and the whole deal

This commit is contained in:
2021-01-22 18:46:18 +11:00
parent 53d0f71b58
commit 605b26af89

View File

@@ -11,28 +11,37 @@
# #
### ###
### SQLALCHEMY IMPORTS ###
from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String, Sequence, Float, ForeignKey, DateTime from sqlalchemy import Column, Integer, String, Sequence, Float, ForeignKey, DateTime, LargeBinary
from sqlalchemy.exc import SQLAlchemyError from sqlalchemy.exc import SQLAlchemyError
from sqlalchemy.orm import relationship from sqlalchemy.orm import relationship
from sqlalchemy import create_engine from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker from sqlalchemy.orm import sessionmaker
from sqlalchemy.orm import scoped_session from sqlalchemy.orm import scoped_session
### SQLALCHEMY IMPORTS ###
### LOCAL FILE IMPORTS ###
from shared import DB_URL, PA_JOB_MANAGER_HOST, PA_JOB_MANAGER_PORT from shared import DB_URL, PA_JOB_MANAGER_HOST, PA_JOB_MANAGER_PORT
from datetime import datetime, timedelta from datetime import datetime, timedelta
import pytz import pytz
import time import time
import os import os
import glob import glob
from PIL import Image from PIL import Image, ImageOps
from pymediainfo import MediaInfo from pymediainfo import MediaInfo
import hashlib import hashlib
import exifread #import exifread
import base64 import base64
import numpy import numpy
import cv2 import cv2
import socket import socket
import threading import threading
import io
import face_recognition
DEBUG=1 DEBUG=1
@@ -114,6 +123,43 @@ class Settings(Base):
def __repr__(self): def __repr__(self):
return "<id: {}, import_path: {}>".format(self.id, self.import_path ) return "<id: {}, import_path: {}>".format(self.id, self.import_path )
class Person_Refimg_Link(Base):
__tablename__ = "person_refimg_link"
person_id = Column(Integer, ForeignKey('person.id'), unique=True, nullable=False, primary_key=True)
refimg_id = Column(Integer, ForeignKey('refimg.id'), unique=True, nullable=False, primary_key=True)
def __repr__(self):
return "<person_id: {}, refimg_id>".format(self.person_id, self.refimg_id)
class Person(Base):
__tablename__ = "person"
id = Column(Integer, Sequence('person_id_seq'), primary_key=True )
tag = Column(String(48), unique=False, nullable=False)
surname = Column(String(48), unique=False, nullable=False)
firstname = Column(String(48), unique=False, nullable=False)
refimg = relationship('Refimg', secondary=Person_Refimg_Link.__table__)
def __repr__(self):
return "<tag: {}, firstname: {}, surname: {}, refimg: {}>".format(self.tag,self.firstname, self.surname, self.refimg)
class Refimg(Base):
__tablename__ = "refimg"
id = Column(Integer, Sequence('refimg_id_seq'), primary_key=True )
fname = Column(String(256), unique=True, nullable=False)
encodings = Column(LargeBinary)
def __repr__(self):
return "<id: {}, fname: {}, encodings: {}>".format(self.id, self.fname, self.encodings )
class File_Person_Link(Base):
__tablename__ = "file_person_link"
file_id = Column(Integer, ForeignKey('file.eid'), unique=True, nullable=False, primary_key=True)
person_id = Column(Integer, ForeignKey('person.id'), unique=True, nullable=False, primary_key=True)
def __repr__(self):
return "<file_id: {}, person_id: {}>".format(self.file_id, self.person_id)
################################################################################ ################################################################################
# classes for the job manager: # classes for the job manager:
@@ -199,6 +245,13 @@ def ProcessImportDirs(parent_job=None):
session.commit() session.commit()
if parent_job: if parent_job:
AddLogForJob(parent_job, "adding <a href='/job/{}'>job id={} {}</a> (wait for: {})".format( job2.id, job2.id, job2.name, job2.wait_for ) ) AddLogForJob(parent_job, "adding <a href='/job/{}'>job id={} {}</a> (wait for: {})".format( job2.id, job2.id, job2.name, job2.wait_for ) )
jex3=JobExtra( name="path", value=path )
job3=Job(start_time='now()', last_update='now()', name="processai", state="New", wait_for=job.id, pa_job_state="New" )
job3.extra.append(jex3)
session.add(job3)
session.commit()
if parent_job:
AddLogForJob(parent_job, "adding <a href='/job/{}'>job id={} {}</a> (wait for: {})".format( job3.id, job3.id, job3.name, job3.wait_for ) )
HandleJobs() HandleJobs()
return return
@@ -225,6 +278,8 @@ def RunJob(job):
JobNewImportDir(job) JobNewImportDir(job)
elif job.name =="getfiledetails": elif job.name =="getfiledetails":
JobGetFileDetails(job) JobGetFileDetails(job)
elif job.name == "processai":
JobProcessAI(job)
else: else:
print("ERROR: Requested to process unknown job type: {}".format(job.name)) print("ERROR: Requested to process unknown job type: {}".format(job.name))
# okay, we finished a job, so check for any jobs that are dependant on this and run them... # okay, we finished a job, so check for any jobs that are dependant on this and run them...
@@ -414,6 +469,16 @@ def JobNewImportDir(job):
session.commit() session.commit()
return return
def JobProcessAI(job):
path=[jex.value for jex in job.extra if jex.name == "path"][0]
path='static/photos'
print('meeeee',path)
for e in FilesInDir( path ):
ProcessFilesInDir(job, e, ProcessAI, lambda a: True)
FinishJob(job, "Finished Processesing AI")
r = session.query(Refimg).get(1)
print(r)
def JobImportDir(job): def JobImportDir(job):
JobProgressState( job, "In Progress" ) JobProgressState( job, "In Progress" )
settings = session.query(Settings).first() settings = session.query(Settings).first()
@@ -527,6 +592,65 @@ def HashAndThumbDirHasNew(dir):
dir.last_hash_date = time.time() dir.last_hash_date = time.time()
return 1 return 1
def ProcessAI(job, e):
print('AING',e)
if e.type.name != 'Image':
return
people = session.query(Person).all()
for person in people:
generateKnownEncodings(person)
file = e.in_dir[0].path_prefix + '/' + e.name
im_orig = Image.open(file)
im = ImageOps.exif_transpose(im_orig)
unknown_encodings = generateUnknownEncodings(im)
for unknown_encoding in unknown_encodings:
for person in people:
lookForPersonInImage(person, unknown_encoding, e)
return
def lookForPersonInImage(person, unknown_encoding, e):
for refimg in person.refimg:
deserialized_bytes = numpy.frombuffer(refimg.encodings, dtype=numpy.float64)
#deserialized_x = numpy.reshape(deserialized_bytes, newshape=(2,2))
results = compareAI(deserialized_bytes, unknown_encoding)
if results[0]:
print(f'Found a match between: {person.tag} and {e.name}')
fpl = File_Person_Link(person_id=person.id, file_id=e.file_details[0].eid)
session.add(fpl)
return
def generateUnknownEncodings(im):
unknown_image = numpy.array(im)
face_locations = face_recognition.face_locations(unknown_image)
unknown_encodings = face_recognition.face_encodings(unknown_image, known_face_locations=face_locations)
# should save these to the db
# file.locations = face_locations
return unknown_encodings
def generateKnownEncodings(person):
for refimg in person.refimg:
img = face_recognition.load_image_file('reference_images/'+refimg.fname)
location = face_recognition.face_locations(img)
encodings = face_recognition.face_encodings(img, known_face_locations=location)
refimg.encodings = encodings[0].tobytes()
session.add(refimg)
session.commit()
def compareAI(known_encoding, unknown_encoding):
results = face_recognition.compare_faces([known_encoding], unknown_encoding, tolerance=0.55)
return results
def ProcessFilesInDir(job, e, file_func, go_into_dir_func): def ProcessFilesInDir(job, e, file_func, go_into_dir_func):
if DEBUG==1: if DEBUG==1:
print("DEBUG: files in dir - process: {} {}".format(e.name, e.in_dir[0].path_prefix)) print("DEBUG: files in dir - process: {} {}".format(e.name, e.in_dir[0].path_prefix))
@@ -602,18 +726,17 @@ def isImage(file):
def GenImageThumbnail(job, file): def GenImageThumbnail(job, file):
thumbnail=None thumbnail=None
AddLogForJob( job, "Generate Thumbnail from Image file: {}".format( file ), file ) AddLogForJob( job, "Generate Thumbnail from Image file: {}".format( file ), file )
f = open(file, 'rb')
try: try:
tags = exifread.process_file(f) im_orig = Image.open(file)
if '20210121_223307.jpg' in file: im = ImageOps.exif_transpose(im_orig)
print("Tag: img orientation={}".format( tags['Image Orientation']) ) im.thumbnail((256,256))
print("Tag: GPS GPSLatitude={}".format( tags['GPS GPSLatitude']) ) img_bytearray = io.BytesIO()
thumbnail = base64.b64encode(tags['JPEGThumbnail']) im.save(img_bytearray, format='JPEG')
thumbnail = str(thumbnail)[2:-1] img_bytearray = img_bytearray.getvalue()
thumbnail = base64.b64encode(img_bytearray)
except: except:
print('WARNING: NO EXIF TAGS?!?!?!?') print('WARNING: NO EXIF TAGS?!?!?!?')
AddLogForJob(job, "WARNING: No EXIF TAF found for: {}".format(file)) AddLogForJob(job, "WARNING: No EXIF TAF found for: {}".format(file))
f.close()
return thumbnail return thumbnail