mirror of
https://github.com/serengil/deepface.git
synced 2025-06-07 03:55:21 +00:00
some improvements
- loading image from url was loading as rgb instead of bar - we are returning image name in load image function to throw meaningful message for no face found case - we started to use imread again, and throw exception if file name contains non English character - get rid of the duplicate if statement in extract faces
This commit is contained in:
parent
76a6bce824
commit
2cc5f39853
@ -16,6 +16,8 @@ from deepface.commons.logger import Logger
|
|||||||
|
|
||||||
logger = Logger(module="commons.functions")
|
logger = Logger(module="commons.functions")
|
||||||
|
|
||||||
|
# pylint: disable=no-else-raise
|
||||||
|
|
||||||
# --------------------------------------------------
|
# --------------------------------------------------
|
||||||
# configurations of dependencies
|
# configurations of dependencies
|
||||||
|
|
||||||
@ -73,49 +75,52 @@ def loadBase64Img(uri):
|
|||||||
"""
|
"""
|
||||||
encoded_data = uri.split(",")[1]
|
encoded_data = uri.split(",")[1]
|
||||||
nparr = np.fromstring(base64.b64decode(encoded_data), np.uint8)
|
nparr = np.fromstring(base64.b64decode(encoded_data), np.uint8)
|
||||||
img = cv2.imdecode(nparr, cv2.IMREAD_COLOR)
|
img_bgr = cv2.imdecode(nparr, cv2.IMREAD_COLOR)
|
||||||
return img
|
# img_rgb = cv2.cvtColor(img_bgr, cv2.COLOR_BGR2RGB)
|
||||||
|
return img_bgr
|
||||||
|
|
||||||
|
|
||||||
def load_image(img):
|
def load_image(img):
|
||||||
"""Load image from path, url, base64 or numpy array.
|
"""
|
||||||
|
Load image from path, url, base64 or numpy array.
|
||||||
Args:
|
Args:
|
||||||
img: a path, url, base64 or numpy array.
|
img: a path, url, base64 or numpy array.
|
||||||
|
|
||||||
Raises:
|
|
||||||
ValueError: if the image path does not exist.
|
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
numpy array: the loaded image.
|
image (numpy array): the loaded image in BGR format
|
||||||
|
image name (str): image name itself
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# The image is already a numpy array
|
# The image is already a numpy array
|
||||||
if type(img).__module__ == np.__name__:
|
if type(img).__module__ == np.__name__:
|
||||||
return img
|
return img, None
|
||||||
|
|
||||||
# The image is a base64 string
|
# The image is a base64 string
|
||||||
if img.startswith("data:image/"):
|
if img.startswith("data:image/"):
|
||||||
return loadBase64Img(img)
|
return loadBase64Img(img), None
|
||||||
|
|
||||||
# The image is a url
|
# The image is a url
|
||||||
if img.startswith("http"):
|
if img.startswith("http"):
|
||||||
return np.array(Image.open(requests.get(img, stream=True, timeout=60).raw).convert("RGB"))[
|
return (
|
||||||
:, :, ::-1
|
np.array(Image.open(requests.get(img, stream=True, timeout=60).raw).convert("BGR"))[
|
||||||
]
|
:, :, ::-1
|
||||||
|
],
|
||||||
|
# return url as image name
|
||||||
|
img,
|
||||||
|
)
|
||||||
|
|
||||||
# The image is a path
|
# The image is a path
|
||||||
if os.path.isfile(img) is not True:
|
if os.path.isfile(img) is not True:
|
||||||
raise ValueError(f"Confirm that {img} exists")
|
raise ValueError(f"Confirm that {img} exists")
|
||||||
|
|
||||||
# For reading images with unicode names
|
# image must be a file on the system then
|
||||||
with open(img, "rb") as img_f:
|
|
||||||
chunk = img_f.read()
|
|
||||||
chunk_arr = np.frombuffer(chunk, dtype=np.uint8)
|
|
||||||
img = cv2.imdecode(chunk_arr, cv2.IMREAD_COLOR)
|
|
||||||
return img
|
|
||||||
|
|
||||||
# This causes troubles when reading files with non english names
|
# image name must have english characters
|
||||||
# return cv2.imread(img)
|
if img.isascii() is False:
|
||||||
|
raise ValueError(f"Input image must not have non-english characters - {img}")
|
||||||
|
|
||||||
|
img_obj_bgr = cv2.imread(img)
|
||||||
|
# img_obj_rgb = cv2.cvtColor(img_obj_bgr, cv2.COLOR_BGR2RGB)
|
||||||
|
return img_obj_bgr, img
|
||||||
|
|
||||||
|
|
||||||
# --------------------------------------------------
|
# --------------------------------------------------
|
||||||
@ -152,7 +157,7 @@ def extract_faces(
|
|||||||
extracted_faces = []
|
extracted_faces = []
|
||||||
|
|
||||||
# img might be path, base64 or numpy array. Convert it to numpy whatever it is.
|
# img might be path, base64 or numpy array. Convert it to numpy whatever it is.
|
||||||
img = load_image(img)
|
img, img_name = load_image(img)
|
||||||
img_region = [0, 0, img.shape[1], img.shape[0]]
|
img_region = [0, 0, img.shape[1], img.shape[0]]
|
||||||
|
|
||||||
if detector_backend == "skip":
|
if detector_backend == "skip":
|
||||||
@ -163,10 +168,17 @@ def extract_faces(
|
|||||||
|
|
||||||
# in case of no face found
|
# in case of no face found
|
||||||
if len(face_objs) == 0 and enforce_detection is True:
|
if len(face_objs) == 0 and enforce_detection is True:
|
||||||
raise ValueError(
|
if img_name is not None:
|
||||||
"Face could not be detected. Please confirm that the picture is a face photo "
|
raise ValueError(
|
||||||
+ "or consider to set enforce_detection param to False."
|
f"Face could not be detected in {img_name}."
|
||||||
)
|
"Please confirm that the picture is a face photo "
|
||||||
|
"or consider to set enforce_detection param to False."
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
raise ValueError(
|
||||||
|
"Face could not be detected. Please confirm that the picture is a face photo "
|
||||||
|
"or consider to set enforce_detection param to False."
|
||||||
|
)
|
||||||
|
|
||||||
if len(face_objs) == 0 and enforce_detection is False:
|
if len(face_objs) == 0 and enforce_detection is False:
|
||||||
face_objs = [(img, img_region, 0)]
|
face_objs = [(img, img_region, 0)]
|
||||||
@ -177,39 +189,38 @@ def extract_faces(
|
|||||||
current_img = cv2.cvtColor(current_img, cv2.COLOR_BGR2GRAY)
|
current_img = cv2.cvtColor(current_img, cv2.COLOR_BGR2GRAY)
|
||||||
|
|
||||||
# resize and padding
|
# resize and padding
|
||||||
if current_img.shape[0] > 0 and current_img.shape[1] > 0:
|
factor_0 = target_size[0] / current_img.shape[0]
|
||||||
factor_0 = target_size[0] / current_img.shape[0]
|
factor_1 = target_size[1] / current_img.shape[1]
|
||||||
factor_1 = target_size[1] / current_img.shape[1]
|
factor = min(factor_0, factor_1)
|
||||||
factor = min(factor_0, factor_1)
|
|
||||||
|
|
||||||
dsize = (
|
dsize = (
|
||||||
int(current_img.shape[1] * factor),
|
int(current_img.shape[1] * factor),
|
||||||
int(current_img.shape[0] * factor),
|
int(current_img.shape[0] * factor),
|
||||||
|
)
|
||||||
|
current_img = cv2.resize(current_img, dsize)
|
||||||
|
|
||||||
|
diff_0 = target_size[0] - current_img.shape[0]
|
||||||
|
diff_1 = target_size[1] - current_img.shape[1]
|
||||||
|
if grayscale is False:
|
||||||
|
# Put the base image in the middle of the padded image
|
||||||
|
current_img = np.pad(
|
||||||
|
current_img,
|
||||||
|
(
|
||||||
|
(diff_0 // 2, diff_0 - diff_0 // 2),
|
||||||
|
(diff_1 // 2, diff_1 - diff_1 // 2),
|
||||||
|
(0, 0),
|
||||||
|
),
|
||||||
|
"constant",
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
current_img = np.pad(
|
||||||
|
current_img,
|
||||||
|
(
|
||||||
|
(diff_0 // 2, diff_0 - diff_0 // 2),
|
||||||
|
(diff_1 // 2, diff_1 - diff_1 // 2),
|
||||||
|
),
|
||||||
|
"constant",
|
||||||
)
|
)
|
||||||
current_img = cv2.resize(current_img, dsize)
|
|
||||||
|
|
||||||
diff_0 = target_size[0] - current_img.shape[0]
|
|
||||||
diff_1 = target_size[1] - current_img.shape[1]
|
|
||||||
if grayscale is False:
|
|
||||||
# Put the base image in the middle of the padded image
|
|
||||||
current_img = np.pad(
|
|
||||||
current_img,
|
|
||||||
(
|
|
||||||
(diff_0 // 2, diff_0 - diff_0 // 2),
|
|
||||||
(diff_1 // 2, diff_1 - diff_1 // 2),
|
|
||||||
(0, 0),
|
|
||||||
),
|
|
||||||
"constant",
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
current_img = np.pad(
|
|
||||||
current_img,
|
|
||||||
(
|
|
||||||
(diff_0 // 2, diff_0 - diff_0 // 2),
|
|
||||||
(diff_1 // 2, diff_1 - diff_1 // 2),
|
|
||||||
),
|
|
||||||
"constant",
|
|
||||||
)
|
|
||||||
|
|
||||||
# double check: if target image is not still the same size with target.
|
# double check: if target image is not still the same size with target.
|
||||||
if current_img.shape[0:2] != target_size:
|
if current_img.shape[0:2] != target_size:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user