Compare commits
No commits in common. "8c83eceefa2921e56ab2c27f6c8f75d8b58be1ff" and "3c8eeba2d0a7e75fbf35be3439d49f2fbdf08012" have entirely different histories.
8c83eceefa
...
3c8eeba2d0
@ -26,8 +26,9 @@ RUN DEBIAN_FRONTEND=NONINTERACTIVE apt-get install -y \
|
|||||||
# Install the latest npm and npx
|
# Install the latest npm and npx
|
||||||
RUN npm install --global npm@latest
|
RUN npm install --global npm@latest
|
||||||
|
|
||||||
# Install deepface
|
# Install deepface and retina-face
|
||||||
RUN pip install deepface
|
RUN pip install deepface
|
||||||
|
RUN pip install retina-face
|
||||||
RUN pip install piexif
|
RUN pip install piexif
|
||||||
|
|
||||||
# numpy 1.24 deprecated float; deepface is still using it, so we need to
|
# numpy 1.24 deprecated float; deepface is still using it, so we need to
|
||||||
|
@ -21,8 +21,6 @@ pictures_path = merge_config_path(config['path'], config['picturesPath'])
|
|||||||
faces_path = merge_config_path(config['path'], config['facesPath'])
|
faces_path = merge_config_path(config['path'], config['facesPath'])
|
||||||
db_path = merge_config_path(config['path'], config["db"]["photos"]["host"])
|
db_path = merge_config_path(config['path'], config["db"]["photos"]["host"])
|
||||||
html_base = config['basePath']
|
html_base = config['basePath']
|
||||||
if html_base == "/":
|
|
||||||
html_base = "."
|
|
||||||
|
|
||||||
# TODO
|
# TODO
|
||||||
# Switch to using DBSCAN
|
# Switch to using DBSCAN
|
||||||
|
@ -7,6 +7,8 @@ import argparse
|
|||||||
|
|
||||||
from PIL import Image, ImageOps
|
from PIL import Image, ImageOps
|
||||||
from deepface import DeepFace
|
from deepface import DeepFace
|
||||||
|
from deepface.detectors import FaceDetector
|
||||||
|
from retinaface import RetinaFace
|
||||||
import numpy as np
|
import numpy as np
|
||||||
import cv2
|
import cv2
|
||||||
|
|
||||||
@ -22,8 +24,8 @@ faces_path = merge_config_path(config['path'], config['facesPath'])
|
|||||||
db_path = merge_config_path(config['path'], config["db"]["photos"]["host"])
|
db_path = merge_config_path(config['path'], config["db"]["photos"]["host"])
|
||||||
html_base = config['basePath']
|
html_base = config['basePath']
|
||||||
|
|
||||||
model_name = 'VGG-Face'
|
model_name = 'VGG-Face' # 'ArcFace'
|
||||||
detector_backend = 'mtcnn'
|
detector_backend = 'mtcnn' # 'retinaface'
|
||||||
model = DeepFace.build_model(model_name)
|
model = DeepFace.build_model(model_name)
|
||||||
|
|
||||||
# Derived from
|
# Derived from
|
||||||
@ -68,16 +70,21 @@ def variance_of_laplacian(image):
|
|||||||
def extract_faces(
|
def extract_faces(
|
||||||
img, threshold=0.95, allow_upscaling = True, focus_threshold = 100):
|
img, threshold=0.95, allow_upscaling = True, focus_threshold = 100):
|
||||||
|
|
||||||
|
if detector_backend == 'retinaface':
|
||||||
|
faces = RetinaFace.detect_faces(
|
||||||
|
img_path = img,
|
||||||
|
threshold = threshold,
|
||||||
|
model = model,
|
||||||
|
allow_upscaling = allow_upscaling)
|
||||||
|
elif detector_backend == 'mtcnn':
|
||||||
img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) # mtcnn expects RGB
|
img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) # mtcnn expects RGB
|
||||||
|
|
||||||
redirect_on()
|
redirect_on()
|
||||||
res = face_detector.detect_faces(img_rgb)
|
res = face_detector.detect_faces(img_rgb)
|
||||||
redirect_off()
|
redirect_off()
|
||||||
|
|
||||||
if type(res) != list:
|
|
||||||
return None
|
|
||||||
|
|
||||||
faces = {}
|
faces = {}
|
||||||
|
if type(res) == list:
|
||||||
for i, face in enumerate(res):
|
for i, face in enumerate(res):
|
||||||
if threshold > face['confidence']:
|
if threshold > face['confidence']:
|
||||||
continue
|
continue
|
||||||
@ -99,6 +106,7 @@ def extract_faces(
|
|||||||
'right_eye': list(face['keypoints']['right_eye']),
|
'right_eye': list(face['keypoints']['right_eye']),
|
||||||
},
|
},
|
||||||
'score': face['confidence'],
|
'score': face['confidence'],
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# Re-implementation of 'extract_faces' with the addition of keeping a
|
# Re-implementation of 'extract_faces' with the addition of keeping a
|
||||||
@ -182,13 +190,8 @@ def extract_faces(
|
|||||||
|
|
||||||
|
|
||||||
parser = argparse.ArgumentParser(description = 'Detect faces in images.')
|
parser = argparse.ArgumentParser(description = 'Detect faces in images.')
|
||||||
parser.add_argument(
|
parser.add_argument('photos', metavar='PHOTO', type=int, nargs='*',
|
||||||
'photos',
|
help='PHOTO ID to scan (default: all unscanned photos)')
|
||||||
metavar = 'PHOTO',
|
|
||||||
type=int,
|
|
||||||
nargs='*',
|
|
||||||
help = 'PHOTO ID to scan (default: all unscanned photos)'
|
|
||||||
)
|
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
print(args)
|
print(args)
|
||||||
|
|
||||||
@ -206,7 +209,7 @@ with conn:
|
|||||||
for i, row in enumerate(rows):
|
for i, row in enumerate(rows):
|
||||||
photoId, photoFaces, albumPath, photoFilename = row
|
photoId, photoFaces, albumPath, photoFilename = row
|
||||||
img_path = f'{base}{albumPath}{photoFilename}'
|
img_path = f'{base}{albumPath}{photoFilename}'
|
||||||
print(f'Processing {i+1}/{count}: photoId = {photoId}: {img_path}')
|
print(f'Processing {i+1}/{count}: {img_path}')
|
||||||
try:
|
try:
|
||||||
img = Image.open(img_path)
|
img = Image.open(img_path)
|
||||||
img = ImageOps.exif_transpose(img) # auto-rotate if needed
|
img = ImageOps.exif_transpose(img) # auto-rotate if needed
|
||||||
@ -244,8 +247,6 @@ with conn:
|
|||||||
'descriptorId': faceDescriptorId,
|
'descriptorId': faceDescriptorId,
|
||||||
})
|
})
|
||||||
|
|
||||||
print(f'Face added to database with faceId = {faceId}')
|
|
||||||
|
|
||||||
path = f'{faces_path}/{"{:02d}".format(faceId % 100)}'
|
path = f'{faces_path}/{"{:02d}".format(faceId % 100)}'
|
||||||
try:
|
try:
|
||||||
os.makedirs(path)
|
os.makedirs(path)
|
||||||
|
@ -7,18 +7,10 @@ import uu
|
|||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
|
|
||||||
from ketrface.util import *
|
from ketrface.util import *
|
||||||
from ketrface.config import *
|
|
||||||
|
|
||||||
config = read_config()
|
|
||||||
|
|
||||||
html_path = merge_config_path(config['path'], 'frontend')
|
|
||||||
pictures_path = merge_config_path(config['path'], config['picturesPath'])
|
|
||||||
faces_path = merge_config_path(config['path'], config['facesPath'])
|
|
||||||
db_path = merge_config_path(config['path'], config["db"]["photos"]["host"])
|
|
||||||
html_base = config['basePath']
|
|
||||||
|
|
||||||
|
face_base = "../"
|
||||||
faceId = int(sys.argv[1])
|
faceId = int(sys.argv[1])
|
||||||
path = f'{faces_path}/{"{:02d}".format(faceId % 100)}'
|
path = f'{face_base}faces/{"{:02d}".format(faceId % 10)}'
|
||||||
|
|
||||||
img = Image.open(f'{path}/{faceId}.jpg')
|
img = Image.open(f'{path}/{faceId}.jpg')
|
||||||
exif_dict = piexif.load(img.info["exif"])
|
exif_dict = piexif.load(img.info["exif"])
|
||||||
|
Loading…
x
Reference in New Issue
Block a user