implemented ai in our pa_job_manager, with refimgs, a job, and the whole deal
This commit is contained in:
@@ -11,28 +11,37 @@
|
||||
#
|
||||
###
|
||||
|
||||
### SQLALCHEMY IMPORTS ###
|
||||
|
||||
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.orm import relationship
|
||||
from sqlalchemy import create_engine
|
||||
from sqlalchemy.orm import sessionmaker
|
||||
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 datetime import datetime, timedelta
|
||||
import pytz
|
||||
import time
|
||||
import os
|
||||
import glob
|
||||
from PIL import Image
|
||||
from PIL import Image, ImageOps
|
||||
from pymediainfo import MediaInfo
|
||||
import hashlib
|
||||
import exifread
|
||||
#import exifread
|
||||
import base64
|
||||
import numpy
|
||||
import cv2
|
||||
import socket
|
||||
import threading
|
||||
import io
|
||||
import face_recognition
|
||||
|
||||
DEBUG=1
|
||||
|
||||
@@ -113,6 +122,43 @@ class Settings(Base):
|
||||
|
||||
def __repr__(self):
|
||||
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)
|
||||
|
||||
|
||||
|
||||
################################################################################
|
||||
@@ -199,6 +245,13 @@ def ProcessImportDirs(parent_job=None):
|
||||
session.commit()
|
||||
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 ) )
|
||||
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()
|
||||
return
|
||||
|
||||
@@ -225,6 +278,8 @@ def RunJob(job):
|
||||
JobNewImportDir(job)
|
||||
elif job.name =="getfiledetails":
|
||||
JobGetFileDetails(job)
|
||||
elif job.name == "processai":
|
||||
JobProcessAI(job)
|
||||
else:
|
||||
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...
|
||||
@@ -414,6 +469,16 @@ def JobNewImportDir(job):
|
||||
session.commit()
|
||||
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):
|
||||
JobProgressState( job, "In Progress" )
|
||||
settings = session.query(Settings).first()
|
||||
@@ -527,6 +592,65 @@ def HashAndThumbDirHasNew(dir):
|
||||
dir.last_hash_date = time.time()
|
||||
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):
|
||||
if DEBUG==1:
|
||||
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):
|
||||
thumbnail=None
|
||||
AddLogForJob( job, "Generate Thumbnail from Image file: {}".format( file ), file )
|
||||
f = open(file, 'rb')
|
||||
try:
|
||||
tags = exifread.process_file(f)
|
||||
if '20210121_223307.jpg' in file:
|
||||
print("Tag: img orientation={}".format( tags['Image Orientation']) )
|
||||
print("Tag: GPS GPSLatitude={}".format( tags['GPS GPSLatitude']) )
|
||||
thumbnail = base64.b64encode(tags['JPEGThumbnail'])
|
||||
thumbnail = str(thumbnail)[2:-1]
|
||||
im_orig = Image.open(file)
|
||||
im = ImageOps.exif_transpose(im_orig)
|
||||
im.thumbnail((256,256))
|
||||
img_bytearray = io.BytesIO()
|
||||
im.save(img_bytearray, format='JPEG')
|
||||
img_bytearray = img_bytearray.getvalue()
|
||||
thumbnail = base64.b64encode(img_bytearray)
|
||||
except:
|
||||
print('WARNING: NO EXIF TAGS?!?!?!?')
|
||||
AddLogForJob(job, "WARNING: No EXIF TAF found for: {}".format(file))
|
||||
f.close()
|
||||
|
||||
return thumbnail
|
||||
|
||||
|
||||
Reference in New Issue
Block a user