-
Notifications
You must be signed in to change notification settings - Fork 0
Fixes/multi anonymization #2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,49 @@ | ||
| import argparse | ||
| import logging | ||
|
|
||
| import cv2 | ||
| import supervision as sv | ||
|
|
||
| from model_face.detector.yolov8_face_detector import YOLOv8FaceDetection | ||
|
|
||
| logger = logging.getLogger(__name__) | ||
|
|
||
|
|
||
| def configure_logging() -> None: | ||
| """Configure logging for the application.""" | ||
| logging.basicConfig( | ||
| level=logging.INFO, | ||
| format="%(asctime)s - %(name)s - %(levelname)s - %(message)s", | ||
| ) | ||
|
|
||
|
|
||
| def main_detect() -> None: | ||
| parser = argparse.ArgumentParser() | ||
| parser.add_argument("--imgpath", type=str, default="images/1.jpg", help="image path") | ||
| parser.add_argument( | ||
| "--modelpath", | ||
| type=str, | ||
| default="zoo/yolov8n-face.onnx", | ||
| help="onnx filepath", | ||
| ) | ||
| parser.add_argument("--confThreshold", default=0.20, type=float, help="class confidence") | ||
| parser.add_argument("--nmsThreshold", default=0.40, type=float, help="nms iou thresh") | ||
| args = parser.parse_args() | ||
|
|
||
| # Initialize YOLOv8_face object detector | ||
| source = cv2.imread(args.imgpath) | ||
|
|
||
| # Detect Objects | ||
| detector = YOLOv8FaceDetection(args.modelpath, conf_thres=args.confThreshold, iou_thres=args.nmsThreshold) | ||
| detections = detector.detect(source) | ||
|
|
||
| # Draw detections | ||
| annotated = source.copy() | ||
| annotator = sv.BoxAnnotator() | ||
| scene = annotator.annotate(scene=annotated, detections=detections) | ||
| cv2.imshow("YOLOv8 Face Detection", scene) | ||
| cv2.waitKey(0) | ||
|
|
||
|
|
||
| if __name__ == "__main__": | ||
| main_detect() |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,128 @@ | ||
| import argparse | ||
| import logging | ||
| import os | ||
| from typing import Any | ||
|
|
||
| import cv2 | ||
| import supervision as sv | ||
| from tqdm import tqdm # type: ignore | ||
| from yaya_tools.helpers.dataset import load_directory_images_annotatations # type: ignore | ||
|
|
||
| from model_face.detector.yolov8_face_detector import YOLOv8FaceDetection | ||
| from model_face.helpers.transformations import blur_box # type: ignore | ||
|
|
||
| logger = logging.getLogger(__name__) | ||
|
|
||
|
|
||
| def anonymize_file(detector: YOLOv8FaceDetection, image_name: str, source_directory: str) -> tuple[str, bool]: | ||
| """Anonymize an image by detecting faces and applying a blur to the detected regions.""" | ||
| try: | ||
| source_path = os.path.join(source_directory, image_name) | ||
| image = cv2.imread(source_path) | ||
| if image is None: | ||
| logger.error(f"Could not read image {image_name}") | ||
| return image_name, False | ||
|
|
||
| detections = detector.detect(image) | ||
|
|
||
| # Logging : How many faces detected | ||
| if detections == sv.Detections.empty(): | ||
| logger.info("No faces on %s image.", image_name) | ||
| else: | ||
| logger.info( | ||
| "Detected %u faces inside %s image. Average conf %2.2f.", | ||
| len(detections), | ||
| image_name, | ||
| detections.confidence.mean(), # type: ignore | ||
| ) | ||
|
|
||
| # Anonymize | ||
| anonymized_im = image | ||
| for xyxy in detections.xyxy: | ||
| anonymized_im = blur_box(image=anonymized_im, box=xyxy) | ||
|
|
||
| # Save : Only if inplace is set and found faces | ||
| if detections != sv.Detections.empty(): | ||
| cv2.imwrite(source_path, anonymized_im) | ||
| logger.info(f"Saved anonymized image to {source_path}") | ||
|
|
||
| return image_name, True | ||
|
|
||
| except Exception as e: | ||
| logger.error(f"Error anonymizing image {image_name}: {e}") | ||
| return image_name, False | ||
|
|
||
|
|
||
| def multiprocess_anonymize( | ||
| detector: YOLOv8FaceDetection, | ||
| source_directory: str, | ||
| images_names: list[str], | ||
| pool_size: int = 5, | ||
| ) -> tuple[list[str], list[str]]: | ||
| """ | ||
| Anonymizes images using a single loop instead of multiprocessing, | ||
| since the detector object cannot be pickled. | ||
| """ | ||
| sucess_files: list[str] = [] | ||
| failed_files: list[str] = [] | ||
| for image_name in tqdm(images_names, desc="Anonymizing images"): | ||
| result = anonymize_file(detector, image_name, source_directory) | ||
| if result[1]: | ||
| sucess_files.append(image_name) | ||
| else: | ||
| failed_files.append(image_name) | ||
|
|
||
| return sucess_files, failed_files | ||
|
|
||
|
|
||
| def configure_logging() -> None: | ||
| """Configure logging for the application.""" | ||
| logging.basicConfig( | ||
| level=logging.INFO, | ||
| format="%(asctime)s - %(name)s - %(levelname)s - %(message)s", | ||
| ) | ||
|
|
||
|
|
||
| def main_anonymize() -> None: | ||
| """Main function to run the detection.""" | ||
| # Configure logging | ||
| configure_logging() | ||
|
|
||
| parser = argparse.ArgumentParser() | ||
| parser.add_argument("--images", type=str, default="images/", help="Directory of images to anonymize in place") | ||
| parser.add_argument( | ||
| "--modelpath", | ||
| type=str, | ||
| default="zoo/yolov8n-face.onnx", | ||
| help="onnx filepath", | ||
| ) | ||
| parser.add_argument("--confThreshold", default=0.10, type=float, help="class confidence") | ||
| parser.add_argument("--nmsThreshold", default=0.40, type=float, help="nms iou thresh") | ||
| parser.add_argument("--pixelate", action="store_true", help="pixelate the face instead of blurring") | ||
| parser.add_argument("--padding", default=5, type=int, help="Bounding box padding size in px") | ||
| args = parser.parse_args() | ||
|
|
||
| # Initialize YOLOv8_face object detector | ||
| images_annotated: dict[str, Any] = load_directory_images_annotatations(args.images) | ||
|
|
||
| # Detector : Create | ||
| detector = YOLOv8FaceDetection( | ||
| args.modelpath, | ||
| conf_thres=args.confThreshold, | ||
| iou_thres=args.nmsThreshold, | ||
| padding=args.padding, | ||
| ) | ||
|
|
||
| # Multiprocess : Anonymize | ||
| logger.info("Anonymizing images...") | ||
| sucess_files, failed_files = multiprocess_anonymize( | ||
| detector=detector, | ||
| source_directory=args.images, | ||
| images_names=list(images_annotated.keys()), | ||
| pool_size=5, | ||
| ) | ||
| logger.info("Anonymization completed.") | ||
|
|
||
|
|
||
| if __name__ == "__main__": | ||
| main_anonymize() |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.