mirror of
https://github.com/serengil/deepface.git
synced 2025-06-07 12:05:22 +00:00
Merge remote-tracking branch 'origin/master' into patch/adjustment-0103-1
This commit is contained in:
commit
e668cd415e
19
README.md
19
README.md
@ -16,6 +16,9 @@
|
|||||||
[](https://github.com/sponsors/serengil)
|
[](https://github.com/sponsors/serengil)
|
||||||
[](https://buymeacoffee.com/serengil)
|
[](https://buymeacoffee.com/serengil)
|
||||||
|
|
||||||
|
[](https://news.ycombinator.com/item?id=42584896)
|
||||||
|
[](https://www.producthunt.com/posts/deepface?embed=true&utm_source=badge-featured&utm_medium=badge&utm_souce=badge-deepface)
|
||||||
|
|
||||||
<!-- [](https://doi.org/10.1109/ICEET53442.2021.9659697) -->
|
<!-- [](https://doi.org/10.1109/ICEET53442.2021.9659697) -->
|
||||||
<!-- [](https://doi.org/10.1109/ASYU50717.2020.9259802) -->
|
<!-- [](https://doi.org/10.1109/ASYU50717.2020.9259802) -->
|
||||||
|
|
||||||
@ -392,7 +395,7 @@ Before creating a PR, you should run the unit tests and linting locally by runni
|
|||||||
|
|
||||||
There are many ways to support a project - starring⭐️ the GitHub repo is just one 🙏
|
There are many ways to support a project - starring⭐️ the GitHub repo is just one 🙏
|
||||||
|
|
||||||
If you do like this work, then you can support it financially on [Patreon](https://www.patreon.com/serengil?repo=deepface), [GitHub Sponsors](https://github.com/sponsors/serengil) or [Buy Me a Coffee](https://buymeacoffee.com/serengil).
|
If you do like this work, then you can support it financially on [Patreon](https://www.patreon.com/serengil?repo=deepface), [GitHub Sponsors](https://github.com/sponsors/serengil) or [Buy Me a Coffee](https://buymeacoffee.com/serengil). Also, your company's logo will be shown on README on GitHub and PyPI if you become a sponsor in gold, silver or bronze tiers.
|
||||||
|
|
||||||
<a href="https://www.patreon.com/serengil?repo=deepface">
|
<a href="https://www.patreon.com/serengil?repo=deepface">
|
||||||
<img src="https://raw.githubusercontent.com/serengil/deepface/master/icon/patreon.png" width="30%" height="30%">
|
<img src="https://raw.githubusercontent.com/serengil/deepface/master/icon/patreon.png" width="30%" height="30%">
|
||||||
@ -402,7 +405,19 @@ If you do like this work, then you can support it financially on [Patreon](https
|
|||||||
<img src="https://raw.githubusercontent.com/serengil/deepface/master/icon/bmc-button.png" width="25%" height="25%">
|
<img src="https://raw.githubusercontent.com/serengil/deepface/master/icon/bmc-button.png" width="25%" height="25%">
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
Also, your company's logo will be shown on README on GitHub and PyPI if you become a sponsor in gold, silver or bronze tiers.
|
Additionally, you can help us reach a wider audience by upvoting our posts on Hacker News and Product Hunt.
|
||||||
|
|
||||||
|
<div style="display: flex; align-items: center; gap: 10px;">
|
||||||
|
<!-- Hacker News Badge -->
|
||||||
|
<a href="https://news.ycombinator.com/item?id=42584896">
|
||||||
|
<img src="https://hackerbadge.vercel.app/api?id=42584896&type=orange" style="width: 250px; height: 54px;" width="250" alt="Featured on Hacker News">
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<!-- Product Hunt Badge -->
|
||||||
|
<a href="https://www.producthunt.com/posts/deepface?embed=true&utm_source=badge-featured&utm_medium=badge&utm_souce=badge-deepface" target="_blank">
|
||||||
|
<img src="https://api.producthunt.com/widgets/embed-image/v1/featured.svg?post_id=753599&theme=light" alt="DeepFace - A Lightweight Deep Face Recognition Library for Python | Product Hunt" style="width: 250px; height: 54px;" width="250" height="54" />
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
## Citation
|
## Citation
|
||||||
|
|
||||||
|
@ -450,6 +450,7 @@ def stream(
|
|||||||
time_threshold: int = 5,
|
time_threshold: int = 5,
|
||||||
frame_threshold: int = 5,
|
frame_threshold: int = 5,
|
||||||
anti_spoofing: bool = False,
|
anti_spoofing: bool = False,
|
||||||
|
output_path: Optional[str] = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""
|
"""
|
||||||
Run real time face recognition and facial attribute analysis
|
Run real time face recognition and facial attribute analysis
|
||||||
@ -478,6 +479,10 @@ def stream(
|
|||||||
frame_threshold (int): The frame threshold for face recognition (default is 5).
|
frame_threshold (int): The frame threshold for face recognition (default is 5).
|
||||||
|
|
||||||
anti_spoofing (boolean): Flag to enable anti spoofing (default is False).
|
anti_spoofing (boolean): Flag to enable anti spoofing (default is False).
|
||||||
|
|
||||||
|
output_path (str): Path to save the output video. (default is None
|
||||||
|
If None, no video is saved).
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
None
|
None
|
||||||
"""
|
"""
|
||||||
@ -495,6 +500,7 @@ def stream(
|
|||||||
time_threshold=time_threshold,
|
time_threshold=time_threshold,
|
||||||
frame_threshold=frame_threshold,
|
frame_threshold=frame_threshold,
|
||||||
anti_spoofing=anti_spoofing,
|
anti_spoofing=anti_spoofing,
|
||||||
|
output_path=output_path,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -149,7 +149,7 @@ def find(
|
|||||||
# Ensure the proper pickle file exists
|
# Ensure the proper pickle file exists
|
||||||
if not os.path.exists(datastore_path):
|
if not os.path.exists(datastore_path):
|
||||||
with open(datastore_path, "wb") as f:
|
with open(datastore_path, "wb") as f:
|
||||||
pickle.dump([], f)
|
pickle.dump([], f, pickle.HIGHEST_PROTOCOL)
|
||||||
|
|
||||||
# Load the representations from the pickle file
|
# Load the representations from the pickle file
|
||||||
with open(datastore_path, "rb") as f:
|
with open(datastore_path, "rb") as f:
|
||||||
@ -232,7 +232,7 @@ def find(
|
|||||||
|
|
||||||
if must_save_pickle:
|
if must_save_pickle:
|
||||||
with open(datastore_path, "wb") as f:
|
with open(datastore_path, "wb") as f:
|
||||||
pickle.dump(representations, f)
|
pickle.dump(representations, f, pickle.HIGHEST_PROTOCOL)
|
||||||
if not silent:
|
if not silent:
|
||||||
logger.info(f"There are now {len(representations)} representations in {file_name}")
|
logger.info(f"There are now {len(representations)} representations in {file_name}")
|
||||||
|
|
||||||
|
@ -22,6 +22,7 @@ os.environ["TF_CPP_MIN_LOG_LEVEL"] = "2"
|
|||||||
IDENTIFIED_IMG_SIZE = 112
|
IDENTIFIED_IMG_SIZE = 112
|
||||||
TEXT_COLOR = (255, 255, 255)
|
TEXT_COLOR = (255, 255, 255)
|
||||||
|
|
||||||
|
|
||||||
# pylint: disable=unused-variable
|
# pylint: disable=unused-variable
|
||||||
def analysis(
|
def analysis(
|
||||||
db_path: str,
|
db_path: str,
|
||||||
@ -33,6 +34,7 @@ def analysis(
|
|||||||
time_threshold=5,
|
time_threshold=5,
|
||||||
frame_threshold=5,
|
frame_threshold=5,
|
||||||
anti_spoofing: bool = False,
|
anti_spoofing: bool = False,
|
||||||
|
output_path: Optional[str] = None,
|
||||||
):
|
):
|
||||||
"""
|
"""
|
||||||
Run real time face recognition and facial attribute analysis
|
Run real time face recognition and facial attribute analysis
|
||||||
@ -62,6 +64,8 @@ def analysis(
|
|||||||
|
|
||||||
anti_spoofing (boolean): Flag to enable anti spoofing (default is False).
|
anti_spoofing (boolean): Flag to enable anti spoofing (default is False).
|
||||||
|
|
||||||
|
output_path (str): Path to save the output video. (default is None
|
||||||
|
If None, no video is saved).
|
||||||
Returns:
|
Returns:
|
||||||
None
|
None
|
||||||
"""
|
"""
|
||||||
@ -77,12 +81,31 @@ def analysis(
|
|||||||
model_name=model_name,
|
model_name=model_name,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
cap = cv2.VideoCapture(source if isinstance(source, str) else int(source))
|
||||||
|
if not cap.isOpened():
|
||||||
|
logger.error(f"Cannot open video source: {source}")
|
||||||
|
return
|
||||||
|
|
||||||
|
# Get video properties
|
||||||
|
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
|
||||||
|
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
|
||||||
|
fps = cap.get(cv2.CAP_PROP_FPS)
|
||||||
|
fourcc = cv2.VideoWriter_fourcc(*"mp4v") # Codec for output file
|
||||||
|
# Ensure the output directory exists if output_path is provided
|
||||||
|
if output_path:
|
||||||
|
os.makedirs(os.path.dirname(output_path), exist_ok=True)
|
||||||
|
# Initialize video writer if output_path is provided
|
||||||
|
video_writer = (
|
||||||
|
cv2.VideoWriter(output_path, cv2.VideoWriter_fourcc(*"mp4v"), fps, (width, height))
|
||||||
|
if output_path
|
||||||
|
else None
|
||||||
|
)
|
||||||
|
|
||||||
freezed_img = None
|
freezed_img = None
|
||||||
freeze = False
|
freeze = False
|
||||||
num_frames_with_faces = 0
|
num_frames_with_faces = 0
|
||||||
tic = time.time()
|
tic = time.time()
|
||||||
|
|
||||||
cap = cv2.VideoCapture(source) # webcam
|
|
||||||
while True:
|
while True:
|
||||||
has_frame, img = cap.read()
|
has_frame, img = cap.read()
|
||||||
if not has_frame:
|
if not has_frame:
|
||||||
@ -91,9 +114,9 @@ def analysis(
|
|||||||
# we are adding some figures into img such as identified facial image, age, gender
|
# we are adding some figures into img such as identified facial image, age, gender
|
||||||
# that is why, we need raw image itself to make analysis
|
# that is why, we need raw image itself to make analysis
|
||||||
raw_img = img.copy()
|
raw_img = img.copy()
|
||||||
|
|
||||||
faces_coordinates = []
|
faces_coordinates = []
|
||||||
if freeze is False:
|
|
||||||
|
if not freeze:
|
||||||
faces_coordinates = grab_facial_areas(
|
faces_coordinates = grab_facial_areas(
|
||||||
img=img, detector_backend=detector_backend, anti_spoofing=anti_spoofing
|
img=img, detector_backend=detector_backend, anti_spoofing=anti_spoofing
|
||||||
)
|
)
|
||||||
@ -101,7 +124,6 @@ def analysis(
|
|||||||
# we will pass img to analyze modules (identity, demography) and add some illustrations
|
# we will pass img to analyze modules (identity, demography) and add some illustrations
|
||||||
# that is why, we will not be able to extract detected face from img clearly
|
# that is why, we will not be able to extract detected face from img clearly
|
||||||
detected_faces = extract_facial_areas(img=img, faces_coordinates=faces_coordinates)
|
detected_faces = extract_facial_areas(img=img, faces_coordinates=faces_coordinates)
|
||||||
|
|
||||||
img = highlight_facial_areas(img=img, faces_coordinates=faces_coordinates)
|
img = highlight_facial_areas(img=img, faces_coordinates=faces_coordinates)
|
||||||
img = countdown_to_freeze(
|
img = countdown_to_freeze(
|
||||||
img=img,
|
img=img,
|
||||||
@ -111,8 +133,8 @@ def analysis(
|
|||||||
)
|
)
|
||||||
|
|
||||||
num_frames_with_faces = num_frames_with_faces + 1 if len(faces_coordinates) else 0
|
num_frames_with_faces = num_frames_with_faces + 1 if len(faces_coordinates) else 0
|
||||||
|
|
||||||
freeze = num_frames_with_faces > 0 and num_frames_with_faces % frame_threshold == 0
|
freeze = num_frames_with_faces > 0 and num_frames_with_faces % frame_threshold == 0
|
||||||
|
|
||||||
if freeze:
|
if freeze:
|
||||||
# add analyze results into img - derive from raw_img
|
# add analyze results into img - derive from raw_img
|
||||||
img = highlight_facial_areas(
|
img = highlight_facial_areas(
|
||||||
@ -144,22 +166,28 @@ def analysis(
|
|||||||
tic = time.time()
|
tic = time.time()
|
||||||
logger.info("freezed")
|
logger.info("freezed")
|
||||||
|
|
||||||
elif freeze is True and time.time() - tic > time_threshold:
|
elif freeze and time.time() - tic > time_threshold:
|
||||||
freeze = False
|
freeze = False
|
||||||
freezed_img = None
|
freezed_img = None
|
||||||
# reset counter for freezing
|
# reset counter for freezing
|
||||||
tic = time.time()
|
tic = time.time()
|
||||||
logger.info("freeze released")
|
logger.info("Freeze released")
|
||||||
|
|
||||||
freezed_img = countdown_to_release(img=freezed_img, tic=tic, time_threshold=time_threshold)
|
freezed_img = countdown_to_release(img=freezed_img, tic=tic, time_threshold=time_threshold)
|
||||||
|
display_img = img if freezed_img is None else freezed_img
|
||||||
|
|
||||||
cv2.imshow("img", img if freezed_img is None else freezed_img)
|
# Save the frame to output video if writer is initialized
|
||||||
|
if video_writer:
|
||||||
|
video_writer.write(display_img)
|
||||||
|
|
||||||
if cv2.waitKey(1) & 0xFF == ord("q"): # press q to quit
|
cv2.imshow("img", display_img)
|
||||||
|
if cv2.waitKey(1) & 0xFF == ord("q"):
|
||||||
break
|
break
|
||||||
|
|
||||||
# kill open cv things
|
# Release resources
|
||||||
cap.release()
|
cap.release()
|
||||||
|
if video_writer:
|
||||||
|
video_writer.release()
|
||||||
cv2.destroyAllWindows()
|
cv2.destroyAllWindows()
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user