Spaces:
Running
Running
| import cv2 | |
| import numpy as np | |
| from skimage.feature import local_binary_pattern | |
| import dlib | |
| import imutils | |
| from PIL import Image as PILImage | |
| from src.cv_utils import get_image, resize_image_height | |
| from typing import Tuple, List, Union | |
| class GetFaceTexture: | |
| def __init__(self) -> None: | |
| pass | |
| def preprocess_image(image) -> np.array: | |
| image = imutils.resize(image, width=500) | |
| gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) | |
| return gray_image | |
| def get_face(gray_image: np.array) -> np.array: | |
| detector = dlib.get_frontal_face_detector() | |
| faces = detector(gray_image, 1) | |
| if len(faces) == 0: | |
| return "No face detected." | |
| x, y, w, h = ( | |
| faces[0].left(), | |
| faces[0].top(), | |
| faces[0].width(), | |
| faces[0].height(), | |
| ) | |
| face_image = gray_image[y : y + h, x : x + w] | |
| return face_image | |
| def get_face_texture(face_image: np.array) -> Tuple[np.array, float]: | |
| radius = 1 | |
| n_points = 8 * radius | |
| lbp = local_binary_pattern(face_image, n_points, radius, method="uniform") | |
| hist, _ = np.histogram( | |
| lbp.ravel(), bins=np.arange(0, n_points + 3), range=(0, n_points + 2) | |
| ) | |
| variance = np.var(hist) | |
| std = np.sqrt(variance) | |
| return lbp, std | |
| def postprocess_image(lbp: np.array) -> PILImage: | |
| lbp = (lbp * 255).astype(np.uint8) | |
| return PILImage.fromarray(lbp) | |
| def main(self, image_input) -> List[Union[PILImage.Image, PILImage.Image, dict]]: | |
| image = get_image(image_input) | |
| gray_image = self.preprocess_image(image) | |
| face_image = self.get_face(gray_image) | |
| lbp, std = self.get_face_texture(face_image) | |
| face_texture_image = self.postprocess_image(lbp) | |
| face_image = PILImage.fromarray(face_image) | |
| face_image = resize_image_height(face_image, new_height=300) | |
| face_texture_image = resize_image_height(face_texture_image, new_height=300) | |
| return face_image, face_texture_image, {"texture_std": round(std, 2)} | |
| if __name__ == "__main__": | |
| image_path = "data/gigi_hadid.webp" | |
| print(GetFaceTexture().main(image_path)) | |