|
import numpy as np
|
|
import tensorflow as tf
|
|
from tensorflow.keras.models import load_model
|
|
from tensorflow.keras.preprocessing import image
|
|
import cv2
|
|
|
|
class_names = [
|
|
'Akshay Kumar', 'Alexandra Daddario', 'Alia Bhatt', 'Amitabh Bachchan',
|
|
'Andy Samberg', 'Anushka Sharma', 'Billie Eilish', 'Brad Pitt', 'Camila Cabello',
|
|
'Charlize Theron', 'Claire Holt', 'Courtney Cox', 'Dwayne Johnson', 'Elizabeth Olsen',
|
|
'Ellen Degeneres', 'Henry Cavill', 'Hrithik Roshan', 'Hugh Jackman', 'Jessica Alba',
|
|
'Lisa Kudrow', 'Margot Robbie', 'Natalie Portman', 'Priyanka Chopra', 'Robert Downey Jr',
|
|
'Roger Federer', 'Tom Cruise', 'Vijay Deverakonda', 'Virat Kohli', 'Zac Efron'
|
|
]
|
|
|
|
model = load_model("my_29_30_model_97.h5", compile=False)
|
|
model.compile(optimizer=tf.keras.optimizers.Adam(), loss='categorical_crossentropy', metrics=['accuracy'])
|
|
|
|
|
|
def load_and_preprocess_image(img_array, target_size):
|
|
if img_array is None:
|
|
raise ValueError("The input image is None. Cannot preprocess an empty image.")
|
|
|
|
img = cv2.resize(img_array, target_size)
|
|
img_array = image.img_to_array(img)
|
|
img_array = np.expand_dims(img_array, axis=0)
|
|
img_array = tf.keras.applications.vgg16.preprocess_input(img_array)
|
|
return img_array
|
|
|
|
def detect_and_crop_faces(img_array, filter_path):
|
|
"""
|
|
Detects faces in an image array using a Haar Cascade filter and returns cropped face images.
|
|
|
|
Args:
|
|
img_array (numpy.ndarray): The input image array.
|
|
filter_path (str): The file path to the Haar Cascade XML file for face detection.
|
|
|
|
Returns:
|
|
tuple: A tuple containing a list of cropped face images and the original image array.
|
|
"""
|
|
|
|
if img_array is None:
|
|
raise ValueError("The input image array is None. Please provide a valid image.")
|
|
|
|
if not isinstance(img_array, np.ndarray):
|
|
raise TypeError("The input must be a NumPy ndarray.")
|
|
|
|
if img_array.size == 0:
|
|
raise ValueError("The input image array is empty. Please provide a non-empty image.")
|
|
|
|
img_array = img_array.astype(np.uint8)
|
|
|
|
if len(img_array.shape) == 2:
|
|
gray = img_array
|
|
elif len(img_array.shape) == 3 and img_array.shape[2] == 3:
|
|
gray = cv2.cvtColor(img_array, cv2.COLOR_RGB2GRAY)
|
|
else:
|
|
raise ValueError("Unexpected image format: the image should have 1 or 3 channels.")
|
|
|
|
face_cascade = cv2.CascadeClassifier(filter_path)
|
|
|
|
if face_cascade.empty():
|
|
raise ValueError("Failed to load the Haar Cascade classifier. Please check the file path.")
|
|
|
|
faces = face_cascade.detectMultiScale(gray, 1.3, 5)
|
|
|
|
cropped_faces = [(img_array[y:y + h, x:x + w], (x, y, w, h)) for (x, y, w, h) in faces]
|
|
|
|
return cropped_faces, img_array
|
|
|
|
|
|
def predict_faces(img, filter_path):
|
|
img_array = np.array(img)
|
|
|
|
if len(img_array.shape) == 2:
|
|
img_array = cv2.cvtColor(img_array, cv2.COLOR_GRAY2RGB)
|
|
elif len(img_array.shape) == 3 and img_array.shape[2] == 1:
|
|
img_array = cv2.cvtColor(img_array, cv2.COLOR_GRAY2RGB)
|
|
|
|
cropped_faces, original_img = detect_and_crop_faces(img_array, filter_path)
|
|
|
|
if not cropped_faces:
|
|
return "No faces detected.", None
|
|
|
|
results = []
|
|
for face, (x, y, w, h) in cropped_faces:
|
|
preprocessed_face = load_and_preprocess_image(face, target_size=(224, 224))
|
|
predictions = model.predict(preprocessed_face)
|
|
pred_idx = np.argmax(predictions[0])
|
|
predicted_label = class_names[pred_idx]
|
|
results.append(predicted_label)
|
|
|
|
return results, original_img
|
|
|
|
|
|
def predict_celebrity(image):
|
|
if image is None:
|
|
return "Unknown"
|
|
|
|
predictions, _ = predict_faces(image, cv2.data.haarcascades + 'haarcascade_frontalface_default.xml')
|
|
if predictions == "No faces detected.":
|
|
return "Unknown"
|
|
return predictions[0] |