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 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
def run(image_path: str, weights_path: str): config_logger(level='DEBUG', to_console=True) person_detector = PersonDetector(weights_path=weights_path, resize_height=192) images_paths = list_images(image_path) 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 for image_path in images_paths: image_name = path.basename(image_path) logger.info(f'Analyzing image {image_name}...') 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 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() boxes, scores = person_detector.detect(image) toc = time() logger.info(f'Found {len(boxes)} persons in {(toc - tic):.3f} s.') for ind, box in enumerate(boxes): drawer.draw_labeled_box(image, f'{int(100*scores[ind])}%', box) 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, output_path: str, weights_path: str): config_logger(level='DEBUG', to_console=True) person_encoder = PersonEncoder(weights_path=weights_path) images_paths = list_images(image_path) logger.info('Starting analysis...') logger.info('Press "space" key to display next result. Press "q" to quit.') drawer = Drawer() drawer.font_scale = 0.5 drawer.font_linewidth = 1 images = [] for image_path in images_paths: image_name = path.basename(image_path) logger.info(f'Reading image {image_name}...') 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 loaded. Image size is {w}x{h} pixels.') images.append(image) logger.info(f'Starting encoding images...') tic = time() embeddings = person_encoder.encode(images) toc = time() logger.info(f'Encoding {len(images)} images took {(toc - tic):.3f} s.') score_matrix = np.matmul(embeddings, embeddings.T) logger.info(f'Building matching results image...') n_images = len(images) grid_width = (n_images + 1) * (SHOW_WIDTH + SHOW_MARGIN[0]) + SHOW_MARGIN[0] grid_height = (n_images + 1) * (SHOW_HEIGHT + SHOW_MARGIN[1]) + SHOW_MARGIN[1] show_grid = np.zeros((grid_height, grid_width, 3), dtype=np.uint8) y = SHOW_MARGIN[1] for i in range(n_images): x = SHOW_MARGIN[0] image_row = resize_grid_item(images[i]) h, w = image_row.shape[0:2] show_grid[y:(y + h), x:(x + w)] = image_row cv.rectangle(img=show_grid, pt1=(x, y), pt2=(x + w, y + h), color=(0, 0, 255), thickness=1, lineType=cv.LINE_AA) x += SHOW_WIDTH + SHOW_MARGIN[0] sort_score_ind = np.argsort(score_matrix[i, :])[::-1] row_score = score_matrix[i, sort_score_ind] row_images = [images[i] for i in sort_score_ind] for j in range(n_images): image_col = resize_grid_item(row_images[j]) h, w = image_col.shape[0:2] show_grid[y:(y + h), x:(x + w)] = image_col score = row_score[j] cv.putText(img=show_grid, text=f'{int(100 * score)}%', org=(x, y + SHOW_HEIGHT + 13), color=(255, 255, 255), fontFace=cv.FONT_HERSHEY_PLAIN, fontScale=0.8, lineType=cv.LINE_AA) x += SHOW_WIDTH + SHOW_MARGIN[0] y += SHOW_HEIGHT + SHOW_MARGIN[1] logger.info(f'Saving matching results image...') cv.imwrite(output_path, show_grid) logger.info(f'Showing matching results image...') window_name = 'Person matching scoring matrix' cv.namedWindow(window_name, cv.WINDOW_NORMAL) cv.resizeWindow(window_name, 1800, 1000) cv.imshow(window_name, show_grid) if cv.waitKey() == ord('q'): cv.destroyAllWindows() logger.info(f'Done !!')