Пример #1
0
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
Пример #2
0
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
Пример #3
0
    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)
Пример #4
0
    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!')
Пример #5
0
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
Пример #6
0
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