deepf / app.py
reinformator's picture
Update app.py
3e5e6de verified
Raw History Blame Contribute Delete
5.1 kB
import streamlit as st
import cv2
import numpy as np
from PIL import Image, ExifTags
from mtcnn import MTCNN
from deepface import DeepFace
from transformers import BlipProcessor, BlipForConditionalGeneration
# Initialize MTCNN for face detection
detector = MTCNN()
# Load BLIP model for scene description
processor = BlipProcessor.from_pretrained("Salesforce/blip-image-captioning-base")
blip_model = BlipForConditionalGeneration.from_pretrained("Salesforce/blip-image-captioning-base")
# Function to auto-rotate the image based on EXIF data
def auto_rotate_image(image):
try:
for orientation in ExifTags.TAGS.keys():
if ExifTags.TAGS[orientation] == 'Orientation':
break
exif = image._getexif()
if exif is not None:
orientation_value = exif.get(orientation)
if orientation_value == 3:
image = image.rotate(180, expand=True)
elif orientation_value == 6:
image = image.rotate(270, expand=True)
elif orientation_value == 8:
image = image.rotate(90, expand=True)
except (AttributeError, KeyError, IndexError, TypeError):
pass # No EXIF data or issues reading EXIF, skip rotation
return image
# Function to generate a scene description using BLIP
def describe_scene(image):
inputs = processor(image, return_tensors="pt")
outputs = blip_model.generate(**inputs)
caption = processor.decode(outputs[0], skip_special_tokens=True)
return caption
# Function for face analysis using DeepFace
def analyze_face(face_image):
face_array = np.array(face_image)
try:
result = DeepFace.analyze(face_array, actions=['gender', 'age', 'race', 'emotion'], enforce_detection=False)
return result
except Exception as e:
return {"error": str(e)}
# Main Streamlit application
def main():
st.title("Comprehensive Image Analysis")
st.write("Upload an image to get a scene description and detailed face analysis (gender, age, race, emotions).")
# Upload image
uploaded_image = st.file_uploader("Upload an image...", type=["jpg", "jpeg", "png", "webp"])
if uploaded_image is not None:
image = Image.open(uploaded_image).convert("RGB")
# Auto-rotate image if possible
image = auto_rotate_image(image)
st.image(image, caption="Uploaded Image", use_container_width=True)
# Option for manual rotation
rotation_angle = st.slider("Rotate Image (Degrees)", -180, 180, 0)
if rotation_angle != 0:
image = image.rotate(rotation_angle, expand=True)
st.image(image, caption="Rotated Image", use_container_width=True)
if st.button("Analyze"):
with st.spinner("Analyzing..."):
# Scene description
scene_caption = describe_scene(image)
st.subheader("Scene Description")
st.write(scene_caption)
# Detect faces using MTCNN
faces = detector.detect_faces(np.array(image))
if faces:
# Limit to only the first detected face
st.write("**One Face Detected. Analyzing...**")
# Get the first face
face = faces[0]
x, y, width, height = face['box']
face_crop = image.crop((x, y, x + width, y + height))
face_crop_resized = face_crop.resize((150, 150))
st.subheader("Face Analysis")
st.image(face_crop_resized, caption="Detected Face", width=150)
# Analyze face with DeepFace
result = analyze_face(face_crop)
if "error" in result:
st.error(f"Face Analysis Error: {result['error']}")
else:
single_result = result[0] if isinstance(result, list) else result
# Gender
dominant_gender = single_result.get('dominant_gender', 'N/A')
gender_confidence = int(round(single_result.get('gender', {}).get(dominant_gender, 0)))
st.write(f"**Gender:** {dominant_gender.capitalize()} ({gender_confidence}%)")
# Age
age = single_result.get('age', 'N/A')
st.write(f"**Age:** {age}")
# Race
race = single_result.get('race', {})
race_text = ", ".join([f"{r}: {int(round(p))}%" for r, p in race.items()])
st.write(f"**Race:** {race_text}")
# Emotions
emotions = single_result.get('emotion', {})
emotion_text = ", ".join([f"{e}: {int(round(p))}%" for e, p in emotions.items()])
st.write(f"**Emotions:** {emotion_text}")
else:
st.write("No faces detected.")
if __name__ == "__main__":
main()