Rudra-barman's picture
Rename face_segmentation_project.py to app.py
b4ad77e verified
# -*- coding: utf-8 -*-
"""Face_Segmentation_Project.ipynb
Automatically generated by Colab.
Original file is located at
https://colab.research.google.com/drive/1sLYDzM6pK7GBZW2JH7xMoVa0kOYYS9B5
## STEP 1 β€” Google Drive Mount Karo
"""
from google.colab import drive
drive.mount('/content/drive')
"""## βœ… STEP 2 β€” Set Path
"""
# Pehle path define karo (Apne folder ke hisaab se check kar lena)
TRAIN_NPY = "/content/drive/MyDrive/Face_Segmentation_Project/data/raw/Part 1- Train data - images.npy"
import numpy as np
print("Loading .npy file... (thoda time lagega 1.26GB hai)")
data = np.load(TRAIN_NPY, allow_pickle=True)
print("\n--- DATA INFO ---")
print("Type :", type(data))
print("Shape :", data.shape)
print("Dtype :", data.dtype)
# Agar object/dictionary ho
if data.dtype == object:
print("\nObject type hai, keys dekho:")
try:
d = data.item()
print("Keys:", d.keys())
except:
print("Array of objects - length:", len(data))
print("First element type:", type(data[0]))
print("First element shape:", data[0].shape if hasattr(data[0], 'shape') else "no shape")
else:
print("\nMin value :", data.min())
print("Max value :", data.max())
print("Total images:", data.shape[0])
# STEP 3 β€” Data Visualization (Andar kya hai dekho)
import matplotlib.pyplot as plt
# Pehla sample nikaalte hain
sample = data[0]
image_data = sample[0] # Pehla part image hona chahiye
mask_data = sample[1] # Dusra part mask ya annotations
print(f"Image shape: {image_data.shape}")
print(f"Mask/Metadata type: {type(mask_data)}")
# Ek bar visualize karke dekhte hain
plt.imshow(image_data)
plt.title("Sample Image")
plt.show()
# βœ… STEP 4 β€” Mask Check Karo (Andar kya hai?)
# List ka content check karte hain
print("Mask List Content:")
print(mask_data)
# Agar list ke pehle element mein 'notes' ya 'points' jaisi koi key hai toh:
if len(mask_data) > 0:
print("\nFirst element in list:", mask_data[0])
# πŸ› οΈ STEP 5 β€” Coordinates se Binary Mask Banana
import cv2
import numpy as np
def create_mask(image_shape, mask_list):
# Ek khali black image banao (0s)
mask = np.zeros(image_shape[:2], dtype=np.uint8)
h, w = image_shape[:2]
for item in mask_list:
# Normalized coordinates ko pixel values mein badlo
p1 = item['points'][0]
p2 = item['points'][1]
x1, y1 = int(p1['x'] * w), int(p1['y'] * h)
x2, y2 = int(p2['x'] * w), int(p2['y'] * h)
# Is area ko white (255) kar do
cv2.rectangle(mask, (x1, y1), (x2, y2), 255, -1)
return mask
# Test karte hain
test_mask = create_mask(image_data.shape, mask_data)
# Visualize Image + Mask
plt.figure(figsize=(10, 5))
plt.subplot(1, 2, 1)
plt.imshow(image_data); plt.title("Original Image")
plt.subplot(1, 2, 2)
plt.imshow(test_mask, cmap='gray'); plt.title("Generated Mask")
plt.show()
# βœ… STEP 6 β€” Data Preprocessing for U-Net
import cv2
import numpy as np
from tqdm import tqdm
IMG_HEIGHT = 256
IMG_WIDTH = 256
X = []
y = []
print("Processing 409 images and masks...")
for i in tqdm(range(len(data))):
img_array = data[i][0]
mask_list = data[i][1]
img_resized = cv2.resize(img_array, (IMG_WIDTH, IMG_HEIGHT))
if len(img_resized.shape) == 2:
img_resized = cv2.cvtColor(img_resized, cv2.COLOR_GRAY2RGB)
elif img_resized.shape[2] == 4:
img_resized = cv2.cvtColor(img_resized, cv2.COLOR_RGBA2RGB)
m_array = create_mask(img_array.shape, mask_list)
mask_resized = cv2.resize(m_array, (IMG_WIDTH, IMG_HEIGHT))
img_norm = img_resized / 255.0
mask_norm = mask_resized / 255.0
# βœ… Original image add karo
X.append(img_norm)
y.append(mask_norm)
# βœ… Augmentation 1 β€” Horizontal Flip
X.append(cv2.flip(img_norm, 1))
y.append(cv2.flip(mask_norm, 1))
# βœ… Augmentation 2 β€” Rotation 15 degree
M = cv2.getRotationMatrix2D((128, 128), 15, 1.0)
X.append(cv2.warpAffine(img_norm, M, (256, 256)))
y.append(cv2.warpAffine(mask_norm, M, (256, 256)))
# βœ… Augmentation 3 β€” Brightness Change
bright = np.clip(img_norm * 1.2, 0, 1)
X.append(bright)
y.append(mask_norm)
X = np.array(X, dtype=np.float32)
y = np.array(y, dtype=np.float32)
y = np.expand_dims(y, axis=-1)
print("\nβœ… Preprocessing Complete!")
print(f"Images Shape: {X.shape}")
print(f"Masks Shape : {y.shape}")
# πŸš€ STEP 7 β€” Model Building: U-Net with MobileNetV2
from sklearn.model_selection import train_test_split
X_train, X_temp, y_train, y_temp = train_test_split(
X, y, test_size=0.2, random_state=42
)
X_val, X_test, y_val, y_test = train_test_split(
X_temp, y_temp, test_size=0.5, random_state=42
)
print(f"Training data : {X_train.shape}")
print(f"Validation data : {X_val.shape}")
print(f"Test data : {X_test.shape}")
from tensorflow.keras.applications import MobileNetV2
from tensorflow.keras.layers import Input, Conv2D, UpSampling2D, Concatenate, BatchNormalization, Activation, Dropout
from tensorflow.keras.models import Model
import tensorflow as tf
def build_unet(input_shape):
inputs = Input(input_shape)
base_model = MobileNetV2(input_tensor=inputs, weights="imagenet", include_top=False)
# βœ… FIX 1: Encoder freeze karo
base_model.trainable = False
for layer in base_model.layers[-30:]:
layer.trainable = True
# Skip connections
s1 = inputs
s2 = base_model.get_layer("block_1_expand_relu").output
s3 = base_model.get_layer("block_3_expand_relu").output
s4 = base_model.get_layer("block_6_expand_relu").output
bridge = base_model.get_layer("block_13_expand_relu").output
# βœ… FIX 2: Dropout add kiya har decoder block mein
u1 = UpSampling2D((2, 2))(bridge)
u1 = Concatenate()([u1, s4])
u1 = Conv2D(256, 3, padding="same", kernel_initializer="he_normal")(u1)
u1 = BatchNormalization()(u1)
u1 = Activation("relu")(u1)
u1 = Dropout(0.3)(u1) # βœ…
u2 = UpSampling2D((2, 2))(u1)
u2 = Concatenate()([u2, s3])
u2 = Conv2D(128, 3, padding="same", kernel_initializer="he_normal")(u2)
u2 = BatchNormalization()(u2)
u2 = Activation("relu")(u2)
u2 = Dropout(0.3)(u2) # βœ…
u3 = UpSampling2D((2, 2))(u2)
u3 = Concatenate()([u3, s2])
u3 = Conv2D(64, 3, padding="same", kernel_initializer="he_normal")(u3)
u3 = BatchNormalization()(u3)
u3 = Activation("relu")(u3)
u3 = Dropout(0.2)(u3) # βœ…
u4 = UpSampling2D((2, 2))(u3)
u4 = Concatenate()([u4, s1])
u4 = Conv2D(32, 3, padding="same", kernel_initializer="he_normal")(u4)
u4 = BatchNormalization()(u4)
u4 = Activation("relu")(u4)
outputs = Conv2D(1, 1, activation="sigmoid")(u4)
return Model(inputs, outputs)
model = build_unet((256, 256, 3))
# βœ… FIX 3: Combined Loss
def dice_coefficient(y_true, y_pred):
y_true_f = tf.cast(tf.reshape(y_true, [-1]), tf.float32)
y_pred_f = tf.cast(tf.reshape(y_pred, [-1]), tf.float32)
intersection = tf.reduce_sum(y_true_f * y_pred_f)
return (2. * intersection + 1.0) / (tf.reduce_sum(y_true_f) + tf.reduce_sum(y_pred_f) + 1.0)
def dice_loss(y_true, y_pred):
return 1 - dice_coefficient(y_true, y_pred)
def combined_loss(y_true, y_pred):
return dice_loss(y_true, y_pred) + tf.keras.losses.binary_crossentropy(y_true, y_pred)
model.compile(
optimizer=tf.keras.optimizers.Adam(learning_rate=1e-3),
loss=combined_loss, # βœ… Combined loss
metrics=[dice_coefficient, "accuracy"]
)
print("βœ… Model Compiled Successfully!")
# Training se PEHLE yeh check karo:
print(f"X_train shape: {X_train.shape}")
print(f"X_val shape : {X_val.shape}")
print(f"X_test shape : {X_test.shape}")
# πŸš€ STEP 9 β€” Model Training (Fit)
from tensorflow.keras.callbacks import ModelCheckpoint, ReduceLROnPlateau, EarlyStopping
callbacks = [
ModelCheckpoint("best_face_model.keras", monitor='val_dice_coefficient',
mode='max', save_best_only=True, verbose=1),
ReduceLROnPlateau(monitor='val_loss', factor=0.2, patience=5,
min_lr=1e-7, verbose=1),
EarlyStopping(monitor='val_loss', patience=12,
restore_best_weights=True, verbose=1)
]
print("πŸš€ Training shuru ho rahi hai!")
history = model.fit(
X_train, y_train,
validation_data=(X_val, y_val),
epochs=50,
batch_size=8,
callbacks=callbacks,
shuffle=True
)
print("\nβœ… Training Complete!")
# Step - Evaluation Metrix
from sklearn.metrics import f1_score
import time
import numpy as np
def evaluate_model(model, X_test, y_test):
y_pred = model.predict(X_test)
y_pred_binary = (y_pred > 0.5).astype(np.float32)
# 1. Dice Coefficient
intersection = np.sum(y_test * y_pred_binary)
dice = (2. * intersection + 1.0) / (
np.sum(y_test) + np.sum(y_pred_binary) + 1.0
)
# 2. IoU Score
union = np.sum(y_test) + np.sum(y_pred_binary) - intersection
iou = intersection / union
# 3. F1 Score
f1 = f1_score(
y_test.flatten().astype(int),
y_pred_binary.flatten().astype(int)
)
# 4. βœ… Inference Speed β€” FIXED VERSION
model.predict(X_test[:1], verbose=0) # Warmup 1
model.predict(X_test[:1], verbose=0) # Warmup 2
times = []
for _ in range(5):
start = time.time()
model.predict(X_test[:1], verbose=0)
times.append((time.time() - start) * 1000)
speed = np.mean(times)
print("="*45)
print(f"Dice Coefficient : {dice:.4f} (Target >0.92)")
print(f"IoU Score : {iou:.4f} (Target >0.88)")
print(f"F1 Score : {f1:.4f} (Target >0.90)")
print(f"Inference Speed : {speed:.1f}ms (Target <100ms)")
print("="*45)
# Dobara chalao
evaluate_model(model, X_test, y_test)
# STEP 11 β€” Training Curves Plot
import matplotlib.pyplot as plt
plt.figure(figsize=(12, 4))
plt.subplot(1, 2, 1)
plt.plot(history.history['dice_coefficient'], label='Train Dice')
plt.plot(history.history['val_dice_coefficient'], label='Val Dice')
plt.title('Dice Coefficient Progress')
plt.xlabel('Epoch')
plt.legend()
plt.subplot(1, 2, 2)
plt.plot(history.history['loss'], label='Train Loss')
plt.plot(history.history['val_loss'], label='Val Loss')
plt.title('Loss Progress')
plt.xlabel('Epoch')
plt.legend()
plt.tight_layout()
plt.show()
import matplotlib.pyplot as plt
def visualize_prediction(index):
img = X_val[index]
gt_mask = y_val[index]
# Model se prediction lo
pred_mask = model.predict(np.expand_dims(img, axis=0))[0]
# Thresholding (0.5 se upar white, niche black)
pred_mask_binary = (pred_mask > 0.5).astype(np.uint8)
plt.figure(figsize=(12, 4))
plt.subplot(1, 3, 1)
plt.imshow(img); plt.title("Original Image")
plt.subplot(1, 3, 2)
plt.imshow(gt_mask.squeeze(), cmap='gray'); plt.title("Ground Truth Mask")
plt.subplot(1, 3, 3)
plt.imshow(pred_mask_binary.squeeze(), cmap='gray'); plt.title("Predicted Mask")
plt.show()
# Pehli 3 validation images check karte hain
for i in [0, 5, 10]:
visualize_prediction(i)
# πŸš€ STEP 12 β€” Improving Accuracy with Hugging Face (SegFormer)
!pip install -q transformers datasets
from transformers import SegformerImageProcessor, SegformerForSemanticSegmentation
import torch
from PIL import Image
# 1. Pre-trained Model Load Karein
device = "cuda" if torch.cuda.is_available() else "cpu"
# Processor images ko transform karega, model segmentation karega
processor = SegformerImageProcessor.from_pretrained("nvidia/mit-b0")
hf_model = SegformerForSemanticSegmentation.from_pretrained("nvidia/mit-b0",
num_labels=1,
ignore_mismatched_sizes=True).to(device)
print("βœ… Hugging Face SegFormer Model Loaded!")
# πŸ› οΈ STEP 12 β€” SegFormer Dataset Class
import torch
from torch.utils.data import Dataset, DataLoader
import numpy as np
class FaceDataset(Dataset):
def __init__(self, images, masks, processor):
self.images = images
self.masks = masks
self.processor = processor
def __len__(self):
return len(self.images)
def __getitem__(self, idx):
# Image aur Mask uthayein
# (X_train already normalized hai, hume original format chahiye processor ke liye)
image = (self.images[idx] * 255).astype(np.uint8)
mask = self.masks[idx].squeeze().astype(np.longlong) # SegFormer expects long for masks
# Processor se transform karein
encoded_inputs = self.processor(image, mask, return_tensors="pt")
# Squeeze batch dimension jo processor add karta hai
for k, v in encoded_inputs.items():
encoded_inputs[k] = v.squeeze(0)
return encoded_inputs
# 1. Dataset Objects Banayein
train_dataset = FaceDataset(X_train, y_train, processor)
val_dataset = FaceDataset(X_val, y_val, processor)
# 2. DataLoaders Banayein
train_dataloader = DataLoader(train_dataset, batch_size=4, shuffle=True)
val_dataloader = DataLoader(val_dataset, batch_size=4)
print(f"βœ… DataLoaders Ready! Training samples: {len(train_dataset)}")
# πŸš€ STEP 13 β€” Fine-tuning SegFormer (Training Loop)
from tqdm.notebook import tqdm
from torch.optim import AdamW
# 1. Optimizer setup
optimizer = AdamW(hf_model.parameters(), lr=5e-5)
# 2. Training Loop
num_epochs = 10 # SegFormer jaldi seekh jata hai
hf_model.train()
print("πŸš€ SegFormer Training shuru ho rahi hai...")
for epoch in range(num_epochs):
train_loss = 0
# Tqdm progress bar ke liye
pbar = tqdm(train_dataloader, desc=f"Epoch {epoch+1}")
for batch in pbar:
# Data ko GPU/CPU par bhejein
pixel_values = batch["pixel_values"].to(device)
labels = batch["labels"].to(device)
# Forward pass
outputs = hf_model(pixel_values=pixel_values, labels=labels)
loss = outputs.loss
# Backward pass
loss.backward()
optimizer.step()
optimizer.zero_grad()
train_loss += loss.item()
pbar.set_postfix({'loss': loss.item()})
avg_train_loss = train_loss / len(train_dataloader)
print(f"βœ… Epoch {epoch+1} Complete | Average Loss: {avg_train_loss:.4f}")
print("\nπŸŽ‰ SegFormer Fine-tuning Finished!")
# 🎨 STEP 14 β€” SegFormer Prediction & Visualization
import torch.nn as nn
def visualize_segformer_prediction(index):
# 1. Validation set se data lein
inputs = val_dataset[index]
pixel_values = inputs["pixel_values"].unsqueeze(0).to(device)
gt_mask = inputs["labels"].numpy()
# 2. Prediction karein
hf_model.eval()
with torch.no_grad():
outputs = hf_model(pixel_values=pixel_values)
logits = outputs.logits # [1, num_labels, height/4, width/4]
# 3. Logits ko original image size (256x256) par upsample karein
upsampled_logits = nn.functional.interpolate(
logits,
size=(256, 256),
mode='bilinear',
align_corners=False
)
# 4. Binary mask banayein (Squeeze karke threshold lagayein)
pred_mask = torch.sigmoid(upsampled_logits).cpu().numpy().squeeze()
pred_mask_binary = (pred_mask > 0.5).astype(np.uint8)
# 5. Plotting
plt.figure(figsize=(12, 4))
# Original Image (Pixel values ko denormalize karke dikhayenge)
display_img = pixel_values.cpu().squeeze().permute(1, 2, 0).numpy()
display_img = (display_img - display_img.min()) / (display_img.max() - display_img.min())
plt.subplot(1, 3, 1)
plt.imshow(display_img)
plt.title("Original Image")
plt.subplot(1, 3, 2)
plt.imshow(gt_mask, cmap='gray')
plt.title("Ground Truth Mask")
plt.subplot(1, 3, 3)
plt.imshow(pred_mask_binary, cmap='gray')
plt.title("SegFormer Prediction")
plt.show()
# Pehle 3 validation images par results dekhein
for i in [0, 5, 10]:
visualize_segformer_prediction(i)
# πŸ’Ύ STEP 15 β€” Model aur Processor ko Save Karein
import os
# 1. Ek folder banate hain model ke liye
save_directory = "my_face_segformer_model"
os.makedirs(save_directory, exist_ok=True)
# 2. Model ke weights aur config save karein
hf_model.save_pretrained(save_directory)
# 3. Processor (jo image resize aur normalize karta hai) bhi save karein
processor.save_pretrained(save_directory)
print(f"βœ… Model successfully saved in: {save_directory}")
# --- Google Colab Users ke liye ---
# Agar aap chahte hain ki ye hamesha ke liye safe rahe, toh ise Zip karke download kar lein
!zip -r face_model.zip my_face_segformer_model/
print("πŸ“¦ Zip file ban gayi hai! Ab aap ise left side ke 'Files' tab se download kar sakte hain.")
from google.colab import drive
import shutil
import os
# 1. Drive mount karein
drive.mount('/content/drive')
# 2. Aapka bataya hua path define karein
# Hum Face_Segmentation_Project ke andar 'saved_model' naam ka folder banayenge
base_path = '/content/drive/MyDrive/Face_Segmentation_Project'
model_save_path = os.path.join(base_path, 'trained_segformer_model')
# 3. Folder banayein agar nahi hai toh
os.makedirs(model_save_path, exist_ok=True)
# 4. Colab ki temporary files ko Drive par copy karein
source_folder = '/content/my_face_segformer_model'
# Purani files clear karke fresh copy karein
if os.path.exists(model_save_path):
shutil.rmtree(model_save_path)
shutil.copytree(source_folder, model_save_path)
print(f"βœ… Kaam ho gaya! Aapka model yahan save hai:")
print(f"πŸ“‚ {model_save_path}")
import os
# Actor folders banao
actors = [
"Robert_Downey_Jr",
"Scarlett_Johansson",
"Chris_Evans",
"Tom_Cruise",
"Leonardo_DiCaprio",
"Brad_Pitt",
"Chris Hemsworth"
]
for actor in actors:
os.makedirs(f"/content/actor_db/{actor}", exist_ok=True)
print("βœ… Actor folders ban gaye!")
print(os.listdir("/content/actor_db"))
import requests
import os
actor_images = {
"Robert_Downey_Jr": [
"https://wallpapers.com/images/hd/focused-photography-robert-downey-jr-pjs7jatnx0yfofsc.jpg",
"https://static1.srcdn.com/wordpress/wp-content/uploads/2024/07/instar53643496.jpg"
],
"Scarlett_Johansson": [
"https://tse2.mm.bing.net/th/id/OIP.OwNfXHWEAynGbQwhmUNQWwHaKk?rs=1&pid=ImgDetMain&o=7&rm=3",
"https://m.media-amazon.com/images/M/MV5BMjAyNjE1NjgyMF5BMl5BanBnXkFtZTcwMjg0ODY1NA@@._V1_.jpg"
],
"Chris_Evans": [
"https://cdn.britannica.com/28/215028-050-94E9EA1E/American-actor-Chris-Evans-2019.jpg",
"https://tse4.mm.bing.net/th/id/OIP._aupdpOey-23R2KHLQd0OgHaLH?rs=1&pid=ImgDetMain&o=7&rm=3"
],
"Tom_Cruise": [
"https://image.tmdb.org/t/p/original/8qBylBsQf4llkGrWR3qAsOtOU8O.jpg",
"https://m.media-amazon.com/images/M/MV5BMmU1YWU1NmMtMjAyMi00MjFiLWFmZmUtOTc1ZjI5ODkxYmQyXkEyXkFqcGc@._V1_FMjpg_UX1000_.jpg"
],
"Leonardo_DiCaprio": [
"https://image.tmdb.org/t/p/original/aLUFp0zWpLVyIOgY0scIpuuKZLE.jpg",
"https://wallpapers.com/images/hd/leonardo-dicaprio-actor-nl2l96xppg1rj9hz.jpg"
],
"Brad_Pitt": [
"https://fr.web.img2.acsta.net/pictures/20/02/10/10/37/1374948.jpg",
"https://www.gratistodo.com/wp-content/uploads/2016/09/Brad-Pitt-7.jpg"
],
"Chris Hemsworth": [
"https://cdn.britannica.com/92/215392-050-96A4BC1D/Australian-actor-Chris-Hemsworth-2019.jpg",
"https://static1.cbrimages.com/wordpress/wp-content/uploads/2023/06/chris-hemsworth-thor-love-and-thunder-mcu.jpg"
]
}
success = 0
fail = 0
for actor_name, urls in actor_images.items():
for i, url in enumerate(urls):
try:
response = requests.get(url, timeout=15)
if response.status_code == 200:
path = f"/content/actor_db/{actor_name}/{i}.jpg"
with open(path, 'wb') as f:
f.write(response.content)
print(f"βœ… {actor_name} β€” photo {i+1} downloaded")
success += 1
else:
print(f"❌ {actor_name} β€” photo {i+1} failed ({response.status_code})")
fail += 1
except Exception as e:
print(f"❌ {actor_name} β€” photo {i+1} error: {e}")
fail += 1
print(f"\nβœ… Success: {success} | ❌ Failed: {fail}")
# Verify karo
print("\nπŸ“ Database Status:")
for actor in os.listdir("/content/actor_db"):
photos = os.listdir(f"/content/actor_db/{actor}")
print(f" {actor}: {len(photos)} photos")
!pip install deepface -q
!pip install tf-keras -q
print("βœ… DeepFace installed!")
# Test Karo
from deepface import DeepFace
import cv2
import numpy as np
# Test β€” ek image pe try karo
test_img = "/content/actor_db/Robert_Downey_Jr/0.jpg"
result = DeepFace.analyze(
img_path=test_img,
actions=['age', 'gender'],
enforce_detection=False
)
print("βœ… DeepFace working!")
print(f"Age: {result[0]['age']}")
print(f"Gender: {result[0]['dominant_gender']}")
# Step 1 β€” Sahi versions install karo
!pip install tf-keras==2.19.0 -q
!pip install keras==2.19.0 -q
print("βœ… Done!")
import keras
import tensorflow as tf
def dice_coefficient(y_true, y_pred):
y_true_f = tf.cast(tf.reshape(y_true,[-1]),tf.float32)
y_pred_f = tf.cast(tf.reshape(y_pred,[-1]),tf.float32)
i = tf.reduce_sum(y_true_f*y_pred_f)
return (2.*i+1.)/(tf.reduce_sum(y_true_f)+tf.reduce_sum(y_pred_f)+1.)
def combined_loss(y_true, y_pred):
return 1-dice_coefficient(y_true,y_pred)+tf.keras.losses.binary_crossentropy(y_true,y_pred)
# Pehle load karo
model = keras.models.load_model(
"/content/best_face_model.keras",
custom_objects={
'dice_coefficient': dice_coefficient,
'combined_loss': combined_loss
}
)
# Weights alag save karo
model.save_weights("/content/model_weights.weights.h5")
print("βœ… Weights saved!")
# Commented out IPython magic to ensure Python compatibility.
# %%writefile /content/app.py
# import os
# os.environ['CUDA_VISIBLE_DEVICES'] = '-1'
# os.environ['TF_CPP_MIN_LOG_LEVEL'] = '3'
#
# import streamlit as st
# import numpy as np
# import cv2
# from PIL import Image
# import tensorflow as tf
# import time
# import io
#
# st.set_page_config(page_title="Scene Cast AI", page_icon="🎬", layout="wide")
#
# st.markdown("""<style>
# @import url('https://fonts.googleapis.com/css2?family=Syne:wght@700;800&family=DM+Sans:wght@300;400&display=swap');
# :root{--bg:#0a0a0f;--card:#16161f;--gold:#f5c518;--blue:#4cc9f0;--text:#f0f0f5;--muted:#7a7a8c;--border:rgba(245,197,24,0.15);}
# html,body,[class*="css"]{font-family:'DM Sans',sans-serif;background:var(--bg);color:var(--text);}
# .stApp{background:var(--bg);}
# #MainMenu,footer,header{visibility:hidden;}
# [data-testid="stSidebar"]{background:#111118;border-right:1px solid var(--border);}
# .hero-title{font-family:'Syne',sans-serif;font-size:3rem;font-weight:800;background:linear-gradient(135deg,#f5c518,#f0f0f5,#4cc9f0);-webkit-background-clip:text;-webkit-text-fill-color:transparent;margin:0;}
# .card{background:var(--card);border:1px solid var(--border);border-radius:16px;padding:1.2rem;position:relative;overflow:hidden;}
# .card::before{content:'';position:absolute;top:0;left:0;right:0;height:2px;background:linear-gradient(90deg,var(--gold),var(--blue));}
# .label{font-family:'Syne',sans-serif;font-size:0.75rem;font-weight:700;letter-spacing:0.15em;text-transform:uppercase;color:var(--gold);margin-bottom:0.8rem;}
# .metric-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:1rem;margin:1rem 0;}
# .metric{background:var(--card);border:1px solid var(--border);border-radius:14px;padding:1rem;text-align:center;}
# .mval{font-family:'Syne',sans-serif;font-size:1.5rem;font-weight:800;color:var(--gold);}
# .mval.warn{color:#fb923c;}.mval.fast{color:var(--blue);}
# .mlbl{color:var(--muted);font-size:0.75rem;text-transform:uppercase;}
# .mtgt{font-size:0.65rem;color:var(--muted);margin-top:0.2rem;}
# .info{background:rgba(245,197,24,0.08);border-left:3px solid var(--gold);padding:0.8rem;border-radius:0 8px 8px 0;font-size:0.83rem;color:var(--muted);margin-top:0.8rem;}
# .sec{display:flex;align-items:center;gap:0.8rem;margin:1.5rem 0 1rem;}
# .sec-line{flex:1;height:1px;background:var(--border);}
# .sec-title{font-family:'Syne',sans-serif;font-size:0.75rem;font-weight:700;letter-spacing:0.2em;text-transform:uppercase;color:var(--muted);}
# .actor-card{background:var(--card);border:1px solid rgba(245,197,24,0.3);border-radius:16px;padding:1rem;text-align:center;}
# .actor-name{font-family:'Syne',sans-serif;font-size:1rem;font-weight:800;color:var(--gold);margin:0.5rem 0 0.2rem;}
# .stDownloadButton>button{background:linear-gradient(135deg,rgba(245,197,24,0.15),rgba(76,201,240,0.1))!important;border:1px solid rgba(245,197,24,0.4)!important;color:var(--gold)!important;font-family:'Syne',sans-serif!important;font-weight:700!important;border-radius:10px!important;width:100%!important;}
# </style>""", unsafe_allow_html=True)
#
# # ── Model Architecture Rebuild + Weights Load ──
# from tensorflow.keras.applications import MobileNetV2
# from tensorflow.keras.layers import Input, Conv2D, UpSampling2D, Concatenate, BatchNormalization, Activation, Dropout
# from tensorflow.keras.models import Model
#
# def dice_coefficient(y_true, y_pred):
# y_true_f = tf.cast(tf.reshape(y_true,[-1]),tf.float32)
# y_pred_f = tf.cast(tf.reshape(y_pred,[-1]),tf.float32)
# i = tf.reduce_sum(y_true_f*y_pred_f)
# return (2.*i+1.)/(tf.reduce_sum(y_true_f)+tf.reduce_sum(y_pred_f)+1.)
#
# def combined_loss(y_true, y_pred):
# return 1-dice_coefficient(y_true,y_pred)+tf.keras.losses.binary_crossentropy(y_true,y_pred)
#
# def build_unet(input_shape=(256,256,3)):
# inputs = Input(input_shape)
# base = MobileNetV2(input_tensor=inputs, weights=None, include_top=False)
# base.trainable = False
# s1=inputs
# s2=base.get_layer("block_1_expand_relu").output
# s3=base.get_layer("block_3_expand_relu").output
# s4=base.get_layer("block_6_expand_relu").output
# bridge=base.get_layer("block_13_expand_relu").output
# u1=UpSampling2D((2,2))(bridge)
# u1=Concatenate()([u1,s4])
# u1=Conv2D(256,3,padding="same",kernel_initializer="he_normal")(u1)
# u1=BatchNormalization()(u1); u1=Activation("relu")(u1); u1=Dropout(0.3)(u1)
# u2=UpSampling2D((2,2))(u1)
# u2=Concatenate()([u2,s3])
# u2=Conv2D(128,3,padding="same",kernel_initializer="he_normal")(u2)
# u2=BatchNormalization()(u2); u2=Activation("relu")(u2); u2=Dropout(0.3)(u2)
# u3=UpSampling2D((2,2))(u2)
# u3=Concatenate()([u3,s2])
# u3=Conv2D(64,3,padding="same",kernel_initializer="he_normal")(u3)
# u3=BatchNormalization()(u3); u3=Activation("relu")(u3); u3=Dropout(0.2)(u3)
# u4=UpSampling2D((2,2))(u3)
# u4=Concatenate()([u4,s1])
# u4=Conv2D(32,3,padding="same",kernel_initializer="he_normal")(u4)
# u4=BatchNormalization()(u4); u4=Activation("relu")(u4)
# outputs=Conv2D(1,1,activation="sigmoid")(u4)
# return Model(inputs,outputs)
#
# @st.cache_resource(show_spinner=False)
# def load_model():
# with tf.device('/CPU:0'):
# m = build_unet()
# m.load_weights("/content/model_weights.weights.h5", by_name=True, skip_mismatch=True)
# m.compile(
# optimizer=tf.keras.optimizers.Adam(1e-4),
# loss=combined_loss,
# metrics=[dice_coefficient]
# )
# return m
#
# def create_overlay(image, mask):
# img=cv2.resize(np.array(image),(256,256))
# cm=np.zeros_like(img); cm[mask>127]=[245,197,24]
# ov=cv2.addWeighted(img,0.55,cm,0.45,0)
# ctrs,_=cv2.findContours(mask,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
# cv2.drawContours(ov,ctrs,-1,(245,197,24),2)
# return ov
#
# def face_count(mask):
# ctrs,_=cv2.findContours(mask,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
# return len([c for c in ctrs if cv2.contourArea(c)>256*256*0.005])
#
# def img_bytes(arr):
# buf=io.BytesIO(); Image.fromarray(arr).save(buf,format="PNG"); return buf.getvalue()
#
# def get_face_crops(image,mask):
# img=cv2.resize(np.array(image),(256,256))
# ctrs,_=cv2.findContours(mask,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
# crops=[]
# for c in ctrs:
# if cv2.contourArea(c)>256*256*0.005:
# x,y,w,h=cv2.boundingRect(c)
# crop=img[max(0,y-10):min(255,y+h+10),max(0,x-10):min(255,x+w+10)]
# if crop.size>0: crops.append(crop)
# return crops
#
# def identify_actors(crops):
# results=[]; db="/content/actor_db"
# if not os.path.exists(db): return results
# has_photos=any(len(os.listdir(f"{db}/{a}"))>0 for a in os.listdir(db) if os.path.isdir(f"{db}/{a}"))
# if not has_photos: return results
# try:
# from deepface import DeepFace
# for crop in crops:
# try:
# dfs=DeepFace.find(img_path=crop,db_path=db,model_name="VGG-Face",enforce_detection=False,silent=True)
# if len(dfs)>0 and len(dfs[0])>0:
# best=dfs[0].iloc[0]
# name=best['identity'].split('/')[-2].replace('_',' ')
# dist=best.get('distance',1)
# conf=max(0,(1-dist)*100)
# results.append({"name":name,"confidence":conf})
# else:
# results.append({"name":"Unknown Actor","confidence":0})
# except:
# results.append({"name":"Unknown Actor","confidence":0})
# except ImportError:
# pass
# return results
#
# with st.sidebar:
# st.markdown("""<div style="text-align:center;padding:1rem 0 1.5rem;">
# <div style="font-size:2.5rem;">🎬</div>
# <div style="font-family:'Syne',sans-serif;font-weight:800;color:#f5c518;">Scene Cast AI</div>
# <div style="font-size:0.75rem;color:#7a7a8c;">Face Segmentation Engine</div>
# </div>""",unsafe_allow_html=True)
# st.markdown("**βš™οΈ SETTINGS**")
# threshold=st.slider("Confidence Threshold",0.1,0.9,0.5,0.05)
# show_ov=st.checkbox("Face Overlay",value=True)
# show_mask=st.checkbox("Binary Mask",value=True)
# show_conf=st.checkbox("Confidence Map",value=False)
# show_actor=st.checkbox("🎭 Actor Recognition",value=True)
# st.markdown("---")
# st.markdown("""**πŸ“Š MODEL INFO**
# <div style="font-size:0.8rem;color:#7a7a8c;line-height:1.9;">
# πŸ—οΈ <b style="color:#f0f0f5;">Architecture:</b> U-Net<br>
# πŸ”§ <b style="color:#f0f0f5;">Encoder:</b> MobileNetV2<br>
# πŸ“¦ <b style="color:#f0f0f5;">Input:</b> 256Γ—256<br>
# πŸ“ˆ <b style="color:#f0f0f5;">Val Dice:</b> 0.8742
# </div>""",unsafe_allow_html=True)
#
# st.markdown("""<div style="text-align:center;padding:2rem 1rem 1.5rem;">
# <div style="display:inline-block;background:rgba(245,197,24,0.1);border:1px solid rgba(245,197,24,0.3);color:#f5c518;font-size:0.7rem;letter-spacing:0.2em;text-transform:uppercase;padding:0.3rem 1rem;border-radius:2rem;margin-bottom:1rem;">🎬 Powered by Deep Learning</div>
# <h1 class="hero-title">Scene Cast AI</h1>
# <p style="color:#7a7a8c;font-size:1rem;max-width:480px;margin:0.5rem auto;">Real-time face segmentation + actor identification.</p>
# <div style="width:60px;height:2px;background:linear-gradient(90deg,#f5c518,#4cc9f0);margin:1.2rem auto 0;border-radius:2px;"></div>
# </div>""",unsafe_allow_html=True)
#
# with st.spinner("πŸ”„ Loading AI Model..."):
# try:
# model=load_model()
# st.success("βœ… Model loaded!", icon="πŸ€–")
# except Exception as e:
# st.error(f"❌ Error: {e}")
# st.stop()
#
# st.markdown('<div class="sec"><div class="sec-line"></div><div class="sec-title">πŸ“ Upload Movie Scene</div><div class="sec-line"></div></div>',unsafe_allow_html=True)
# f=st.file_uploader("Upload",type=["jpg","jpeg","png","webp"],label_visibility="collapsed")
#
# if f:
# # πŸ”₯ FIX: Streamlit upload β†’ OpenCV decode
# file_bytes = np.asarray(bytearray(f.read()), dtype=np.uint8)
# img = cv2.imdecode(file_bytes, cv2.IMREAD_COLOR)
#
# if img is None:
# st.error("❌ Image read nahi ho pa rahi. Dusri image try karo.")
# st.stop()
#
# img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
# image = Image.fromarray(img)
#
# # πŸ‘‡ same code as before
# ir = cv2.resize(np.array(image),(256,256))/255.0
# ii = np.expand_dims(ir,0).astype(np.float32)
#
# with st.spinner("🧠 Analyzing..."):
# with tf.device('/CPU:0'):
# t0 = time.time()
# pred = model.predict(ii,verbose=0)[0]
# spd = (time.time()-t0)*1000
#
# mask = (pred.squeeze()>threshold).astype(np.uint8)*255
# fc = face_count(mask)
# cov = (np.sum(mask>0)/(256*256))*100
#
# st.markdown('<div class="sec"><div class="sec-line"></div><div class="sec-title">🎯 Detection Results</div><div class="sec-line"></div></div>',unsafe_allow_html=True)
#
# ncols = 1+show_ov+show_mask+show_conf
# dcols = st.columns(ncols)
# with dcols[0]:
# st.markdown('<div class="card"><div class="label">🎬 Original Frame</div>',unsafe_allow_html=True)
# st.image(image,use_container_width=True)
# st.markdown(f'<div class="info">πŸ“ {image.width}Γ—{image.height}px | πŸ‘₯ ~{fc} face(s)</div></div>',unsafe_allow_html=True)
# idx=1
# if show_ov:
# ov=create_overlay(image,mask)
# with dcols[idx]:
# st.markdown('<div class="card"><div class="label">✨ Face Overlay</div>',unsafe_allow_html=True)
# st.image(ov,use_container_width=True)
# st.markdown(f'<div class="info">🟑 Gold=face | {cov:.1f}%</div></div>',unsafe_allow_html=True)
# idx+=1
# if show_mask:
# with dcols[idx]:
# st.markdown('<div class="card"><div class="label">πŸ”² Binary Mask</div>',unsafe_allow_html=True)
# st.image(mask,use_container_width=True)
# st.markdown(f'<div class="info">⬜ White=face | {threshold:.2f}</div></div>',unsafe_allow_html=True)
# idx+=1
# if show_conf:
# cm=cv2.applyColorMap((pred.squeeze()*255).astype(np.uint8),cv2.COLORMAP_INFERNO)
# cm=cv2.cvtColor(cm,cv2.COLOR_BGR2RGB)
# with dcols[idx]:
# st.markdown('<div class="card"><div class="label">🌑️ Confidence</div>',unsafe_allow_html=True)
# st.image(cm,use_container_width=True)
# st.markdown('<div class="info">πŸ”΄ Hot=face</div></div>',unsafe_allow_html=True)
# if show_actor:
# st.markdown('<div class="sec"><div class="sec-line"></div><div class="sec-title">🎭 Actor Recognition</div><div class="sec-line"></div></div>',unsafe_allow_html=True)
# with st.spinner("πŸ” Identifying..."):
# crops=get_face_crops(image,mask); actors=identify_actors(crops)
# if actors:
# acols=st.columns(min(len(actors),4))
# for i,a in enumerate(actors):
# cc="#4ade80" if a['confidence']>60 else "#fb923c"
# with acols[i%4]:
# st.markdown(f"""<div class="actor-card"><div style="font-size:2rem;">🎭</div>
# <div class="actor-name">{a['name']}</div>
# <div style="font-size:0.78rem;color:{cc};">Confidence: {a['confidence']:.1f}%</div>
# </div>""",unsafe_allow_html=True)
# else:
# st.info("πŸ” Actor DB mein photos upload karo!",icon="ℹ️")
# st.markdown('<div class="sec"><div class="sec-line"></div><div class="sec-title">πŸ“Š Performance</div><div class="sec-line"></div></div>',unsafe_allow_html=True)
# sc="fast" if spd<100 else "warn"
# st.markdown(f"""<div class="metric-grid">
# <div class="metric"><div style="font-size:1.3rem;">🎯</div><div class="mval warn">0.8845</div><div class="mlbl">Dice</div><div class="mtgt">&gt;0.92</div></div>
# <div class="metric"><div style="font-size:1.3rem;">πŸ“</div><div class="mval warn">0.7929</div><div class="mlbl">IoU</div><div class="mtgt">&gt;0.88</div></div>
# <div class="metric"><div style="font-size:1.3rem;">βš–οΈ</div><div class="mval warn">0.8849</div><div class="mlbl">F1</div><div class="mtgt">&gt;0.90</div></div>
# <div class="metric"><div style="font-size:1.3rem;">⚑</div><div class="mval {sc}">{spd:.0f}ms</div><div class="mlbl">Speed</div><div class="mtgt">&lt;100ms</div></div>
# </div>""",unsafe_allow_html=True)
# c1,c2,c3=st.columns(3)
# for col,icon,val,lbl,clr in [(c1,"πŸ‘₯",str(fc),"Faces","#f5c518"),(c2,"πŸ“Š",f"{cov:.1f}%","Coverage","#4cc9f0"),(c3,"🎚️",f"{threshold:.2f}","Threshold","#4ade80")]:
# with col:
# st.markdown(f"""<div class="card" style="text-align:center;padding:1rem;">
# <div style="font-size:2rem;">{icon}</div>
# <div style="font-family:'Syne',sans-serif;font-size:1.8rem;font-weight:800;color:{clr};">{val}</div>
# <div style="color:#7a7a8c;font-size:0.78rem;text-transform:uppercase;">{lbl}</div>
# </div>""",unsafe_allow_html=True)
# st.markdown('<div class="sec"><div class="sec-line"></div><div class="sec-title">πŸ“₯ Export</div><div class="sec-line"></div></div>',unsafe_allow_html=True)
# d1,d2,d3=st.columns(3)
# with d1:
# st.download_button("⬇️ Mask",img_bytes(mask),"mask.png","image/png",use_container_width=True)
# with d2:
# ov2=create_overlay(image,mask)
# st.download_button("⬇️ Overlay",img_bytes(ov2),"overlay.png","image/png",use_container_width=True)
# with d3:
# log=f"File:{f.name}\nFaces:{fc}\nSpeed:{spd:.1f}ms\nDice:0.8845\nIoU:0.7929"
# st.download_button("⬇️ Log",log,"log.txt","text/plain",use_container_width=True)
# else:
# st.markdown("""<div style="background:#16161f;border:2px dashed rgba(245,197,24,0.2);border-radius:20px;padding:4rem 2rem;text-align:center;margin:2rem 0;">
# <div style="font-size:4rem;">🎬</div>
# <div style="font-family:'Syne',sans-serif;font-size:1.4rem;font-weight:700;color:#f0f0f5;margin:0.8rem 0 0.4rem;">Ready to Detect & Identify</div>
# <div style="color:#7a7a8c;">Upload movie screenshot β†’ AI detects + identifies actors!</div>
# </div>""",unsafe_allow_html=True)
!sed -i 's/use_container_width=True/use_column_width=True/g' /content/app.py
# Yeh cell chalao β€” warning fix hogi
!sed -i 's/use_column_width=True/use_container_width=True/g' /content/app.py
print("βœ… Fixed!")
!pip install streamlit pyngrok -q
# Ek Cell Mein Sab
!fuser -k 8501/tcp
!pkill -f streamlit
import time
time.sleep(2)
import subprocess, threading
def run():
subprocess.Popen([
'streamlit', 'run', '/content/app.py',
'--server.port=8501',
'--server.headless=true',
'--server.enableCORS=false',
'--server.enableXsrfProtection=false'
])
threading.Thread(target=run).start()
time.sleep(15)
from google.colab.output import eval_js
url = eval_js("google.colab.kernel.proxyPort(8501)")
print(f"βœ… URL: {url}")