refactor with an eye on paravision alternative

This commit is contained in:
carl 2024-01-22 10:10:56 -04:00
parent 4ade0b27a3
commit 94d284129e
4 changed files with 411 additions and 0 deletions

174
src/face_recognitionx.py Normal file
View File

@ -0,0 +1,174 @@
#!/usr/bin/python
"""
#
# DISPENSION CONFIDENTIAL
#
# [2020] - [2021] Dispension Industries Limited.
# Portions Copyright © 2014-2020 Atlantean Technical Solutions Limited
# with full rights granted to Dispension & Successors.
#
# All Rights Reserved.
#
# NOTICE: All information contained herein is, and remains
# the property of Dispension Industries Limited.
# The intellectual and technical concepts contained
# herein are proprietary to Dispension Industries Limited
# and its suppliers and may be covered by U.S. and Foreign Patents,
# patents in process, and are protected by trade secret or copyright law.
# Dissemination of this information or reproduction of this material
# is strictly forbidden unless prior written permission is obtained
# from Dispension Industries Limited.
#
Old:
Use Paravision recognition SDK to compare two images of faces
Returns face quality scores of both images and a match score
Quality score range from 0 to 1, where 1 is highest quality for face recognition / matching
Match score ranges from 400 to 700, where higher score is higher chance of match
New:
As of Dec 2022, use an open source equivalent to paravision
"""
# supt apt install cmake (for building face_recognition)
# sudo pip3 install opencv2
# sudo pip3 install face_recognition
import cv2
import sys
import os
import face_recognition
import json
import urllib.request
import time
class FaceRecognition(object):
name = "face_recognition_face_match"
IN_ENGLISH = "A class for checking the similarity between two faces."
dev1 = "some_device"
dev2 = "some_other_device"
id_qual = 0.7
photo_qual = 0.7
face_match_json = None
conf = []
imgs = {}
# Load the config
def init(self):
with open("/etc/ukdi.json","r") as f:
self.conf = json.loads(f.read())
#id_image_filepath = '/home/lucas-acm/Dispension/UKDI_testdata/LW_cardscan/Portrait_0.jpg'
#photo_image_filepath = '/home/lucas-acm/Dispension/UKDI_testdata/LW.jpg'
#id_image_filepath = '/tmp/regula/Portrait_0.jpg'
#photo_image_filepath = '/home/disp/Pictures/realsense_test.jpg'
def load(self, dev, image_filepath):
self.dev1 = dev1
self.dev2 = dev2
print("id_image_filepath: " + id_image_filepath)
try:
# load/encode pic1
img1 = cv2.imread(id_image_filepath)
self.id_image = cv2.cvtColor(img1, cv2.COLOR_BGR2RGB)
# load/encode pic2
img2 = cv2.imread(photo_image_filepath)
self.photo_image = cv2.cvtColor(img2, cv2.COLOR_BGR2RGB)
#cv2.imshow("id..",self.id_image)
#cv2.imshow("id..",self.photo_image)
#cv2.waitKey(0)
return True
except:
return None
def load2(self, dev1, dev2, id_image_filepath, photo_image_filepath):
self.dev1 = dev1
self.dev2 = dev2
print("id_image_filepath: " + id_image_filepath)
try:
# load/encode pic1
img1 = cv2.imread(id_image_filepath)
self.id_image = cv2.cvtColor(img1, cv2.COLOR_BGR2RGB)
# load/encode pic2
img2 = cv2.imread(photo_image_filepath)
self.photo_image = cv2.cvtColor(img2, cv2.COLOR_BGR2RGB)
#cv2.imshow("id..",self.id_image)
#cv2.imshow("id..",self.photo_image)
#cv2.waitKey(0)
return True
except:
return None
def get_faces(self):
print("** get_faces ...")
try:
# Get all faces from images with qualities, landmarks, and embeddings
boxes1 = face_recognition.face_locations(self.photo_image, number_of_times_to_upsample=2, model='hog')
boxes2 = face_recognition.face_locations(self.id_image, number_of_times_to_upsample=2, model='hog')
#print("n boxes = ", boxes)
print("found %d + %d boxes" % (len(boxes1), len(boxes2)))
# Get numerical representation of faces (required for face match)
self.id_enc = face_recognition.face_encodings(self.id_image)[0]
self.photo_enc = face_recognition.face_encodings(self.photo_image)[0]
#print(self.id_enc)
#print(self.photo_enc)
except Exception as ex:
return "image processing exception "+str(ex)
return len(boxes1)+len(boxes2)
# return " id=%d photo=%d result=%d " % (self.id_face, self.photo_face, len(self.image_inference_result))
def get_landmarks(self):
self.landmarks = face_recognition.face_landmarks(self.photo_image)
print(self.landmarks)
def compute_scores(self):
print("** computing...")
try:
res = face_recognition.compare_faces([self.id_enc], self.photo_enc)
print("Match is ",res)
self.match_score = 1000 * (1 - face_recognition.face_distance([self.id_enc], self.photo_enc))
print("Score is ",self.match_score)
# Create .json
self.face_match_json = {"device1":self.dev1,
"device2":self.dev2,
"passmark":380,
"device1_qual":0.5,
"device2_qual":0.5,
"match_score":self.match_score[0]}
except Exception as ex:
return "image comparison exception "+str(ex)
def get_scores(self):
return json.dumps(self.face_match_json)
if __name__ == '__main__':
d = FaceRecognition()
if sys.argv[1]=="match":
# lfw
n=0
print("LFW Matching")
for lfw in sorted(os.listdir("/home/carl/Downloads/lfw/0002")):
d.load2("0001","0002", "/home/carl/Downloads/lfw/0001/" + lfw, "/home/carl/Downloads/lfw/0002/" + lfw)
d.get_faces()
d.compute_scores()
print(d.get_scores())
print(d.get_landmarks())
n+=1
if n > 1:
sys.exit(0)

74
src/faceclass.py Normal file
View File

@ -0,0 +1,74 @@
import sys
import os
import cv2
from matplotlib import pyplot as plt
class FaceClass(object):
imgs = {}
faces = {}
visual = 0
# Prep tasks
# Load a pics using the device label
def load1(self, name,fname):
if not os.path.isfile(fname):
return False
self.imgs[name] = cv2.imread(fname)
#print(" Loaded %s from file %s" % (name, fname))
return True
def load(self, name1,name2,fname1,fname2):
if not os.path.isfile(fname1):
return False
if not os.path.isfile(fname2):
return False
self.imgs[name1] = cv2.imread(fname1)
self.imgs[name2] = cv2.imread(fname2)
if self.visual:
p1 = plt.imshow(name1, self.imgs[name1])
p2.imshow(name2, self.imgs[name2])
p1.show()
#print(" Loaded %s from file %s" % (name, fname))
return True
def box(self, name, x, y, w, h):
cv2.rectangle(self.imgs[name],(x,y),(x+w,y+h), (0,255,0), 4)
# Load the config
def init(self):
with open("/etc/ukdi.json","r") as f:
self.conf = json.loads(f.read())
# Find all faces
# Find best face
# Find landmarks
# Find metadata (age etc)
# Match two faces
if __name__ == '__main__':
# tests
# big/clear big/clear small/side small/clear obscured ig card IR cam some rotated
picfiles = [ "gerrard.jpg", "ronaldo.jpg", "messi1.jpg", "messi2.jpg", "ox_matt.png", "ox_govid.jpg", "cg_ir.jpg", "fivepeople.jpg" ]
# Test the dlib image detector
d = FaceClass()
# quick test
if sys.argv[1]=="quick":
d.visual = 1
d.load("messi1","messi2","testimg/messi1.jpg","testimg/messi2.jpg")
sys.exit(0)

15
src/insightfacex.py Normal file
View File

@ -0,0 +1,15 @@
import cv2
import numpy as np
import insightface
from insightface.app import FaceAnalysis
from insightface.data import get_image as ins_get_image
class InsightFace(object):
app = None
def init(self):
# Method-1, use FaceAnalysis
self.app = FaceAnalysis(allowed_modules=['detection']) # enable detection model only
self.app.prepare(ctx_id=0, det_size=(640, 640))

148
src/paravisionx.py Normal file
View File

@ -0,0 +1,148 @@
#
# Paravision based face matcher
#
import json
from paravision.recognition.exceptions import ParavisionException
from paravision.recognition.engine import Engine
from paravision.recognition.sdk import SDK
import paravision.recognition.utils as pru
#from openvino.inference_engine import Engineq
#from deepface.basemodels import VGGFace, OpenFace, Facenet, FbDeepFace, DeepID
class Facematch(object):
def init(self):
print("@@@ initialising paravision")
try:
self.sdk = SDK(engine=Engine.AUTO)
except ParavisionException:
pass
# Read an image from a file
def loadiii(self, imgpath):
if not os.path.exists(imgpath):
print("File not found ",imgpath)
return False
self.imgpath = imgpath
self.image = pru.load_image(imgpath)
print(self.image)
return True
# Assess the face that was read in
def processiii(self):
# Get all faces metadata
print("Finding faces in %s" %(self.imgpath))
faces = self.sdk.get_faces([self.image], qualities=True, landmarks=True, embeddings=True)
print("Getting metadata")
inferences = faces.image_inferences
print("Getting best face")
ix = inferences[0].most_prominent_face_index()
print("Getting a mathematical mode of that best face")
self.model = inferences[0].faces[ix].embedding
print("Getting image quality scores..")
self.score = round(1000*inferences[0].faces[ix].quality)
print("Score was %d" %(self.score))
return self.score
# Compare to a face in another Facematch instance
def compare(self,other):
# Get face match score
return self.sdk.get_match_score(self.model, other.model)
#mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
#
def load(self, dev1, dev2, id_image_filepath, photo_image_filepath):
print("## loading images", dev1, dev2)
self.dev1 = dev1
self.dev2 = dev2
try:
self.id_image = pru.load_image(id_image_filepath)
except Exception as e:
return "id image loading failed ", e
try:
self.photo_image = pru.load_image(photo_image_filepath)
except Exception as e:
return "client image loading failed ", e
return None
def get_faces(self):
try:
# Get all faces from images with qualities, landmarks, and embeddings
print("Finding faces...")
self.inference_result = self.sdk.get_faces([self.id_image, self.photo_image], qualities=True, landmarks=True, embeddings=True)
print("Inferences...")
self.image_inference_result = self.inference_result.image_inferences
if len(self.image_inference_result)==0:
return "no inferences found"
# Get most prominent face
print("Most prominent...")
self.id_face = self.image_inference_result[0].most_prominent_face_index()
self.photo_face = self.image_inference_result[1].most_prominent_face_index()
if self.id_face<0:
return "no id face found"
if self.photo_face<0:
return "no live face found"
# Get numerical representation of faces (required for face match)
print("stats...")
if (len(self.image_inference_result)<2):
return "ID or human face could not be recognised"
self.id_emb = self.image_inference_result[0].faces[self.id_face].embedding
self.photo_emb = self.image_inference_result[1].faces[self.photo_face].embedding
except Exception as ex:
return "image processing exception "+str(ex)
return None
def compute_scores(self):
try:
# Get image quality scores (how 'good' a face is)
self.id_qual = self.image_inference_result[0].faces[self.id_face].quality
self.photo_qual = self.image_inference_result[1].faces[self.photo_face].quality
self.id_qual = round(self.id_qual, 3)
self.photo_qual = round(self.photo_qual, 3)
# Get face match score
self.match_score = self.sdk.get_match_score(self.id_emb, self.photo_emb)
# Create .json
self.face_match_json = {"device1":self.dev1,
"device2":self.dev2,
"passmark":500,
"device1_qual":self.id_qual,
"device2_qual":self.photo_qual,
"match_score":self.match_score}
#return json.dumps(self.face_match_json)
#print(self.face_match_json)
# Send to core
#url = "%s/notify/%s/%s" % (self.conf["core"], self.conf["identity"], face_match_json)
#url = url.replace(" ", "%20") # Remove spaces
#buf = []
#req = urllib.request.Request( url )
#with urllib.request.urlopen(req) as response:
#print(response.read())
except Exception as ex:
return str(ex)
def get_scores(self):
return json.dumps(self.face_match_json)