Rudra-barman commited on
Commit
d08b661
Β·
verified Β·
1 Parent(s): 349ac6a

Upload 3 files

Browse files
Face_Segmentation_Project.ipynb ADDED
The diff for this file is too large to render. See raw diff
 
face_segmentation_project.py ADDED
@@ -0,0 +1,1038 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # -*- coding: utf-8 -*-
2
+ """Face_Segmentation_Project.ipynb
3
+
4
+ Automatically generated by Colab.
5
+
6
+ Original file is located at
7
+ https://colab.research.google.com/drive/1sLYDzM6pK7GBZW2JH7xMoVa0kOYYS9B5
8
+
9
+ ## STEP 1 β€” Google Drive Mount Karo
10
+ """
11
+
12
+ from google.colab import drive
13
+ drive.mount('/content/drive')
14
+
15
+ """## βœ… STEP 2 β€” Set Path
16
+
17
+ """
18
+
19
+ # Pehle path define karo (Apne folder ke hisaab se check kar lena)
20
+ TRAIN_NPY = "/content/drive/MyDrive/Face_Segmentation_Project/data/raw/Part 1- Train data - images.npy"
21
+
22
+ import numpy as np
23
+
24
+ print("Loading .npy file... (thoda time lagega 1.26GB hai)")
25
+ data = np.load(TRAIN_NPY, allow_pickle=True)
26
+
27
+ print("\n--- DATA INFO ---")
28
+ print("Type :", type(data))
29
+ print("Shape :", data.shape)
30
+ print("Dtype :", data.dtype)
31
+
32
+ # Agar object/dictionary ho
33
+ if data.dtype == object:
34
+ print("\nObject type hai, keys dekho:")
35
+ try:
36
+ d = data.item()
37
+ print("Keys:", d.keys())
38
+ except:
39
+ print("Array of objects - length:", len(data))
40
+ print("First element type:", type(data[0]))
41
+ print("First element shape:", data[0].shape if hasattr(data[0], 'shape') else "no shape")
42
+ else:
43
+ print("\nMin value :", data.min())
44
+ print("Max value :", data.max())
45
+ print("Total images:", data.shape[0])
46
+
47
+ # STEP 3 β€” Data Visualization (Andar kya hai dekho)
48
+
49
+ import matplotlib.pyplot as plt
50
+
51
+ # Pehla sample nikaalte hain
52
+ sample = data[0]
53
+ image_data = sample[0] # Pehla part image hona chahiye
54
+ mask_data = sample[1] # Dusra part mask ya annotations
55
+
56
+ print(f"Image shape: {image_data.shape}")
57
+ print(f"Mask/Metadata type: {type(mask_data)}")
58
+
59
+ # Ek bar visualize karke dekhte hain
60
+ plt.imshow(image_data)
61
+ plt.title("Sample Image")
62
+ plt.show()
63
+
64
+ # βœ… STEP 4 β€” Mask Check Karo (Andar kya hai?)
65
+
66
+ # List ka content check karte hain
67
+ print("Mask List Content:")
68
+ print(mask_data)
69
+
70
+ # Agar list ke pehle element mein 'notes' ya 'points' jaisi koi key hai toh:
71
+ if len(mask_data) > 0:
72
+ print("\nFirst element in list:", mask_data[0])
73
+
74
+ # πŸ› οΈ STEP 5 β€” Coordinates se Binary Mask Banana
75
+
76
+ import cv2
77
+ import numpy as np
78
+
79
+ def create_mask(image_shape, mask_list):
80
+ # Ek khali black image banao (0s)
81
+ mask = np.zeros(image_shape[:2], dtype=np.uint8)
82
+
83
+ h, w = image_shape[:2]
84
+
85
+ for item in mask_list:
86
+ # Normalized coordinates ko pixel values mein badlo
87
+ p1 = item['points'][0]
88
+ p2 = item['points'][1]
89
+
90
+ x1, y1 = int(p1['x'] * w), int(p1['y'] * h)
91
+ x2, y2 = int(p2['x'] * w), int(p2['y'] * h)
92
+
93
+ # Is area ko white (255) kar do
94
+ cv2.rectangle(mask, (x1, y1), (x2, y2), 255, -1)
95
+
96
+ return mask
97
+
98
+ # Test karte hain
99
+ test_mask = create_mask(image_data.shape, mask_data)
100
+
101
+ # Visualize Image + Mask
102
+ plt.figure(figsize=(10, 5))
103
+ plt.subplot(1, 2, 1)
104
+ plt.imshow(image_data); plt.title("Original Image")
105
+ plt.subplot(1, 2, 2)
106
+ plt.imshow(test_mask, cmap='gray'); plt.title("Generated Mask")
107
+ plt.show()
108
+
109
+ # βœ… STEP 6 β€” Data Preprocessing for U-Net
110
+
111
+ import cv2
112
+ import numpy as np
113
+ from tqdm import tqdm
114
+
115
+ IMG_HEIGHT = 256
116
+ IMG_WIDTH = 256
117
+
118
+ X = []
119
+ y = []
120
+
121
+ print("Processing 409 images and masks...")
122
+
123
+ for i in tqdm(range(len(data))):
124
+ img_array = data[i][0]
125
+ mask_list = data[i][1]
126
+
127
+ img_resized = cv2.resize(img_array, (IMG_WIDTH, IMG_HEIGHT))
128
+
129
+ if len(img_resized.shape) == 2:
130
+ img_resized = cv2.cvtColor(img_resized, cv2.COLOR_GRAY2RGB)
131
+ elif img_resized.shape[2] == 4:
132
+ img_resized = cv2.cvtColor(img_resized, cv2.COLOR_RGBA2RGB)
133
+
134
+ m_array = create_mask(img_array.shape, mask_list)
135
+ mask_resized = cv2.resize(m_array, (IMG_WIDTH, IMG_HEIGHT))
136
+
137
+ img_norm = img_resized / 255.0
138
+ mask_norm = mask_resized / 255.0
139
+
140
+ # βœ… Original image add karo
141
+ X.append(img_norm)
142
+ y.append(mask_norm)
143
+
144
+ # βœ… Augmentation 1 β€” Horizontal Flip
145
+ X.append(cv2.flip(img_norm, 1))
146
+ y.append(cv2.flip(mask_norm, 1))
147
+
148
+ # βœ… Augmentation 2 β€” Rotation 15 degree
149
+ M = cv2.getRotationMatrix2D((128, 128), 15, 1.0)
150
+ X.append(cv2.warpAffine(img_norm, M, (256, 256)))
151
+ y.append(cv2.warpAffine(mask_norm, M, (256, 256)))
152
+
153
+ # βœ… Augmentation 3 β€” Brightness Change
154
+ bright = np.clip(img_norm * 1.2, 0, 1)
155
+ X.append(bright)
156
+ y.append(mask_norm)
157
+
158
+ X = np.array(X, dtype=np.float32)
159
+ y = np.array(y, dtype=np.float32)
160
+ y = np.expand_dims(y, axis=-1)
161
+
162
+ print("\nβœ… Preprocessing Complete!")
163
+ print(f"Images Shape: {X.shape}")
164
+ print(f"Masks Shape : {y.shape}")
165
+
166
+ # πŸš€ STEP 7 β€” Model Building: U-Net with MobileNetV2
167
+
168
+ from sklearn.model_selection import train_test_split
169
+
170
+ X_train, X_temp, y_train, y_temp = train_test_split(
171
+ X, y, test_size=0.2, random_state=42
172
+ )
173
+
174
+ X_val, X_test, y_val, y_test = train_test_split(
175
+ X_temp, y_temp, test_size=0.5, random_state=42
176
+ )
177
+
178
+ print(f"Training data : {X_train.shape}")
179
+ print(f"Validation data : {X_val.shape}")
180
+ print(f"Test data : {X_test.shape}")
181
+
182
+ from tensorflow.keras.applications import MobileNetV2
183
+ from tensorflow.keras.layers import Input, Conv2D, UpSampling2D, Concatenate, BatchNormalization, Activation, Dropout
184
+ from tensorflow.keras.models import Model
185
+ import tensorflow as tf
186
+
187
+ def build_unet(input_shape):
188
+ inputs = Input(input_shape)
189
+
190
+ base_model = MobileNetV2(input_tensor=inputs, weights="imagenet", include_top=False)
191
+
192
+ # βœ… FIX 1: Encoder freeze karo
193
+ base_model.trainable = False
194
+ for layer in base_model.layers[-30:]:
195
+ layer.trainable = True
196
+
197
+ # Skip connections
198
+ s1 = inputs
199
+ s2 = base_model.get_layer("block_1_expand_relu").output
200
+ s3 = base_model.get_layer("block_3_expand_relu").output
201
+ s4 = base_model.get_layer("block_6_expand_relu").output
202
+ bridge = base_model.get_layer("block_13_expand_relu").output
203
+
204
+ # βœ… FIX 2: Dropout add kiya har decoder block mein
205
+ u1 = UpSampling2D((2, 2))(bridge)
206
+ u1 = Concatenate()([u1, s4])
207
+ u1 = Conv2D(256, 3, padding="same", kernel_initializer="he_normal")(u1)
208
+ u1 = BatchNormalization()(u1)
209
+ u1 = Activation("relu")(u1)
210
+ u1 = Dropout(0.3)(u1) # βœ…
211
+
212
+ u2 = UpSampling2D((2, 2))(u1)
213
+ u2 = Concatenate()([u2, s3])
214
+ u2 = Conv2D(128, 3, padding="same", kernel_initializer="he_normal")(u2)
215
+ u2 = BatchNormalization()(u2)
216
+ u2 = Activation("relu")(u2)
217
+ u2 = Dropout(0.3)(u2) # βœ…
218
+
219
+ u3 = UpSampling2D((2, 2))(u2)
220
+ u3 = Concatenate()([u3, s2])
221
+ u3 = Conv2D(64, 3, padding="same", kernel_initializer="he_normal")(u3)
222
+ u3 = BatchNormalization()(u3)
223
+ u3 = Activation("relu")(u3)
224
+ u3 = Dropout(0.2)(u3) # βœ…
225
+
226
+ u4 = UpSampling2D((2, 2))(u3)
227
+ u4 = Concatenate()([u4, s1])
228
+ u4 = Conv2D(32, 3, padding="same", kernel_initializer="he_normal")(u4)
229
+ u4 = BatchNormalization()(u4)
230
+ u4 = Activation("relu")(u4)
231
+
232
+ outputs = Conv2D(1, 1, activation="sigmoid")(u4)
233
+
234
+ return Model(inputs, outputs)
235
+
236
+ model = build_unet((256, 256, 3))
237
+
238
+ # βœ… FIX 3: Combined Loss
239
+ def dice_coefficient(y_true, y_pred):
240
+ y_true_f = tf.cast(tf.reshape(y_true, [-1]), tf.float32)
241
+ y_pred_f = tf.cast(tf.reshape(y_pred, [-1]), tf.float32)
242
+ intersection = tf.reduce_sum(y_true_f * y_pred_f)
243
+ return (2. * intersection + 1.0) / (tf.reduce_sum(y_true_f) + tf.reduce_sum(y_pred_f) + 1.0)
244
+
245
+ def dice_loss(y_true, y_pred):
246
+ return 1 - dice_coefficient(y_true, y_pred)
247
+
248
+ def combined_loss(y_true, y_pred):
249
+ return dice_loss(y_true, y_pred) + tf.keras.losses.binary_crossentropy(y_true, y_pred)
250
+
251
+ model.compile(
252
+ optimizer=tf.keras.optimizers.Adam(learning_rate=1e-3),
253
+ loss=combined_loss, # βœ… Combined loss
254
+ metrics=[dice_coefficient, "accuracy"]
255
+ )
256
+
257
+ print("βœ… Model Compiled Successfully!")
258
+
259
+ # Training se PEHLE yeh check karo:
260
+ print(f"X_train shape: {X_train.shape}")
261
+ print(f"X_val shape : {X_val.shape}")
262
+ print(f"X_test shape : {X_test.shape}")
263
+
264
+ # πŸš€ STEP 9 β€” Model Training (Fit)
265
+
266
+ from tensorflow.keras.callbacks import ModelCheckpoint, ReduceLROnPlateau, EarlyStopping
267
+
268
+ callbacks = [
269
+ ModelCheckpoint("best_face_model.keras", monitor='val_dice_coefficient',
270
+ mode='max', save_best_only=True, verbose=1),
271
+ ReduceLROnPlateau(monitor='val_loss', factor=0.2, patience=5,
272
+ min_lr=1e-7, verbose=1),
273
+ EarlyStopping(monitor='val_loss', patience=12,
274
+ restore_best_weights=True, verbose=1)
275
+ ]
276
+
277
+ print("πŸš€ Training shuru ho rahi hai!")
278
+
279
+ history = model.fit(
280
+ X_train, y_train,
281
+ validation_data=(X_val, y_val),
282
+ epochs=50,
283
+ batch_size=8,
284
+ callbacks=callbacks,
285
+ shuffle=True
286
+ )
287
+
288
+ print("\nβœ… Training Complete!")
289
+
290
+ # Step - Evaluation Metrix
291
+ from sklearn.metrics import f1_score
292
+ import time
293
+ import numpy as np
294
+
295
+ def evaluate_model(model, X_test, y_test):
296
+ y_pred = model.predict(X_test)
297
+ y_pred_binary = (y_pred > 0.5).astype(np.float32)
298
+
299
+ # 1. Dice Coefficient
300
+ intersection = np.sum(y_test * y_pred_binary)
301
+ dice = (2. * intersection + 1.0) / (
302
+ np.sum(y_test) + np.sum(y_pred_binary) + 1.0
303
+ )
304
+
305
+ # 2. IoU Score
306
+ union = np.sum(y_test) + np.sum(y_pred_binary) - intersection
307
+ iou = intersection / union
308
+
309
+ # 3. F1 Score
310
+ f1 = f1_score(
311
+ y_test.flatten().astype(int),
312
+ y_pred_binary.flatten().astype(int)
313
+ )
314
+
315
+ # 4. βœ… Inference Speed β€” FIXED VERSION
316
+ model.predict(X_test[:1], verbose=0) # Warmup 1
317
+ model.predict(X_test[:1], verbose=0) # Warmup 2
318
+ times = []
319
+ for _ in range(5):
320
+ start = time.time()
321
+ model.predict(X_test[:1], verbose=0)
322
+ times.append((time.time() - start) * 1000)
323
+ speed = np.mean(times)
324
+
325
+ print("="*45)
326
+ print(f"Dice Coefficient : {dice:.4f} (Target >0.92)")
327
+ print(f"IoU Score : {iou:.4f} (Target >0.88)")
328
+ print(f"F1 Score : {f1:.4f} (Target >0.90)")
329
+ print(f"Inference Speed : {speed:.1f}ms (Target <100ms)")
330
+ print("="*45)
331
+
332
+ # Dobara chalao
333
+ evaluate_model(model, X_test, y_test)
334
+
335
+ # STEP 11 β€” Training Curves Plot
336
+
337
+ import matplotlib.pyplot as plt
338
+
339
+ plt.figure(figsize=(12, 4))
340
+
341
+ plt.subplot(1, 2, 1)
342
+ plt.plot(history.history['dice_coefficient'], label='Train Dice')
343
+ plt.plot(history.history['val_dice_coefficient'], label='Val Dice')
344
+ plt.title('Dice Coefficient Progress')
345
+ plt.xlabel('Epoch')
346
+ plt.legend()
347
+
348
+ plt.subplot(1, 2, 2)
349
+ plt.plot(history.history['loss'], label='Train Loss')
350
+ plt.plot(history.history['val_loss'], label='Val Loss')
351
+ plt.title('Loss Progress')
352
+ plt.xlabel('Epoch')
353
+ plt.legend()
354
+
355
+ plt.tight_layout()
356
+ plt.show()
357
+
358
+ import matplotlib.pyplot as plt
359
+
360
+ def visualize_prediction(index):
361
+ img = X_val[index]
362
+ gt_mask = y_val[index]
363
+
364
+ # Model se prediction lo
365
+ pred_mask = model.predict(np.expand_dims(img, axis=0))[0]
366
+
367
+ # Thresholding (0.5 se upar white, niche black)
368
+ pred_mask_binary = (pred_mask > 0.5).astype(np.uint8)
369
+
370
+ plt.figure(figsize=(12, 4))
371
+ plt.subplot(1, 3, 1)
372
+ plt.imshow(img); plt.title("Original Image")
373
+
374
+ plt.subplot(1, 3, 2)
375
+ plt.imshow(gt_mask.squeeze(), cmap='gray'); plt.title("Ground Truth Mask")
376
+
377
+ plt.subplot(1, 3, 3)
378
+ plt.imshow(pred_mask_binary.squeeze(), cmap='gray'); plt.title("Predicted Mask")
379
+ plt.show()
380
+
381
+ # Pehli 3 validation images check karte hain
382
+ for i in [0, 5, 10]:
383
+ visualize_prediction(i)
384
+
385
+ # πŸš€ STEP 12 β€” Improving Accuracy with Hugging Face (SegFormer)
386
+
387
+ !pip install -q transformers datasets
388
+
389
+ from transformers import SegformerImageProcessor, SegformerForSemanticSegmentation
390
+ import torch
391
+ from PIL import Image
392
+
393
+ # 1. Pre-trained Model Load Karein
394
+
395
+ device = "cuda" if torch.cuda.is_available() else "cpu"
396
+
397
+ # Processor images ko transform karega, model segmentation karega
398
+ processor = SegformerImageProcessor.from_pretrained("nvidia/mit-b0")
399
+ hf_model = SegformerForSemanticSegmentation.from_pretrained("nvidia/mit-b0",
400
+ num_labels=1,
401
+ ignore_mismatched_sizes=True).to(device)
402
+
403
+ print("βœ… Hugging Face SegFormer Model Loaded!")
404
+
405
+ # πŸ› οΈ STEP 12 β€” SegFormer Dataset Class
406
+ import torch
407
+ from torch.utils.data import Dataset, DataLoader
408
+ import numpy as np
409
+
410
+ class FaceDataset(Dataset):
411
+ def __init__(self, images, masks, processor):
412
+ self.images = images
413
+ self.masks = masks
414
+ self.processor = processor
415
+
416
+ def __len__(self):
417
+ return len(self.images)
418
+
419
+ def __getitem__(self, idx):
420
+ # Image aur Mask uthayein
421
+ # (X_train already normalized hai, hume original format chahiye processor ke liye)
422
+ image = (self.images[idx] * 255).astype(np.uint8)
423
+ mask = self.masks[idx].squeeze().astype(np.longlong) # SegFormer expects long for masks
424
+
425
+ # Processor se transform karein
426
+ encoded_inputs = self.processor(image, mask, return_tensors="pt")
427
+
428
+ # Squeeze batch dimension jo processor add karta hai
429
+ for k, v in encoded_inputs.items():
430
+ encoded_inputs[k] = v.squeeze(0)
431
+
432
+ return encoded_inputs
433
+
434
+ # 1. Dataset Objects Banayein
435
+ train_dataset = FaceDataset(X_train, y_train, processor)
436
+ val_dataset = FaceDataset(X_val, y_val, processor)
437
+
438
+ # 2. DataLoaders Banayein
439
+ train_dataloader = DataLoader(train_dataset, batch_size=4, shuffle=True)
440
+ val_dataloader = DataLoader(val_dataset, batch_size=4)
441
+
442
+ print(f"βœ… DataLoaders Ready! Training samples: {len(train_dataset)}")
443
+
444
+ # πŸš€ STEP 13 β€” Fine-tuning SegFormer (Training Loop)
445
+
446
+ from tqdm.notebook import tqdm
447
+ from torch.optim import AdamW
448
+
449
+ # 1. Optimizer setup
450
+ optimizer = AdamW(hf_model.parameters(), lr=5e-5)
451
+
452
+ # 2. Training Loop
453
+ num_epochs = 10 # SegFormer jaldi seekh jata hai
454
+ hf_model.train()
455
+
456
+ print("πŸš€ SegFormer Training shuru ho rahi hai...")
457
+
458
+ for epoch in range(num_epochs):
459
+ train_loss = 0
460
+ # Tqdm progress bar ke liye
461
+ pbar = tqdm(train_dataloader, desc=f"Epoch {epoch+1}")
462
+
463
+ for batch in pbar:
464
+ # Data ko GPU/CPU par bhejein
465
+ pixel_values = batch["pixel_values"].to(device)
466
+ labels = batch["labels"].to(device)
467
+
468
+ # Forward pass
469
+ outputs = hf_model(pixel_values=pixel_values, labels=labels)
470
+ loss = outputs.loss
471
+
472
+ # Backward pass
473
+ loss.backward()
474
+ optimizer.step()
475
+ optimizer.zero_grad()
476
+
477
+ train_loss += loss.item()
478
+ pbar.set_postfix({'loss': loss.item()})
479
+
480
+ avg_train_loss = train_loss / len(train_dataloader)
481
+ print(f"βœ… Epoch {epoch+1} Complete | Average Loss: {avg_train_loss:.4f}")
482
+
483
+ print("\nπŸŽ‰ SegFormer Fine-tuning Finished!")
484
+
485
+ # 🎨 STEP 14 β€” SegFormer Prediction & Visualization
486
+
487
+ import torch.nn as nn
488
+
489
+ def visualize_segformer_prediction(index):
490
+ # 1. Validation set se data lein
491
+ inputs = val_dataset[index]
492
+ pixel_values = inputs["pixel_values"].unsqueeze(0).to(device)
493
+ gt_mask = inputs["labels"].numpy()
494
+
495
+ # 2. Prediction karein
496
+ hf_model.eval()
497
+ with torch.no_grad():
498
+ outputs = hf_model(pixel_values=pixel_values)
499
+ logits = outputs.logits # [1, num_labels, height/4, width/4]
500
+
501
+ # 3. Logits ko original image size (256x256) par upsample karein
502
+ upsampled_logits = nn.functional.interpolate(
503
+ logits,
504
+ size=(256, 256),
505
+ mode='bilinear',
506
+ align_corners=False
507
+ )
508
+
509
+ # 4. Binary mask banayein (Squeeze karke threshold lagayein)
510
+ pred_mask = torch.sigmoid(upsampled_logits).cpu().numpy().squeeze()
511
+ pred_mask_binary = (pred_mask > 0.5).astype(np.uint8)
512
+
513
+ # 5. Plotting
514
+ plt.figure(figsize=(12, 4))
515
+
516
+ # Original Image (Pixel values ko denormalize karke dikhayenge)
517
+ display_img = pixel_values.cpu().squeeze().permute(1, 2, 0).numpy()
518
+ display_img = (display_img - display_img.min()) / (display_img.max() - display_img.min())
519
+
520
+ plt.subplot(1, 3, 1)
521
+ plt.imshow(display_img)
522
+ plt.title("Original Image")
523
+
524
+ plt.subplot(1, 3, 2)
525
+ plt.imshow(gt_mask, cmap='gray')
526
+ plt.title("Ground Truth Mask")
527
+
528
+ plt.subplot(1, 3, 3)
529
+ plt.imshow(pred_mask_binary, cmap='gray')
530
+ plt.title("SegFormer Prediction")
531
+
532
+ plt.show()
533
+
534
+ # Pehle 3 validation images par results dekhein
535
+ for i in [0, 5, 10]:
536
+ visualize_segformer_prediction(i)
537
+
538
+ # πŸ’Ύ STEP 15 β€” Model aur Processor ko Save Karein
539
+
540
+ import os
541
+
542
+ # 1. Ek folder banate hain model ke liye
543
+ save_directory = "my_face_segformer_model"
544
+ os.makedirs(save_directory, exist_ok=True)
545
+
546
+ # 2. Model ke weights aur config save karein
547
+ hf_model.save_pretrained(save_directory)
548
+
549
+ # 3. Processor (jo image resize aur normalize karta hai) bhi save karein
550
+ processor.save_pretrained(save_directory)
551
+
552
+ print(f"βœ… Model successfully saved in: {save_directory}")
553
+
554
+ # --- Google Colab Users ke liye ---
555
+ # Agar aap chahte hain ki ye hamesha ke liye safe rahe, toh ise Zip karke download kar lein
556
+ !zip -r face_model.zip my_face_segformer_model/
557
+ print("πŸ“¦ Zip file ban gayi hai! Ab aap ise left side ke 'Files' tab se download kar sakte hain.")
558
+
559
+ from google.colab import drive
560
+ import shutil
561
+ import os
562
+
563
+ # 1. Drive mount karein
564
+ drive.mount('/content/drive')
565
+
566
+ # 2. Aapka bataya hua path define karein
567
+ # Hum Face_Segmentation_Project ke andar 'saved_model' naam ka folder banayenge
568
+ base_path = '/content/drive/MyDrive/Face_Segmentation_Project'
569
+ model_save_path = os.path.join(base_path, 'trained_segformer_model')
570
+
571
+ # 3. Folder banayein agar nahi hai toh
572
+ os.makedirs(model_save_path, exist_ok=True)
573
+
574
+ # 4. Colab ki temporary files ko Drive par copy karein
575
+ source_folder = '/content/my_face_segformer_model'
576
+
577
+ # Purani files clear karke fresh copy karein
578
+ if os.path.exists(model_save_path):
579
+ shutil.rmtree(model_save_path)
580
+
581
+ shutil.copytree(source_folder, model_save_path)
582
+
583
+ print(f"βœ… Kaam ho gaya! Aapka model yahan save hai:")
584
+ print(f"πŸ“‚ {model_save_path}")
585
+
586
+ import os
587
+
588
+ # Actor folders banao
589
+ actors = [
590
+ "Robert_Downey_Jr",
591
+ "Scarlett_Johansson",
592
+ "Chris_Evans",
593
+ "Tom_Cruise",
594
+ "Leonardo_DiCaprio",
595
+ "Brad_Pitt",
596
+ "Chris Hemsworth"
597
+ ]
598
+
599
+ for actor in actors:
600
+ os.makedirs(f"/content/actor_db/{actor}", exist_ok=True)
601
+
602
+ print("βœ… Actor folders ban gaye!")
603
+ print(os.listdir("/content/actor_db"))
604
+
605
+ import requests
606
+ import os
607
+
608
+ actor_images = {
609
+ "Robert_Downey_Jr": [
610
+ "https://wallpapers.com/images/hd/focused-photography-robert-downey-jr-pjs7jatnx0yfofsc.jpg",
611
+ "https://static1.srcdn.com/wordpress/wp-content/uploads/2024/07/instar53643496.jpg"
612
+ ],
613
+ "Scarlett_Johansson": [
614
+ "https://tse2.mm.bing.net/th/id/OIP.OwNfXHWEAynGbQwhmUNQWwHaKk?rs=1&pid=ImgDetMain&o=7&rm=3",
615
+ "https://m.media-amazon.com/images/M/MV5BMjAyNjE1NjgyMF5BMl5BanBnXkFtZTcwMjg0ODY1NA@@._V1_.jpg"
616
+ ],
617
+ "Chris_Evans": [
618
+ "https://cdn.britannica.com/28/215028-050-94E9EA1E/American-actor-Chris-Evans-2019.jpg",
619
+ "https://tse4.mm.bing.net/th/id/OIP._aupdpOey-23R2KHLQd0OgHaLH?rs=1&pid=ImgDetMain&o=7&rm=3"
620
+ ],
621
+ "Tom_Cruise": [
622
+ "https://image.tmdb.org/t/p/original/8qBylBsQf4llkGrWR3qAsOtOU8O.jpg",
623
+ "https://m.media-amazon.com/images/M/MV5BMmU1YWU1NmMtMjAyMi00MjFiLWFmZmUtOTc1ZjI5ODkxYmQyXkEyXkFqcGc@._V1_FMjpg_UX1000_.jpg"
624
+ ],
625
+ "Leonardo_DiCaprio": [
626
+ "https://image.tmdb.org/t/p/original/aLUFp0zWpLVyIOgY0scIpuuKZLE.jpg",
627
+ "https://wallpapers.com/images/hd/leonardo-dicaprio-actor-nl2l96xppg1rj9hz.jpg"
628
+ ],
629
+ "Brad_Pitt": [
630
+ "https://fr.web.img2.acsta.net/pictures/20/02/10/10/37/1374948.jpg",
631
+ "https://www.gratistodo.com/wp-content/uploads/2016/09/Brad-Pitt-7.jpg"
632
+ ],
633
+ "Chris Hemsworth": [
634
+ "https://cdn.britannica.com/92/215392-050-96A4BC1D/Australian-actor-Chris-Hemsworth-2019.jpg",
635
+ "https://static1.cbrimages.com/wordpress/wp-content/uploads/2023/06/chris-hemsworth-thor-love-and-thunder-mcu.jpg"
636
+ ]
637
+ }
638
+
639
+ success = 0
640
+ fail = 0
641
+
642
+ for actor_name, urls in actor_images.items():
643
+ for i, url in enumerate(urls):
644
+ try:
645
+ response = requests.get(url, timeout=15)
646
+ if response.status_code == 200:
647
+ path = f"/content/actor_db/{actor_name}/{i}.jpg"
648
+ with open(path, 'wb') as f:
649
+ f.write(response.content)
650
+ print(f"βœ… {actor_name} β€” photo {i+1} downloaded")
651
+ success += 1
652
+ else:
653
+ print(f"❌ {actor_name} β€” photo {i+1} failed ({response.status_code})")
654
+ fail += 1
655
+ except Exception as e:
656
+ print(f"❌ {actor_name} β€” photo {i+1} error: {e}")
657
+ fail += 1
658
+
659
+ print(f"\nβœ… Success: {success} | ❌ Failed: {fail}")
660
+
661
+ # Verify karo
662
+ print("\nπŸ“ Database Status:")
663
+ for actor in os.listdir("/content/actor_db"):
664
+ photos = os.listdir(f"/content/actor_db/{actor}")
665
+ print(f" {actor}: {len(photos)} photos")
666
+
667
+ !pip install deepface -q
668
+ !pip install tf-keras -q
669
+ print("βœ… DeepFace installed!")
670
+
671
+ # Test Karo
672
+
673
+ from deepface import DeepFace
674
+ import cv2
675
+ import numpy as np
676
+
677
+ # Test β€” ek image pe try karo
678
+ test_img = "/content/actor_db/Robert_Downey_Jr/0.jpg"
679
+
680
+ result = DeepFace.analyze(
681
+ img_path=test_img,
682
+ actions=['age', 'gender'],
683
+ enforce_detection=False
684
+ )
685
+ print("βœ… DeepFace working!")
686
+ print(f"Age: {result[0]['age']}")
687
+ print(f"Gender: {result[0]['dominant_gender']}")
688
+
689
+ # Step 1 β€” Sahi versions install karo
690
+ !pip install tf-keras==2.19.0 -q
691
+ !pip install keras==2.19.0 -q
692
+ print("βœ… Done!")
693
+
694
+ import keras
695
+ import tensorflow as tf
696
+
697
+ def dice_coefficient(y_true, y_pred):
698
+ y_true_f = tf.cast(tf.reshape(y_true,[-1]),tf.float32)
699
+ y_pred_f = tf.cast(tf.reshape(y_pred,[-1]),tf.float32)
700
+ i = tf.reduce_sum(y_true_f*y_pred_f)
701
+ return (2.*i+1.)/(tf.reduce_sum(y_true_f)+tf.reduce_sum(y_pred_f)+1.)
702
+
703
+ def combined_loss(y_true, y_pred):
704
+ return 1-dice_coefficient(y_true,y_pred)+tf.keras.losses.binary_crossentropy(y_true,y_pred)
705
+
706
+ # Pehle load karo
707
+ model = keras.models.load_model(
708
+ "/content/best_face_model.keras",
709
+ custom_objects={
710
+ 'dice_coefficient': dice_coefficient,
711
+ 'combined_loss': combined_loss
712
+ }
713
+ )
714
+
715
+ # Weights alag save karo
716
+ model.save_weights("/content/model_weights.weights.h5")
717
+ print("βœ… Weights saved!")
718
+
719
+ # Commented out IPython magic to ensure Python compatibility.
720
+ # %%writefile /content/app.py
721
+ # import os
722
+ # os.environ['CUDA_VISIBLE_DEVICES'] = '-1'
723
+ # os.environ['TF_CPP_MIN_LOG_LEVEL'] = '3'
724
+ #
725
+ # import streamlit as st
726
+ # import numpy as np
727
+ # import cv2
728
+ # from PIL import Image
729
+ # import tensorflow as tf
730
+ # import time
731
+ # import io
732
+ #
733
+ # st.set_page_config(page_title="Scene Cast AI", page_icon="🎬", layout="wide")
734
+ #
735
+ # st.markdown("""<style>
736
+ # @import url('https://fonts.googleapis.com/css2?family=Syne:wght@700;800&family=DM+Sans:wght@300;400&display=swap');
737
+ # :root{--bg:#0a0a0f;--card:#16161f;--gold:#f5c518;--blue:#4cc9f0;--text:#f0f0f5;--muted:#7a7a8c;--border:rgba(245,197,24,0.15);}
738
+ # html,body,[class*="css"]{font-family:'DM Sans',sans-serif;background:var(--bg);color:var(--text);}
739
+ # .stApp{background:var(--bg);}
740
+ # #MainMenu,footer,header{visibility:hidden;}
741
+ # [data-testid="stSidebar"]{background:#111118;border-right:1px solid var(--border);}
742
+ # .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;}
743
+ # .card{background:var(--card);border:1px solid var(--border);border-radius:16px;padding:1.2rem;position:relative;overflow:hidden;}
744
+ # .card::before{content:'';position:absolute;top:0;left:0;right:0;height:2px;background:linear-gradient(90deg,var(--gold),var(--blue));}
745
+ # .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;}
746
+ # .metric-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:1rem;margin:1rem 0;}
747
+ # .metric{background:var(--card);border:1px solid var(--border);border-radius:14px;padding:1rem;text-align:center;}
748
+ # .mval{font-family:'Syne',sans-serif;font-size:1.5rem;font-weight:800;color:var(--gold);}
749
+ # .mval.warn{color:#fb923c;}.mval.fast{color:var(--blue);}
750
+ # .mlbl{color:var(--muted);font-size:0.75rem;text-transform:uppercase;}
751
+ # .mtgt{font-size:0.65rem;color:var(--muted);margin-top:0.2rem;}
752
+ # .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;}
753
+ # .sec{display:flex;align-items:center;gap:0.8rem;margin:1.5rem 0 1rem;}
754
+ # .sec-line{flex:1;height:1px;background:var(--border);}
755
+ # .sec-title{font-family:'Syne',sans-serif;font-size:0.75rem;font-weight:700;letter-spacing:0.2em;text-transform:uppercase;color:var(--muted);}
756
+ # .actor-card{background:var(--card);border:1px solid rgba(245,197,24,0.3);border-radius:16px;padding:1rem;text-align:center;}
757
+ # .actor-name{font-family:'Syne',sans-serif;font-size:1rem;font-weight:800;color:var(--gold);margin:0.5rem 0 0.2rem;}
758
+ # .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;}
759
+ # </style>""", unsafe_allow_html=True)
760
+ #
761
+ # # ── Model Architecture Rebuild + Weights Load ──
762
+ # from tensorflow.keras.applications import MobileNetV2
763
+ # from tensorflow.keras.layers import Input, Conv2D, UpSampling2D, Concatenate, BatchNormalization, Activation, Dropout
764
+ # from tensorflow.keras.models import Model
765
+ #
766
+ # def dice_coefficient(y_true, y_pred):
767
+ # y_true_f = tf.cast(tf.reshape(y_true,[-1]),tf.float32)
768
+ # y_pred_f = tf.cast(tf.reshape(y_pred,[-1]),tf.float32)
769
+ # i = tf.reduce_sum(y_true_f*y_pred_f)
770
+ # return (2.*i+1.)/(tf.reduce_sum(y_true_f)+tf.reduce_sum(y_pred_f)+1.)
771
+ #
772
+ # def combined_loss(y_true, y_pred):
773
+ # return 1-dice_coefficient(y_true,y_pred)+tf.keras.losses.binary_crossentropy(y_true,y_pred)
774
+ #
775
+ # def build_unet(input_shape=(256,256,3)):
776
+ # inputs = Input(input_shape)
777
+ # base = MobileNetV2(input_tensor=inputs, weights=None, include_top=False)
778
+ # base.trainable = False
779
+ # s1=inputs
780
+ # s2=base.get_layer("block_1_expand_relu").output
781
+ # s3=base.get_layer("block_3_expand_relu").output
782
+ # s4=base.get_layer("block_6_expand_relu").output
783
+ # bridge=base.get_layer("block_13_expand_relu").output
784
+ # u1=UpSampling2D((2,2))(bridge)
785
+ # u1=Concatenate()([u1,s4])
786
+ # u1=Conv2D(256,3,padding="same",kernel_initializer="he_normal")(u1)
787
+ # u1=BatchNormalization()(u1); u1=Activation("relu")(u1); u1=Dropout(0.3)(u1)
788
+ # u2=UpSampling2D((2,2))(u1)
789
+ # u2=Concatenate()([u2,s3])
790
+ # u2=Conv2D(128,3,padding="same",kernel_initializer="he_normal")(u2)
791
+ # u2=BatchNormalization()(u2); u2=Activation("relu")(u2); u2=Dropout(0.3)(u2)
792
+ # u3=UpSampling2D((2,2))(u2)
793
+ # u3=Concatenate()([u3,s2])
794
+ # u3=Conv2D(64,3,padding="same",kernel_initializer="he_normal")(u3)
795
+ # u3=BatchNormalization()(u3); u3=Activation("relu")(u3); u3=Dropout(0.2)(u3)
796
+ # u4=UpSampling2D((2,2))(u3)
797
+ # u4=Concatenate()([u4,s1])
798
+ # u4=Conv2D(32,3,padding="same",kernel_initializer="he_normal")(u4)
799
+ # u4=BatchNormalization()(u4); u4=Activation("relu")(u4)
800
+ # outputs=Conv2D(1,1,activation="sigmoid")(u4)
801
+ # return Model(inputs,outputs)
802
+ #
803
+ # @st.cache_resource(show_spinner=False)
804
+ # def load_model():
805
+ # with tf.device('/CPU:0'):
806
+ # m = build_unet()
807
+ # m.load_weights("/content/model_weights.weights.h5", by_name=True, skip_mismatch=True)
808
+ # m.compile(
809
+ # optimizer=tf.keras.optimizers.Adam(1e-4),
810
+ # loss=combined_loss,
811
+ # metrics=[dice_coefficient]
812
+ # )
813
+ # return m
814
+ #
815
+ # def create_overlay(image, mask):
816
+ # img=cv2.resize(np.array(image),(256,256))
817
+ # cm=np.zeros_like(img); cm[mask>127]=[245,197,24]
818
+ # ov=cv2.addWeighted(img,0.55,cm,0.45,0)
819
+ # ctrs,_=cv2.findContours(mask,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
820
+ # cv2.drawContours(ov,ctrs,-1,(245,197,24),2)
821
+ # return ov
822
+ #
823
+ # def face_count(mask):
824
+ # ctrs,_=cv2.findContours(mask,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
825
+ # return len([c for c in ctrs if cv2.contourArea(c)>256*256*0.005])
826
+ #
827
+ # def img_bytes(arr):
828
+ # buf=io.BytesIO(); Image.fromarray(arr).save(buf,format="PNG"); return buf.getvalue()
829
+ #
830
+ # def get_face_crops(image,mask):
831
+ # img=cv2.resize(np.array(image),(256,256))
832
+ # ctrs,_=cv2.findContours(mask,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
833
+ # crops=[]
834
+ # for c in ctrs:
835
+ # if cv2.contourArea(c)>256*256*0.005:
836
+ # x,y,w,h=cv2.boundingRect(c)
837
+ # crop=img[max(0,y-10):min(255,y+h+10),max(0,x-10):min(255,x+w+10)]
838
+ # if crop.size>0: crops.append(crop)
839
+ # return crops
840
+ #
841
+ # def identify_actors(crops):
842
+ # results=[]; db="/content/actor_db"
843
+ # if not os.path.exists(db): return results
844
+ # has_photos=any(len(os.listdir(f"{db}/{a}"))>0 for a in os.listdir(db) if os.path.isdir(f"{db}/{a}"))
845
+ # if not has_photos: return results
846
+ # try:
847
+ # from deepface import DeepFace
848
+ # for crop in crops:
849
+ # try:
850
+ # dfs=DeepFace.find(img_path=crop,db_path=db,model_name="VGG-Face",enforce_detection=False,silent=True)
851
+ # if len(dfs)>0 and len(dfs[0])>0:
852
+ # best=dfs[0].iloc[0]
853
+ # name=best['identity'].split('/')[-2].replace('_',' ')
854
+ # dist=best.get('distance',1)
855
+ # conf=max(0,(1-dist)*100)
856
+ # results.append({"name":name,"confidence":conf})
857
+ # else:
858
+ # results.append({"name":"Unknown Actor","confidence":0})
859
+ # except:
860
+ # results.append({"name":"Unknown Actor","confidence":0})
861
+ # except ImportError:
862
+ # pass
863
+ # return results
864
+ #
865
+ # with st.sidebar:
866
+ # st.markdown("""<div style="text-align:center;padding:1rem 0 1.5rem;">
867
+ # <div style="font-size:2.5rem;">🎬</div>
868
+ # <div style="font-family:'Syne',sans-serif;font-weight:800;color:#f5c518;">Scene Cast AI</div>
869
+ # <div style="font-size:0.75rem;color:#7a7a8c;">Face Segmentation Engine</div>
870
+ # </div>""",unsafe_allow_html=True)
871
+ # st.markdown("**βš™οΈ SETTINGS**")
872
+ # threshold=st.slider("Confidence Threshold",0.1,0.9,0.5,0.05)
873
+ # show_ov=st.checkbox("Face Overlay",value=True)
874
+ # show_mask=st.checkbox("Binary Mask",value=True)
875
+ # show_conf=st.checkbox("Confidence Map",value=False)
876
+ # show_actor=st.checkbox("🎭 Actor Recognition",value=True)
877
+ # st.markdown("---")
878
+ # st.markdown("""**πŸ“Š MODEL INFO**
879
+ # <div style="font-size:0.8rem;color:#7a7a8c;line-height:1.9;">
880
+ # πŸ—οΈ <b style="color:#f0f0f5;">Architecture:</b> U-Net<br>
881
+ # πŸ”§ <b style="color:#f0f0f5;">Encoder:</b> MobileNetV2<br>
882
+ # πŸ“¦ <b style="color:#f0f0f5;">Input:</b> 256Γ—256<br>
883
+ # πŸ“ˆ <b style="color:#f0f0f5;">Val Dice:</b> 0.8742
884
+ # </div>""",unsafe_allow_html=True)
885
+ #
886
+ # st.markdown("""<div style="text-align:center;padding:2rem 1rem 1.5rem;">
887
+ # <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>
888
+ # <h1 class="hero-title">Scene Cast AI</h1>
889
+ # <p style="color:#7a7a8c;font-size:1rem;max-width:480px;margin:0.5rem auto;">Real-time face segmentation + actor identification.</p>
890
+ # <div style="width:60px;height:2px;background:linear-gradient(90deg,#f5c518,#4cc9f0);margin:1.2rem auto 0;border-radius:2px;"></div>
891
+ # </div>""",unsafe_allow_html=True)
892
+ #
893
+ # with st.spinner("πŸ”„ Loading AI Model..."):
894
+ # try:
895
+ # model=load_model()
896
+ # st.success("βœ… Model loaded!", icon="πŸ€–")
897
+ # except Exception as e:
898
+ # st.error(f"❌ Error: {e}")
899
+ # st.stop()
900
+ #
901
+ # 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)
902
+ # f=st.file_uploader("Upload",type=["jpg","jpeg","png","webp"],label_visibility="collapsed")
903
+ #
904
+ # if f:
905
+ # # πŸ”₯ FIX: Streamlit upload β†’ OpenCV decode
906
+ # file_bytes = np.asarray(bytearray(f.read()), dtype=np.uint8)
907
+ # img = cv2.imdecode(file_bytes, cv2.IMREAD_COLOR)
908
+ #
909
+ # if img is None:
910
+ # st.error("❌ Image read nahi ho pa rahi. Dusri image try karo.")
911
+ # st.stop()
912
+ #
913
+ # img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
914
+ # image = Image.fromarray(img)
915
+ #
916
+ # # πŸ‘‡ same code as before
917
+ # ir = cv2.resize(np.array(image),(256,256))/255.0
918
+ # ii = np.expand_dims(ir,0).astype(np.float32)
919
+ #
920
+ # with st.spinner("🧠 Analyzing..."):
921
+ # with tf.device('/CPU:0'):
922
+ # t0 = time.time()
923
+ # pred = model.predict(ii,verbose=0)[0]
924
+ # spd = (time.time()-t0)*1000
925
+ #
926
+ # mask = (pred.squeeze()>threshold).astype(np.uint8)*255
927
+ # fc = face_count(mask)
928
+ # cov = (np.sum(mask>0)/(256*256))*100
929
+ #
930
+ # 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)
931
+ #
932
+ # ncols = 1+show_ov+show_mask+show_conf
933
+ # dcols = st.columns(ncols)
934
+ # with dcols[0]:
935
+ # st.markdown('<div class="card"><div class="label">🎬 Original Frame</div>',unsafe_allow_html=True)
936
+ # st.image(image,use_container_width=True)
937
+ # st.markdown(f'<div class="info">πŸ“ {image.width}Γ—{image.height}px | πŸ‘₯ ~{fc} face(s)</div></div>',unsafe_allow_html=True)
938
+ # idx=1
939
+ # if show_ov:
940
+ # ov=create_overlay(image,mask)
941
+ # with dcols[idx]:
942
+ # st.markdown('<div class="card"><div class="label">✨ Face Overlay</div>',unsafe_allow_html=True)
943
+ # st.image(ov,use_container_width=True)
944
+ # st.markdown(f'<div class="info">🟑 Gold=face | {cov:.1f}%</div></div>',unsafe_allow_html=True)
945
+ # idx+=1
946
+ # if show_mask:
947
+ # with dcols[idx]:
948
+ # st.markdown('<div class="card"><div class="label">πŸ”² Binary Mask</div>',unsafe_allow_html=True)
949
+ # st.image(mask,use_container_width=True)
950
+ # st.markdown(f'<div class="info">⬜ White=face | {threshold:.2f}</div></div>',unsafe_allow_html=True)
951
+ # idx+=1
952
+ # if show_conf:
953
+ # cm=cv2.applyColorMap((pred.squeeze()*255).astype(np.uint8),cv2.COLORMAP_INFERNO)
954
+ # cm=cv2.cvtColor(cm,cv2.COLOR_BGR2RGB)
955
+ # with dcols[idx]:
956
+ # st.markdown('<div class="card"><div class="label">🌑️ Confidence</div>',unsafe_allow_html=True)
957
+ # st.image(cm,use_container_width=True)
958
+ # st.markdown('<div class="info">πŸ”΄ Hot=face</div></div>',unsafe_allow_html=True)
959
+ # if show_actor:
960
+ # 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)
961
+ # with st.spinner("πŸ” Identifying..."):
962
+ # crops=get_face_crops(image,mask); actors=identify_actors(crops)
963
+ # if actors:
964
+ # acols=st.columns(min(len(actors),4))
965
+ # for i,a in enumerate(actors):
966
+ # cc="#4ade80" if a['confidence']>60 else "#fb923c"
967
+ # with acols[i%4]:
968
+ # st.markdown(f"""<div class="actor-card"><div style="font-size:2rem;">🎭</div>
969
+ # <div class="actor-name">{a['name']}</div>
970
+ # <div style="font-size:0.78rem;color:{cc};">Confidence: {a['confidence']:.1f}%</div>
971
+ # </div>""",unsafe_allow_html=True)
972
+ # else:
973
+ # st.info("πŸ” Actor DB mein photos upload karo!",icon="ℹ️")
974
+ # 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)
975
+ # sc="fast" if spd<100 else "warn"
976
+ # st.markdown(f"""<div class="metric-grid">
977
+ # <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>
978
+ # <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>
979
+ # <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>
980
+ # <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>
981
+ # </div>""",unsafe_allow_html=True)
982
+ # c1,c2,c3=st.columns(3)
983
+ # for col,icon,val,lbl,clr in [(c1,"πŸ‘₯",str(fc),"Faces","#f5c518"),(c2,"πŸ“Š",f"{cov:.1f}%","Coverage","#4cc9f0"),(c3,"🎚️",f"{threshold:.2f}","Threshold","#4ade80")]:
984
+ # with col:
985
+ # st.markdown(f"""<div class="card" style="text-align:center;padding:1rem;">
986
+ # <div style="font-size:2rem;">{icon}</div>
987
+ # <div style="font-family:'Syne',sans-serif;font-size:1.8rem;font-weight:800;color:{clr};">{val}</div>
988
+ # <div style="color:#7a7a8c;font-size:0.78rem;text-transform:uppercase;">{lbl}</div>
989
+ # </div>""",unsafe_allow_html=True)
990
+ # 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)
991
+ # d1,d2,d3=st.columns(3)
992
+ # with d1:
993
+ # st.download_button("⬇️ Mask",img_bytes(mask),"mask.png","image/png",use_container_width=True)
994
+ # with d2:
995
+ # ov2=create_overlay(image,mask)
996
+ # st.download_button("⬇️ Overlay",img_bytes(ov2),"overlay.png","image/png",use_container_width=True)
997
+ # with d3:
998
+ # log=f"File:{f.name}\nFaces:{fc}\nSpeed:{spd:.1f}ms\nDice:0.8845\nIoU:0.7929"
999
+ # st.download_button("⬇️ Log",log,"log.txt","text/plain",use_container_width=True)
1000
+ # else:
1001
+ # 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;">
1002
+ # <div style="font-size:4rem;">🎬</div>
1003
+ # <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>
1004
+ # <div style="color:#7a7a8c;">Upload movie screenshot β†’ AI detects + identifies actors!</div>
1005
+ # </div>""",unsafe_allow_html=True)
1006
+
1007
+ !sed -i 's/use_container_width=True/use_column_width=True/g' /content/app.py
1008
+
1009
+ # Yeh cell chalao β€” warning fix hogi
1010
+ !sed -i 's/use_column_width=True/use_container_width=True/g' /content/app.py
1011
+ print("βœ… Fixed!")
1012
+
1013
+ !pip install streamlit pyngrok -q
1014
+
1015
+ # Ek Cell Mein Sab
1016
+ !fuser -k 8501/tcp
1017
+ !pkill -f streamlit
1018
+
1019
+ import time
1020
+ time.sleep(2)
1021
+
1022
+ import subprocess, threading
1023
+
1024
+ def run():
1025
+ subprocess.Popen([
1026
+ 'streamlit', 'run', '/content/app.py',
1027
+ '--server.port=8501',
1028
+ '--server.headless=true',
1029
+ '--server.enableCORS=false',
1030
+ '--server.enableXsrfProtection=false'
1031
+ ])
1032
+
1033
+ threading.Thread(target=run).start()
1034
+ time.sleep(15)
1035
+
1036
+ from google.colab.output import eval_js
1037
+ url = eval_js("google.colab.kernel.proxyPort(8501)")
1038
+ print(f"βœ… URL: {url}")
requirements.txt CHANGED
@@ -1,3 +1,8 @@
1
- altair
2
- pandas
3
- streamlit
 
 
 
 
 
 
1
+ streamlit
2
+ pandas
3
+ numpy
4
+ matplotlib
5
+ seaborn
6
+ scikit-learn
7
+ tensorflow
8
+ keras