mirror of
https://github.com/serengil/deepface.git
synced 2025-06-04 02:20:06 +00:00
fix(represent): 1. support represent user given image 2. img_path support pathlib.Path
This commit is contained in:
parent
44f191c8aa
commit
8c6dad0147
@ -674,16 +674,30 @@ def represent(
|
||||
This might be convenient for low resolution images.
|
||||
|
||||
detector_backend (string): set face detector backend to opencv, retinaface, mtcnn, ssd,
|
||||
dlib, mediapipe or yolov8.
|
||||
dlib, mediapipe or yolov8. A special value `skip` could be used to skip face-detection
|
||||
and only encode the given image.
|
||||
|
||||
align (boolean): alignment according to the eye positions.
|
||||
|
||||
normalization (string): normalize the input image before feeding to model
|
||||
|
||||
Returns:
|
||||
Represent function returns a list of object with multidimensional vector (embedding).
|
||||
The number of dimensions is changing based on the reference model.
|
||||
E.g. FaceNet returns 128 dimensional vector; VGG-Face returns 2622 dimensional vector.
|
||||
Represent function returns a list of object, each object has fields as follows:
|
||||
{
|
||||
// Multidimensional vector
|
||||
// The number of dimensions is changing based on the reference model.
|
||||
// E.g. FaceNet returns 128 dimensional vector; VGG-Face returns 2622 dimensional vector.
|
||||
"embedding": np.array,
|
||||
|
||||
// Detected Facial-Area by Face detection in dict format.
|
||||
// (x, y) is left-corner point, and (w, h) is the width and height
|
||||
// If `detector_backend` == `skip`, it is the full image area and nonsense.
|
||||
"facial_area": dict{"x": int, "y": int, "w": int, "h": int},
|
||||
|
||||
// Face detection confidence.
|
||||
// If `detector_backend` == `skip`, will be 0 and nonsense.
|
||||
"face_confidence": float
|
||||
}
|
||||
"""
|
||||
resp_objs = []
|
||||
|
||||
@ -702,23 +716,23 @@ def represent(
|
||||
align=align,
|
||||
)
|
||||
else: # skip
|
||||
if isinstance(img_path, str):
|
||||
img = functions.load_image(img_path)
|
||||
elif type(img_path).__module__ == np.__name__:
|
||||
if type(img_path).__module__ == np.__name__:
|
||||
img = img_path.copy()
|
||||
else:
|
||||
raise ValueError(f"unexpected type for img_path - {type(img_path)}")
|
||||
# Try load. If load error, will raise exception internal
|
||||
img, _ = functions.load_image(img_path)
|
||||
# --------------------------------
|
||||
if len(img.shape) == 4:
|
||||
img = img[0] # e.g. (1, 224, 224, 3) to (224, 224, 3)
|
||||
if len(img.shape) == 3:
|
||||
img = cv2.resize(img, target_size)
|
||||
img = np.expand_dims(img, axis=0)
|
||||
# when represent is called from verify, this is already normalized
|
||||
img = np.expand_dims(img, axis=0) # Why we remove a axis=0 previously and here expand one?
|
||||
# when represent is called from verify, this is already normalized. But needed when user given.
|
||||
if img.max() > 1:
|
||||
img /= 255
|
||||
img = img.astype(np.float32) / 255.
|
||||
# --------------------------------
|
||||
img_region = [0, 0, img.shape[1], img.shape[0]]
|
||||
# make dummy region and confidence to keep compatibility with `extract_faces`
|
||||
img_region = {"x": 0, "y": 0, "w": img.shape[1], "h": img.shape[2]}
|
||||
img_objs = [(img, img_region, 0)]
|
||||
# ---------------------------------
|
||||
|
||||
@ -731,6 +745,9 @@ def represent(
|
||||
# model.predict causes memory issue when it is called in a for loop
|
||||
# embedding = model.predict(img, verbose=0)[0].tolist()
|
||||
embedding = model(img, training=False).numpy()[0].tolist()
|
||||
# if you still get verbose logging. try call
|
||||
# - `tf.keras.utils.disable_interactive_logging()`
|
||||
# in your main program
|
||||
else:
|
||||
# SFace and Dlib are not keras models and no verbose arguments
|
||||
embedding = model.predict(img)[0].tolist()
|
||||
|
@ -94,6 +94,14 @@ def load_image(img):
|
||||
if type(img).__module__ == np.__name__:
|
||||
return img, None
|
||||
|
||||
try:
|
||||
# Test whether img is a Python3's Path. If hit, tranform to str to let following logic work.
|
||||
from pathlib import Path
|
||||
if isinstance(img, Path):
|
||||
img = str(img)
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
# The image is a base64 string
|
||||
if img.startswith("data:image/"):
|
||||
return loadBase64Img(img), None
|
||||
|
@ -127,6 +127,27 @@ def test_cases():
|
||||
assert exception_thrown is False
|
||||
# -------------------------------------------
|
||||
|
||||
# Test represent on user-given image (skip detector)
|
||||
try:
|
||||
face_img = dataset[1][0] # It's a face
|
||||
img_objs = DeepFace.represent(img_path=face_img, detector_backend="skip")
|
||||
assert len(img_objs) == 1
|
||||
img_obj = img_objs[0]
|
||||
assert "embedding" in img_obj.keys()
|
||||
assert "facial_area" in img_obj.keys()
|
||||
assert isinstance(img_obj["facial_area"], dict)
|
||||
assert "x" in img_obj["facial_area"].keys()
|
||||
assert "y" in img_obj["facial_area"].keys()
|
||||
assert "w" in img_obj["facial_area"].keys()
|
||||
assert "h" in img_obj["facial_area"].keys()
|
||||
assert "face_confidence" in img_obj.keys()
|
||||
exception_thrown = False
|
||||
except Exception as e:
|
||||
exception_thrown = True
|
||||
|
||||
assert exception_thrown is False
|
||||
|
||||
# -------------------------------------------
|
||||
logger.info("-----------------------------------------")
|
||||
|
||||
logger.info("Extract faces test")
|
||||
|
Loading…
x
Reference in New Issue
Block a user