manii576 commited on
Commit
fbec667
·
verified ·
1 Parent(s): 134bd1c

Upload 2 files

Browse files
Files changed (2) hide show
  1. face_shape_model_v2.h5 +3 -0
  2. main_app.py +149 -0
face_shape_model_v2.h5 ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:08d08a78219924ab0d9b8d475696f8bf912fd78dc4615cb924fa21c81f2db8d6
3
+ size 25822424
main_app.py ADDED
@@ -0,0 +1,149 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import cv2
3
+ import mediapipe as mp
4
+ import numpy as np
5
+ import os
6
+ os.environ['TF_CPP_MIN_LOG_LEVEL'] = '3'
7
+ import tensorflow as tf
8
+ from tensorflow.keras.models import load_model
9
+ from PIL import Image
10
+
11
+ # --- Setup ---
12
+ BASE_PATH = r"C:\Users\MANII\Desktop\AI_Hairstyle_Project"
13
+ MODEL_PATH = os.path.join(BASE_PATH, "face_shape_model_v2.h5")
14
+
15
+ # MediaPipe
16
+ BaseOptions = mp.tasks.BaseOptions
17
+ FaceDetector = mp.tasks.vision.FaceDetector
18
+ FaceDetectorOptions = mp.tasks.vision.FaceDetectorOptions
19
+ VisionRunningMode = mp.tasks.vision.RunningMode
20
+ TFLITE_PATH = os.path.join(BASE_PATH, "blaze_face_short_range.tflite")
21
+
22
+ # Class Labels
23
+ CLASS_NAMES = {0: 'Heart', 1: 'Oblong', 2: 'Oval', 3: 'Round', 4: 'Square'}
24
+
25
+ # Hairstyle Recommendations
26
+ RECOMMENDATIONS = {
27
+ 'Heart': {
28
+ 'styles': ['Side Part', 'Quiff', 'Fringe'],
29
+ 'avoid': 'Volume on top',
30
+ 'reason': 'Chin area balanced ho jata hai'
31
+ },
32
+ 'Oblong': {
33
+ 'styles': ['Buzz Cut', 'Crop Top', 'Side Swept'],
34
+ 'avoid': 'Long straight styles',
35
+ 'reason': 'Face width add hoti hai'
36
+ },
37
+ 'Oval': {
38
+ 'styles': ['Any Style', 'Undercut', 'Pompadour'],
39
+ 'avoid': 'Kuch bhi avoid nahi',
40
+ 'reason': 'Oval face sab styles suit karta hai'
41
+ },
42
+ 'Round': {
43
+ 'styles': ['Fade', 'Mohawk', 'Textured Top'],
44
+ 'avoid': 'Bowl cut',
45
+ 'reason': 'Face elongated dikhta hai'
46
+ },
47
+ 'Square': {
48
+ 'styles': ['Buzz Cut', 'Crew Cut', 'Short Sides'],
49
+ 'avoid': 'Flat top',
50
+ 'reason': 'Strong jawline complement hoti hai'
51
+ }
52
+ }
53
+
54
+ # Load ML Model
55
+ @st.cache_resource
56
+ def load_face_model():
57
+ return load_model(MODEL_PATH)
58
+
59
+ ml_model = load_face_model()
60
+
61
+ # --- UI ---
62
+ st.set_page_config(page_title="AI Men's Hairstyle", layout="centered")
63
+ st.title("✂️ Men's AI Virtual Hairstyle Try-On")
64
+ st.markdown("Photo upload karo — AI face shape detect karega aur best hairstyle suggest karega")
65
+
66
+ uploaded_file = st.file_uploader("Apni Photo Upload Karein", type=["jpg", "jpeg", "png"])
67
+
68
+ if uploaded_file is not None:
69
+ file_bytes = np.asarray(bytearray(uploaded_file.read()), dtype=np.uint8)
70
+ img = cv2.imdecode(file_bytes, 1)
71
+ img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
72
+
73
+ st.image(img_rgb, caption="Uploaded Photo", width=300)
74
+
75
+ with st.spinner("AI analyze kar raha hai..."):
76
+
77
+ # --- Face Shape Prediction ---
78
+ img_resized = cv2.resize(img_rgb, (224, 224))
79
+ img_array = np.expand_dims(img_resized / 255.0, axis=0)
80
+ predictions = ml_model.predict(img_array)
81
+ predicted_class = np.argmax(predictions[0])
82
+ confidence = predictions[0][predicted_class] * 100
83
+ face_shape = CLASS_NAMES[predicted_class]
84
+
85
+ # --- Results ---
86
+ st.success(f" Face Shape Detected: **{face_shape}** ({confidence:.1f}% confidence)")
87
+
88
+ rec = RECOMMENDATIONS[face_shape]
89
+
90
+ col1, col2 = st.columns(2)
91
+ with col1:
92
+ st.subheader(" Recommended Styles")
93
+ for style in rec['styles']:
94
+ st.write(f"• {style}")
95
+ st.caption(f"Why: {rec['reason']}")
96
+
97
+ with col2:
98
+ st.subheader(" Avoid")
99
+ st.write(rec['avoid'])
100
+
101
+ # --- Virtual Try-On ---
102
+ st.subheader("🎭 Virtual Try-On")
103
+ style_choice = st.selectbox("Hairstyle choose karo:", rec['styles'] + ['Buzz Cut', 'Second Style'])
104
+
105
+ hair_file = "buzz_cut.png" if "Buzz" in style_choice else "style.png"
106
+ hair_path = os.path.join(BASE_PATH, hair_file)
107
+ hair = cv2.imread(hair_path, cv2.IMREAD_UNCHANGED)
108
+
109
+ if hair is not None:
110
+ options = FaceDetectorOptions(
111
+ base_options=BaseOptions(model_asset_path=TFLITE_PATH),
112
+ running_mode=VisionRunningMode.IMAGE
113
+ )
114
+ with FaceDetector.create_from_options(options) as detector:
115
+ mp_image = mp.Image(image_format=mp.ImageFormat.SRGB, data=img_rgb)
116
+ result = detector.detect(mp_image)
117
+
118
+ if result.detections:
119
+ detection = result.detections[0]
120
+ bbox = detection.bounding_box
121
+ h, w, _ = img_rgb.shape
122
+
123
+ face_w = int(bbox.width * 1.1)
124
+ face_h = int(bbox.height * 0.6)
125
+ hair_resized = cv2.resize(hair, (face_w, face_h))
126
+
127
+ x1 = max(0, bbox.origin_x - int(face_w * 0.1))
128
+ y1 = max(0, bbox.origin_y - int(face_h * 0.7))
129
+ x2 = min(w, x1 + face_w)
130
+ y2 = min(h, y1 + face_h)
131
+
132
+ output = img_rgb.copy()
133
+ hair_crop = hair_resized[0:(y2-y1), 0:(x2-x1)]
134
+
135
+ if hair_crop.shape[2] == 4:
136
+ alpha = hair_crop[:,:,3] / 255.0
137
+ for c in range(3):
138
+ output[y1:y2, x1:x2, c] = (
139
+ hair_crop[:,:,c] * alpha +
140
+ output[y1:y2, x1:x2, c] * (1 - alpha)
141
+ )
142
+ else:
143
+ output[y1:y2, x1:x2] = hair_crop[:,:,:3]
144
+
145
+ st.image(output, caption=f"Try-On: {style_choice}", width=300)
146
+ else:
147
+ st.warning("Face detect nahi hua try-on ke liye.")
148
+ else:
149
+ st.error(f"Hair image nahi mili: {hair_path}")