Spaces:
Runtime error
Runtime error
| from PIL import Image | |
| from schemas.vision_schemas import FakeFaceDetector | |
| import cv2 | |
| import numpy as np | |
| from tensorflow.keras.models import Sequential | |
| from tensorflow.keras.layers import Conv2D, BatchNormalization, MaxPooling2D, Flatten, Dropout, Dense | |
| from tensorflow.keras.preprocessing.image import img_to_array | |
| from PIL import Image | |
| class Meso4FakeFaceDetector(FakeFaceDetector): | |
| """ | |
| Deepfake face detector using Meso4 models trained on DF and F2F datasets. | |
| Combines both models' predictions for a more robust detection. | |
| """ | |
| def __init__(self, | |
| df_model_path: str = "models/Meso4_DF.h5", | |
| f2f_model_path: str = "models/Meso4_F2F.h5", | |
| input_shape=(256, 256, 3)): | |
| """ | |
| Initialize and load both pretrained models. | |
| Args: | |
| df_model_path (str): Path to Meso4 model trained on DeepFake dataset. | |
| f2f_model_path (str): Path to Meso4 model trained on Face2Face dataset. | |
| input_shape (tuple): Expected input shape for the models. | |
| """ | |
| self.df_model_path = df_model_path | |
| self.f2f_model_path = f2f_model_path | |
| self.input_shape = input_shape | |
| # Build both models | |
| self.model_df = self._build_meso4() | |
| self.model_f2f = self._build_meso4() | |
| # Load pretrained weights | |
| self.model_df.load_weights(self.df_model_path) | |
| self.model_f2f.load_weights(self.f2f_model_path) | |
| # ------------------ Internal Model Builder ------------------ | |
| def _build_meso4(self): | |
| """Build the Meso4 CNN model architecture.""" | |
| model = Sequential() | |
| model.add(Conv2D(8, (3, 3), activation='relu', padding='same', input_shape=self.input_shape)) | |
| model.add(BatchNormalization()) | |
| model.add(MaxPooling2D(pool_size=(2, 2), strides=2)) | |
| model.add(Conv2D(8, (5, 5), activation='relu', padding='same')) | |
| model.add(BatchNormalization()) | |
| model.add(MaxPooling2D(pool_size=(2, 2), strides=2)) | |
| model.add(Conv2D(16, (5, 5), activation='relu', padding='same')) | |
| model.add(BatchNormalization()) | |
| model.add(MaxPooling2D(pool_size=(2, 2), strides=2)) | |
| model.add(Conv2D(16, (5, 5), activation='relu', padding='same')) | |
| model.add(BatchNormalization()) | |
| model.add(MaxPooling2D(pool_size=(4, 4), strides=4)) | |
| model.add(Flatten()) | |
| model.add(Dropout(0.5)) | |
| model.add(Dense(16, activation='relu')) | |
| model.add(Dense(1, activation='sigmoid')) | |
| model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy']) | |
| return model | |
| # ------------------ Image Preprocessing ------------------ | |
| def _preprocess_image(self, image: Image.Image) -> np.ndarray: | |
| """ | |
| Preprocess a PIL image for prediction. | |
| Args: | |
| image (PIL.Image): Input face image. | |
| Returns: | |
| np.ndarray: Preprocessed image ready for model input. | |
| """ | |
| img = image.convert("RGB") | |
| img = img.resize((256, 256)) | |
| img = img_to_array(img) / 255.0 | |
| img = np.expand_dims(img, axis=0) | |
| return img | |
| # ------------------ Detection ------------------ | |
| def detect(self, image: Image.Image, threshold: float = 0.5, verbose=True) -> bool: | |
| """ | |
| Detect whether an input face image is fake or real. | |
| Args: | |
| image (PIL.Image): Input image of a face. | |
| threshold (float): Decision threshold (default 0.5). | |
| Returns: | |
| bool: True if fake, False if real. | |
| """ | |
| img = self._preprocess_image(image) | |
| # Get individual predictions | |
| pred_df = float(self.model_df.predict(img, verbose=0)[0][0]) | |
| pred_f2f = float(self.model_f2f.predict(img, verbose=0)[0][0]) | |
| # Combine predictions (average) | |
| combined_pred = (pred_df + pred_f2f) / 2.0 | |
| if verbose: | |
| # Print detailed info | |
| print(f"π Meso4_DF Prediction: {pred_df:.4f}") | |
| print(f"π Meso4_F2F Prediction: {pred_f2f:.4f}") | |
| print(f"βοΈ Combined Score: {combined_pred:.4f}") | |
| # Determine if fake | |
| is_fake = combined_pred >= threshold | |
| if is_fake: | |
| print("π΄ Deepfake detected.") | |
| else: | |
| print("π’ Real face detected.") | |
| return is_fake | |