def run(image_path: str, weights_path: str): face_marker = FaceMarker(weights_path=weights_path) face_aligner = FaceAligner() if path.isdir(image_path): image_paths = list_files(image_path, IMAGE_EXT, recursive=True) if len(image_paths) == 0: raise ValueError(f'No images found in {image_path}.') elif path.isfile(image_path): image_paths = [image_path] else: raise ValueError(f'Input "{image_path}" is not file nor a directory.') logger.info('Starting analysis...') logger.info('Press "space" key to display next result. Press "q" to quit.') images = [] for image_path in image_paths: image_name = path.basename(image_path) image = cv.imread(image_path) if image is None: logger.warn(f'Unable to open image file {image_path}') continue h, w, = image.shape[0:2] logger.info(f'{image_name} loaded. Image size is {w}x{h} pixels.') images.append(image) n_images = len(images) tic = time() marks, scores = face_marker.mark(images) toc = time() logger.info(f'Number of images loaded: {n_images}') logger.info(f'Total processing time: {(toc - tic):.4f} s.') for i in range(n_images): image = images[i] mark = marks[i] score = scores[i] aligned_image, nose_dev = face_aligner.align(image, mark) for point in mark: cv.circle(image, (int(point[0]), int(point[1])), 2, (0, 255, 0), -1) cv.imshow(f'Face {i} (score {score:.3f})', image) title = f'Aligned Face {i} (dev: {nose_dev[0]:.3f}, {nose_dev[1]:.3f})' cv.imshow(title, aligned_image) ret = cv.waitKey() if ret == ord(' '): cv.destroyAllWindows() elif ret == ord('q'): cv.destroyAllWindows() break
def list_images(root_path): if path.isdir(root_path): image_paths = list_files(root_path, IMAGE_EXT, recursive=True) if len(image_paths) == 0: raise ValueError(f'No images found in {root_path}.') elif path.isfile(root_path): image_paths = [root_path] else: raise ValueError(f'Input "{root_path}" is not file nor a directory.') return image_paths
def setUp(self) -> None: detection_min_height = 24 detection_min_score = 0.8 marking_min_score = 0.6 max_frame_size = 1024 store_frames = True align_max_deviation = None detection_face_padding = 0.2 face_detector = FaceDetector( weights_path=DETECTOR_WEIGHTS_PATH, min_height=detection_min_height, min_score=detection_min_score, force_cpu=True ) face_marker: FaceMarker = FaceMarker( weights_path=MARKER_WEIGHTS_PATH, force_cpu=True ) face_aligner = FaceAligner() face_encoder = FaceEncoder( weights_path=ENCODER_WEIGHTS_PATH, force_cpu=True ) self.frame_analyzer = FrameAnalyzer( detector=face_detector, marker=face_marker, aligner=face_aligner, encoder=face_encoder, detection_only=False, max_frame_size=max_frame_size, store_frames=store_frames, max_deviation=align_max_deviation, marking_min_score=marking_min_score, face_padding=detection_face_padding ) self.image_paths = list_files(DATA_DIR, IMAGE_EXT, recursive=True)
def handle(self, *args, **options): images_path = options['src'] image_exts = tuple([ext.strip() for ext in options['exts'].split(',')]) max_subjects = options['count'] if max_subjects <= 0: max_subjects = float('inf') print(f'Listing images from {images_path}...') image_paths = list_files(images_path, image_exts, recursive=True) files_count = len(image_paths) print(f'Found {files_count} images.') print(f'Starting processing images.') root = settings.FACES_IMAGES_PATH max_iter = min(files_count, max_subjects) for index, image_path in enumerate(image_paths): if index >= max_subjects: break image_name = path.basename(image_path) frame_path = create_image(image_path, root, 'frame_') frame = Frame.objects.create(image=frame_path) face_analyzer.analyze_frame(frame.pk) # frame = Frame.objects.get(pk=frame.pk) n_faces = frame.faces.count() if n_faces: face = frame.faces.all()[0] name = path.splitext(image_name)[0] subject_name = ' '.join(name.split('_')[0:-1]) subject = Subject.objects.create(name=subject_name) subject.faces.add(face) if n_faces > 1: warn(f'More than one face detected in "{image_name}".') else: warn(f'No face detected in "{image_name}".') print(f'Progress {(100 * index / max_iter):.1f}%.') print(f'Done!')
def run( image_path: str, detector_weights_path: str, marker_weights_path: str, encoder_weights_path: str, show_scores: bool = False ): from dnfal.vision import FacesVision from dnfal.settings import Settings from dnfal.loggers import logger settings = Settings() settings.detector_weights_path = detector_weights_path settings.marker_weights_path = marker_weights_path settings.encoder_weights_path = encoder_weights_path settings.log_to_console = True settings.detection_min_height = 24 settings.detection_min_score = 0.8 settings.marking_min_score = 0.6 faces_vision = FacesVision(settings) if path.isdir(image_path): image_paths = list_files(image_path, IMAGE_EXT, recursive=True) if len(image_paths) == 0: raise ValueError(f'No images found in {image_path}.') elif path.isfile(image_path): image_paths = [image_path] else: raise ValueError(f'Input "{image_path}" is not file nor a directory.') logger.info('Starting analysis...') logger.info('Press "space" key to display next result. Press "q" to quit.') max_image_size = 1920 drawer = Drawer() drawer.font_scale = 0.7 drawer.font_linewidth = 2 drawer.font_color = (0, 255, 0) for image_path in image_paths: image_name = path.basename(image_path) image = cv.imread(image_path) if image is None: logger.warn(f'Unable to open image file {image_path}') continue h, w, = image.shape[0:2] logger.info(f'{image_name} loaded. Image size is {w}x{h} pixels.') if max(w, h) > max_image_size: image, scale = resize(image, max_image_size) h, w, = image.shape[0:2] logger.info(f'Image resized to {w}x{h} pixels.') tic = time() faces, _ = faces_vision.frame_analyzer.find_faces(image) toc = time() logger.info(f'Found {len(faces)} faces in {(toc - tic):.3f} seconds.') for ind, face in enumerate(faces): face_image = face.image.copy() box = ( int(w * face.box[0]), int(h * face.box[1]), int(w * face.box[2]), int(h * face.box[3]), ) if show_scores: s = (int(100 * face.detect_score), int(100 * face.mark_score)) label = f'Face {ind}, ({s[0]} %, {s[1]} %)' else: label = f'Face {ind}' drawer.draw_labeled_box(image, label, box) for m in face.landmarks: cv.circle(face_image, (m[0], m[1]), 2, (0, 255, 0), -1) nv = face.nose_deviation print( f'Detected face [{ind}]: {{ score: {face.detect_score}, ' f'nose deviation: [{nv[0]:.3f}, {nv[1]:.3f}] }}' ) cv.imshow(f'Face "{ind}"', face_image) cv.imshow(f'Faces in {image_name}', image) ret = cv.waitKey() if ret == ord(' '): cv.destroyAllWindows() elif ret == ord('q'): cv.destroyAllWindows() break
def run(image_path: str, detector_weights_path: str, marker_weights_path: str): from dnfal.amazon.faces import analyze_faces, AwsFace from dnfal.detection import FaceDetector from dnfal.alignment import FaceMarker, FaceAligner from dnfal.engine import FrameAnalyzer from dnfal.loggers import logger, config_logger config_logger(level='info') face_detector = FaceDetector(weights_path=detector_weights_path, min_score=0.9, nms_thresh=0.7) face_marker = FaceMarker(weights_path=marker_weights_path) face_aligner = FaceAligner(out_size=256) frame_analyzer = FrameAnalyzer(detector=face_detector, marker=face_marker, aligner=face_aligner, encoder=None, face_padding=0.4, store_aligned=True) if path.isdir(image_path): image_paths = list_files(image_path, IMAGE_EXT, recursive=True) if len(image_paths) == 0: raise ValueError(f'No images found in {image_path}.') elif path.isfile(image_path): image_paths = [image_path] else: raise ValueError(f'Input "{image_path}" is not file nor a directory.') logger.info('Starting analysis...') logger.info('Press "space" key to display next result. Press "q" to quit.') max_image_size = 1920 drawer = Drawer() drawer.font_scale = 0.5 drawer.font_linewidth = 1 drawer.text_margins = (2, 3, 12, 3) GENDER_LABELS = { AwsFace.GENDER_MAN: 'Man', AwsFace.GENDER_WOMAN: 'Woman', } for image_path in image_paths: image_name = path.basename(image_path) image = cv.imread(image_path) if image is None: logger.warn(f'Unable to open image file {image_path}') continue h, w, = image.shape[0:2] logger.info(f'{image_name} loaded. Image size is {w}x{h} pixels.') if max(w, h) > max_image_size: image, scale = resize(image, max_image_size) h, w, = image.shape[0:2] logger.info(f'Image resized to {w}x{h} pixels.') image = cv.copyMakeBorder(image, left=0, top=100, right=0, bottom=0, borderType=cv.BORDER_CONSTANT, value=(0, 0, 0)) h, w, = image.shape[0:2] tic = time() faces, _ = frame_analyzer.find_faces(image) n_faces = len(faces) toc = time() logger.info(f'Found {n_faces} faces in {(toc - tic):.3f} seconds.') if n_faces: tic = time() aws_faces = analyze_faces([face.image for face in faces]) delay = time() - tic logger.info(f'Faces analyzed in {delay:.3f} seconds.') for ind, face in enumerate(faces): gender_label = 'Unknown gender' age_label = 'Unknown age' aws_face = aws_faces[ind] if aws_face is not None: gender_pred = GENDER_LABELS[aws_face.gender] gender_prob = 100 * aws_face.gender_score age_low = aws_face.age_low age_high = aws_face.age_high gender_label = f'{gender_pred} ({int(gender_prob)}%)' age_label = f'{age_low}-{age_high} years' label = f'{gender_label} \n {age_label}' box = ( int(w * face.box[0]), int(h * face.box[1]), int(w * face.box[2]), int(h * face.box[3]), ) drawer.draw_labeled_box(image, label, box) cv.imshow(f'Faces in {image_name}', image) ret = cv.waitKey() if ret == ord(' '): cv.destroyAllWindows() elif ret == ord('q'): cv.destroyAllWindows() break