From 15b4c83514b9daacc7b05496fae920f491e08aa1 Mon Sep 17 00:00:00 2001 From: Xulang Guan Date: Sun, 9 Feb 2025 02:05:34 -0800 Subject: [PATCH 1/4] Handled cases when no landmark in some of the frame in videos. --- .gitignore | 3 +++ libreface/detect_mediapipe_image.py | 21 +++++++++++++++++---- requirements_new.txt | 2 +- test_libreface.py | 10 +++++----- 4 files changed, 26 insertions(+), 10 deletions(-) diff --git a/.gitignore b/.gitignore index bf3768b..96d5446 100644 --- a/.gitignore +++ b/.gitignore @@ -22,5 +22,8 @@ libreface/Facial_Expression_Recognition/weights/ weights_libreface/ build/ dist/ +temp/ +test_issue11.py +/data *.egg-info/* *.DS_Store \ No newline at end of file diff --git a/libreface/detect_mediapipe_image.py b/libreface/detect_mediapipe_image.py index f6fcaf1..13cb67a 100644 --- a/libreface/detect_mediapipe_image.py +++ b/libreface/detect_mediapipe_image.py @@ -205,7 +205,8 @@ def get_aligned_image(image_path, temp_dir = "./tmp", verbose=False): # Draw face landmarks of each face. # print(f'Face landmarks of {name}:') if not results.multi_face_landmarks: - print("Processing landmarks did not result on anything...") + raise RuntimeError(f"No face landmarks") + # print("Processing landmarks did not result on anything...") img_h, img_w, img_c = image.shape face_3d = [] face_2d = [] @@ -348,12 +349,24 @@ def get_aligned_video_frames(frames_df, temp_dir="./tmp"): aligned_frames_paths = [] head_pose_list = [] landmark_list = [] - for _, row in tqdm(frames_df.iterrows(), desc="Aligning face for video frames..."): - aligned_image_path, head_pose, landmark_dict = get_aligned_image(row["path_to_frame"], temp_dir) + #track the errored frames + indexes_to_drop = [] + for index, row in tqdm(frames_df.iterrows(), desc="Aligning face for video frames..."): + try: + aligned_image_path, head_pose, landmark_dict = get_aligned_image(row["path_to_frame"], temp_dir) + except Exception as e: + indexes_to_drop.append(index) + continue aligned_frames_paths.append(aligned_image_path) head_pose_list.append(head_pose) landmark_list.append(landmark_dict) - + #drop all the errored frames + frames_df.drop(index=indexes_to_drop,inplace=True) + frames_df.reset_index(drop=True, inplace=True) + if len(indexes_to_drop)!=0 : + print(f"Dropped {len(indexes_to_drop)} frames because no landmarks detected by mediapipe.") + if frames_df.empty: + print("Can't detect any face landmarks in the provided video") return aligned_frames_paths, head_pose_list, landmark_list if __name__ == "__main__": diff --git a/requirements_new.txt b/requirements_new.txt index b77a9d2..6a9384d 100644 --- a/requirements_new.txt +++ b/requirements_new.txt @@ -5,7 +5,7 @@ gdown==5.2.0 importlib-metadata==8.4.0 importlib-resources==6.4.5 imutils==0.5.4 -mediapipe==0.9.3 +mediapipe==0.10.5 oauthlib>=3.0.0 opencv-python==4.10.0.84 pandas==2.0.3 diff --git a/test_libreface.py b/test_libreface.py index 5ff9b95..f5d446f 100644 --- a/test_libreface.py +++ b/test_libreface.py @@ -2,29 +2,29 @@ import time # inference on single image and store results to a variable -detected_facial_attributes = libreface.get_facial_attributes_image(image_path = "sample_disfa.png", +detected_facial_attributes = libreface.get_facial_attributes_image(image_path = "examples/sample_disfa.png", temp_dir = "./temp", device = "cpu") # inference on a single image and save results in a csv file -libreface.save_facial_attributes_image(image_path = "sample_disfa.png", +libreface.save_facial_attributes_image(image_path = "examples/sample_disfa.png", output_save_path = "sample_image_results.csv", temp_dir = "./temp", device = "cpu") # inference on a video and store the results to a pandas dataframe -detected_facial_attributes_df = libreface.get_facial_attributes_video(video_path = "sample_disfa.avi", +detected_facial_attributes_df = libreface.get_facial_attributes_video(video_path = "examples/sample_disfa.avi", temp_dir = "./temp", device = "cpu") # ## inference on a video and save the results framewise in a csv file -libreface.save_facial_attributes_video(video_path = "sample_disfa.avi", +libreface.save_facial_attributes_video(video_path = "examples/sample_disfa.avi", output_save_path = "sample_video_results.csv", temp_dir = "./temp", device = "cpu") ## inference on any image or video type and store results accordingly to a variable or save results -detected_facial_attributes = libreface.get_facial_attributes(file_path = "sample_disfa.avi", +detected_facial_attributes = libreface.get_facial_attributes(file_path = "examples/sample_disfa.avi", output_save_path = "sample_results.csv", temp_dir = "./temp", device = "cpu") \ No newline at end of file From 73eeb9fa8ca32a8f1ee731168b8ca03d93261021 Mon Sep 17 00:00:00 2001 From: xulanggu Date: Mon, 24 Feb 2025 01:47:39 -0800 Subject: [PATCH 2/4] libreface0.0.26 testversion --- .gitignore | 2 ++ README_pypi.rst | 8 ++++---- libreface/__init__.py | 22 +++++++++++++++------- libreface/detect_mediapipe_image.py | 4 ++-- setup.py | 12 +++++++----- 5 files changed, 30 insertions(+), 18 deletions(-) diff --git a/.gitignore b/.gitignore index 96d5446..6413b45 100644 --- a/.gitignore +++ b/.gitignore @@ -23,6 +23,8 @@ weights_libreface/ build/ dist/ temp/ +tmp/ +test_instruction.txt test_issue11.py /data *.egg-info/* diff --git a/README_pypi.rst b/README_pypi.rst index 1229413..ee33725 100644 --- a/README_pypi.rst +++ b/README_pypi.rst @@ -13,7 +13,7 @@ Libreface :alt: Static Badge -.. |badge2| image:: https://img.shields.io/badge/python-%3D%3D3.8-green +.. |badge2| image:: https://img.shields.io/badge/python-%3D%3D3.9-green :alt: Static Badge @@ -29,7 +29,7 @@ We conduct extensive experiments of pre-training and distillation to demonstrate Dependencies ============ -- Python 3.8 +- Python 3.9 - You should have `cmake` installed in your system. - **For Linux users** - :code:`sudo apt-get install cmake`. If you run into trouble, consider upgrading to the latest version (`instructions`_). - **For Mac users** - :code:`brew install cmake`. @@ -39,11 +39,11 @@ Dependencies Installation ============ -You can first create a new Python 3.8 environment using `conda` and then install this package using `pip` from the PyPI hub: +You can first create a new Python 3.9 environment using `conda` and then install this package using `pip` from the PyPI hub: .. code-block:: bash - conda create -n libreface_env python=3.8 + conda create -n libreface_env python=3.9 conda activate libreface_env pip install --upgrade libreface diff --git a/libreface/__init__.py b/libreface/__init__.py index 82ecc4c..a463340 100644 --- a/libreface/__init__.py +++ b/libreface/__init__.py @@ -68,6 +68,8 @@ def get_facial_attributes_video(video_path, cur_video_name = ".".join(video_path.split("/")[-1].split(".")[:-1]) aligned_frames_path_list, headpose_list, landmarks_3d_list = get_aligned_video_frames(frames_df, temp_dir=os.path.join(temp_dir, cur_video_name)) # frames_df["aligned_frame_path"] = aligned_frames_path_list + if frames_df.empty: + raise RuntimeError(f"No face detected in the video, get_facial_attributes fails.") frames_df = frames_df.drop("path_to_frame", axis=1) frames_df["headpose"] = headpose_list frames_df["landmarks_3d"] = landmarks_3d_list @@ -118,13 +120,19 @@ def save_facial_attributes_video(video_path, batch_size = 256, num_workers = 2, weights_download_dir:str = "./weights_libreface"): - frames_df = get_facial_attributes_video(video_path, - model_choice=model_choice, - temp_dir=temp_dir, - device=device, - batch_size=batch_size, - num_workers=num_workers, - weights_download_dir=weights_download_dir) + try: + frames_df = get_facial_attributes_video(video_path, + model_choice=model_choice, + temp_dir=temp_dir, + device=device, + batch_size=batch_size, + num_workers=num_workers, + weights_download_dir=weights_download_dir) + + except Exception as e: + print(e) + print(f"Since no face is detected, can't save the file") + return False save_path = uniquify_file(output_save_path) frames_df.to_csv(save_path, index=False) print(f"Facial attributes of the video saved to {save_path}") diff --git a/libreface/detect_mediapipe_image.py b/libreface/detect_mediapipe_image.py index 13cb67a..60a052c 100644 --- a/libreface/detect_mediapipe_image.py +++ b/libreface/detect_mediapipe_image.py @@ -364,9 +364,9 @@ def get_aligned_video_frames(frames_df, temp_dir="./tmp"): frames_df.drop(index=indexes_to_drop,inplace=True) frames_df.reset_index(drop=True, inplace=True) if len(indexes_to_drop)!=0 : - print(f"Dropped {len(indexes_to_drop)} frames because no landmarks detected by mediapipe.") + print(f"Dropped {len(indexes_to_drop)} frames because no landmarks detected by mediapipe in the frame.") if frames_df.empty: - print("Can't detect any face landmarks in the provided video") + print("No face detected in the provided video") return aligned_frames_paths, head_pose_list, landmark_list if __name__ == "__main__": diff --git a/setup.py b/setup.py index 4eaef60..77c7fde 100644 --- a/setup.py +++ b/setup.py @@ -14,7 +14,7 @@ URL = 'https://boese0601.github.io/libreface' EMAIL = 'achaubey@usc.edu' AUTHOR = 'IHP-Lab' -REQUIRES_PYTHON = '>=3.8' +REQUIRES_PYTHON = '>=3.9' # What packages are required for this module to be executed? @@ -52,7 +52,7 @@ def list_reqs(fname='requirements_new.txt'): # with open(PACKAGE_DIR / 'VERSION') as f: # _version = f.read().strip() -about['__version__'] = "0.0.19" +about['__version__'] = "0.0.26" # Where the magic happens: @@ -60,7 +60,7 @@ def list_reqs(fname='requirements_new.txt'): name=NAME, version=about['__version__'], description='LibreFace model for facial analysis', - long_descripation_content_type='text/x-rst', + long_description_content_type='text/x-rst', long_description=long_description, author=AUTHOR, author_email=EMAIL, @@ -73,14 +73,16 @@ def list_reqs(fname='requirements_new.txt'): include_package_data=True, license=license, entry_points={ - 'console_scripts': 'libreface=libreface.commandline:main_func' + 'console_scripts': [ + 'libreface=libreface.commandline:main_func' + ] }, classifiers=[ # Trove classifiers # Full list: https://pypi.python.org/pypi?%3Aaction=list_classifiers 'Programming Language :: Python', 'Programming Language :: Python :: 3', - 'Programming Language :: Python :: 3.8', + 'Programming Language :: Python :: 3.9', 'Programming Language :: Python :: Implementation :: CPython', 'Programming Language :: Python :: Implementation :: PyPy' ], From 93ad6c42760cc4dda9fc47457b152d28e546f381 Mon Sep 17 00:00:00 2001 From: xulanggu Date: Mon, 31 Mar 2025 21:27:14 -0700 Subject: [PATCH 3/4] Chage version --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 77c7fde..ec10caf 100644 --- a/setup.py +++ b/setup.py @@ -52,7 +52,7 @@ def list_reqs(fname='requirements_new.txt'): # with open(PACKAGE_DIR / 'VERSION') as f: # _version = f.read().strip() -about['__version__'] = "0.0.26" +about['__version__'] = "0.1.1" # Where the magic happens: From 8441b973db6234a31c280b841d07fa060c7d67e8 Mon Sep 17 00:00:00 2001 From: xulanggu Date: Tue, 1 Apr 2025 15:08:12 -0700 Subject: [PATCH 4/4] Update README --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 72858ff..5cb8912 100644 --- a/README.md +++ b/README.md @@ -41,7 +41,7 @@ This is the official implementation of our WACV 2024 Application Track paper: Li ### Dependencies -- Python 3.8 +- Python 3.9 - You should have `cmake` installed in your system. - **For Linux users** - `sudo apt-get install cmake`. If you run into trouble, consider upgrading to the latest version ([instructions](https://askubuntu.com/questions/355565/how-do-i-install-the-latest-version-of-cmake-from-the-command-line)). - **For Mac users** - `brew install cmake`. @@ -49,10 +49,10 @@ This is the official implementation of our WACV 2024 Application Track paper: Li ### Installation -You can first create a new Python 3.8 environment using `conda` and then install this package using `pip` from the PyPI hub: +You can first create a new Python 3.9 environment using `conda` and then install this package using `pip` from the PyPI hub: ```console -conda create -n libreface_env python=3.8 +conda create -n libreface_env python=3.9 conda activate libreface_env pip install --upgrade libreface ```