ostemshaug commited on
Commit
1258ce8
Β·
verified Β·
1 Parent(s): 912f2fa

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +111 -116
app.py CHANGED
@@ -2,13 +2,13 @@ import gradio as gr
2
  from transformers import pipeline
3
  from PIL import Image
4
 
5
- # ---------- 1. Load model (AI part) ----------
6
  emotion_model = pipeline(
7
  task="image-classification",
8
  model="trpakov/vit-face-expression"
9
  )
10
 
11
- # ---------- 2. Mood β†’ playlist mapping (Spotify-only, rule-based part) ----------
12
  mood_to_songs = {
13
  "happy": [
14
  "Happy – Pharrell Williams (https://open.spotify.com/search/Happy%20Pharrell%20Williams)",
@@ -42,165 +42,160 @@ mood_to_songs = {
42
  ]
43
  }
44
 
45
-
46
- # ---------- 3. Core logic ----------
47
- def analyze_image(image, min_confidence: float = 0.40) -> str:
48
- """Main function: numpy image β†’ markdown text."""
49
  if image is None:
50
- return "Please upload a photo with a clear view of your face πŸ™‚"
51
 
52
- # Gradio gives a numpy array; convert to PIL
53
  img = Image.fromarray(image).convert("RGB")
54
-
55
- # AI: emotion detection
56
  results = emotion_model(img)
 
57
  top = results[0]
58
  raw_label = top["label"].lower().strip()
59
  score = float(top["score"])
60
 
61
- # Rule-based playlist choice
62
- if (score < min_confidence) or (raw_label not in mood_to_songs):
63
- final_mood = "neutral"
64
- else:
65
- final_mood = raw_label
 
66
 
67
- songs = mood_to_songs[final_mood]
68
 
69
- # Markdown output
70
- text = f"### Detected mood: **{final_mood.capitalize()}** 🧠🎡\n"
71
- text += f"Confidence: **{score:.2f}** (raw model label: `{raw_label}`)\n\n"
72
- text += "#### Recommended Spotify tracks / playlists:\n"
73
  for s in songs:
74
  text += f"- {s}\n"
75
 
76
- text += "\n<details><summary>Show raw model predictions</summary>\n\n"
 
 
 
 
 
77
  for r in results:
78
- text += f"- **{r['label']}**: {r['score']:.2f}\n"
79
- text += "\n</details>"
 
80
 
81
  return text
82
 
83
 
84
- # ---------- 4. UI (Spotify x iOS inspired, using inline styles) ----------
85
  with gr.Blocks() as demo:
86
 
87
- # Header card
88
- gr.HTML(
89
- """
90
  <div style="
91
- background: radial-gradient(circle at top left, #1f2933 0, #020617 45%, #020617 100%);
92
- border-radius: 24px;
93
- padding: 20px 24px;
94
- margin: 16px auto 20px auto;
95
- max-width: 1100px;
96
- box-shadow: 0 18px 45px rgba(0,0,0,0.6);
97
- border: 1px solid rgba(148,163,184,0.25);
98
- color: #e5e7eb;
99
- font-family: system-ui, -apple-system, BlinkMacSystemFont, 'SF Pro Text', 'Segoe UI', sans-serif;
100
  ">
101
- <div style="font-size: 2.1rem; font-weight: 700; letter-spacing: -0.03em;">
102
  🌊 MoodWave
103
  </div>
104
- <div style="opacity: 0.85; font-size: 0.95rem; margin-top: 4px;">
105
- AI-powered mood-based music recommendations –
106
- <span style="color:#1DB954; font-weight:600;">Spotify only</span>
107
  </div>
108
- <p style="margin-top: 10px; font-size: 0.95rem; line-height: 1.5;">
109
- Upload a selfie or any face picture and MoodWave will:<br>
110
- 1. Detect your <b>emotion</b> using a pre-trained computer vision model.<br>
111
- 2. Suggest a short <b>Spotify playlist</b> that matches your current vibe.
112
  </p>
113
  </div>
114
- """
115
- )
116
 
117
  with gr.Row():
118
  # LEFT: upload
119
- with gr.Column(scale=1):
120
- gr.HTML(
121
- """
122
  <div style="
123
- background: #111827;
124
- border-radius: 20px;
125
- padding: 16px 18px;
126
- margin: 0 auto 12px auto;
127
- max-width: 540px;
128
- box-shadow: 0 12px 32px rgba(0,0,0,0.5);
129
- border: 1px solid rgba(55,65,81,0.7);
130
- color: #e5e7eb;
131
- font-family: system-ui, -apple-system, BlinkMacSystemFont, 'SF Pro Text', 'Segoe UI', sans-serif;
132
  ">
133
- <h3 style="margin: 0 0 4px 0; font-size: 1.1rem;">1. Upload your photo</h3>
134
- <p style="margin: 0; font-size: 0.9rem; opacity: 0.85;">
135
- Use a clear face photo (like a profile picture) for better emotion detection.
136
- </p>
137
  </div>
138
- """
139
- )
140
- image_input = gr.Image(type="numpy", label="Face photo", height=320)
141
 
142
  submit_btn = gr.Button(
143
- "🎧 Analyze mood & suggest Spotify music",
144
- elem_id="mw-main-button"
145
  )
146
 
147
  # RIGHT: result
148
- with gr.Column(scale=1):
149
- gr.HTML(
150
- """
151
  <div style="
152
- background: #111827;
153
- border-radius: 20px;
154
- padding: 16px 18px;
155
- margin: 0 auto 12px auto;
156
- max-width: 540px;
157
- box-shadow: 0 12px 32px rgba(0,0,0,0.5);
158
- border: 1px solid rgba(55,65,81,0.7);
159
- color: #e5e7eb;
160
- font-family: system-ui, -apple-system, BlinkMacSystemFont, 'SF Pro Text', 'Segoe UI', sans-serif;
161
  ">
162
- <h3 style="margin: 0 0 4px 0; font-size: 1.1rem;">2. Mood & recommendations</h3>
163
- <p style="margin: 0; font-size: 0.9rem; opacity: 0.85;">
164
- The detected mood and Spotify suggestions will appear below.
165
- </p>
166
  </div>
167
- """
168
- )
169
- output_md = gr.Markdown(value="Waiting for an image…")
170
 
171
- # Footer / technical card
172
- gr.HTML(
173
- """
 
174
  <div style="
175
- background: #020617;
176
- border-radius: 20px;
177
- padding: 16px 18px;
178
- margin: 8px auto 24px auto;
179
- max-width: 1100px;
180
- box-shadow: 0 10px 28px rgba(0,0,0,0.6);
181
- border: 1px solid rgba(30,64,175,0.6);
182
- color: #e5e7eb;
183
- font-family: system-ui, -apple-system, BlinkMacSystemFont, 'SF Pro Text', 'Segoe UI', sans-serif;
184
- font-size: 0.9rem;
185
  ">
186
- <h4 style="margin-top: 0;">How it works (technical view)</h4>
187
- <ul style="margin-left: 1.1rem;">
188
- <li>Uses a Hugging Face <code>transformers</code> <b>image-classification pipeline</b></li>
189
- <li>Model: <code>trpakov/vit-face-expression</code> (Vision Transformer fine-tuned for facial expressions)</li>
190
- <li>The predicted emotion label feeds a simple <b>rule-based recommender</b> (Python dictionary)</li>
191
- <li>Built with <b>Python + Gradio</b>, deployed on <b>Hugging Face Spaces</b></li>
192
- <li>All suggestions are <b>Spotify</b> search links for tracks or playlists</li>
193
- </ul>
194
  </div>
195
- """
196
- )
197
-
198
- # Wire button to function
199
- submit_btn.click(
200
- fn=analyze_image,
201
- inputs=image_input,
202
- outputs=output_md
203
- )
 
 
 
 
 
 
 
 
 
 
 
 
204
 
205
 
206
  if __name__ == "__main__":
 
2
  from transformers import pipeline
3
  from PIL import Image
4
 
5
+ # ---------- 1. Load model ----------
6
  emotion_model = pipeline(
7
  task="image-classification",
8
  model="trpakov/vit-face-expression"
9
  )
10
 
11
+ # ---------- 2. Spotify-only playlists ----------
12
  mood_to_songs = {
13
  "happy": [
14
  "Happy – Pharrell Williams (https://open.spotify.com/search/Happy%20Pharrell%20Williams)",
 
42
  ]
43
  }
44
 
45
+ # ---------- 3. AI logic ----------
46
+ def analyze_image(image, min_confidence: float = 0.40):
 
 
47
  if image is None:
48
+ return "Please upload a photo πŸ™‚"
49
 
 
50
  img = Image.fromarray(image).convert("RGB")
 
 
51
  results = emotion_model(img)
52
+
53
  top = results[0]
54
  raw_label = top["label"].lower().strip()
55
  score = float(top["score"])
56
 
57
+ mood = raw_label if raw_label in mood_to_songs and score >= min_confidence else "neutral"
58
+ songs = mood_to_songs[mood]
59
+
60
+ text = f"""
61
+ ### 🎡 Detected mood: **{mood.capitalize()}**
62
+ **Confidence:** {score:.2f}
63
 
64
+ ---
65
 
66
+ ### πŸ”Š Spotify Recommendations:
67
+ """
 
 
68
  for s in songs:
69
  text += f"- {s}\n"
70
 
71
+ text += """
72
+ <br>
73
+
74
+ <details><summary>Raw model predictions</summary>
75
+ """
76
+
77
  for r in results:
78
+ text += f"- **{r['label']}** β€” {r['score']:.2f}\n"
79
+
80
+ text += "</details>"
81
 
82
  return text
83
 
84
 
85
+ # ---------- 4. UI with TRUE Spotify Dark Mode ----------
86
  with gr.Blocks() as demo:
87
 
88
+ # HEADER CARD
89
+ gr.HTML("""
 
90
  <div style="
91
+ background:#181818;
92
+ border-radius:24px;
93
+ padding:24px;
94
+ margin:20px auto;
95
+ max-width:950px;
96
+ box-shadow:0 0 22px rgba(0,0,0,0.6);
97
+ border:1px solid #282828;
98
+ color:white;
99
+ font-family:system-ui,-apple-system,'SF Pro Text';
100
  ">
101
+ <div style="font-size:2.2rem;font-weight:700;">
102
  🌊 MoodWave
103
  </div>
104
+ <div style="color:#1DB954;font-weight:600;font-size:1.1rem;margin-top:4px;">
105
+ Spotify Mood-Based Recommendations
 
106
  </div>
107
+ <p style="color:#B3B3B3;margin-top:8px;font-size:1rem;">
108
+ Upload a face photo. MoodWave detects your emotion and plays the right vibe.
 
 
109
  </p>
110
  </div>
111
+ """)
 
112
 
113
  with gr.Row():
114
  # LEFT: upload
115
+ with gr.Column():
116
+ gr.HTML("""
 
117
  <div style="
118
+ background:#181818;
119
+ border-radius:20px;
120
+ padding:18px;
121
+ margin:0 auto 16px auto;
122
+ max-width:450px;
123
+ border:1px solid #282828;
124
+ color:white;
125
+ font-family:system-ui,-apple-system,'SF Pro Text';
 
126
  ">
127
+ <h3 style="margin:0 0 6px 0;">πŸ“Έ Upload a photo</h3>
128
+ <p style="margin:0;color:#B3B3B3;">Use a clear face photo for best accuracy.</p>
 
 
129
  </div>
130
+ """)
131
+
132
+ image_input = gr.Image(type="numpy", height=280, label="")
133
 
134
  submit_btn = gr.Button(
135
+ "🎧 Analyze Mood",
136
+ elem_id="mw-btn"
137
  )
138
 
139
  # RIGHT: result
140
+ with gr.Column():
141
+ gr.HTML("""
 
142
  <div style="
143
+ background:#181818;
144
+ border-radius:20px;
145
+ padding:18px;
146
+ margin:0 auto 16px auto;
147
+ max-width:450px;
148
+ border:1px solid #282828;
149
+ color:white;
150
+ font-family:system-ui,-apple-system,'SF Pro Text';
 
151
  ">
152
+ <h3 style="margin:0 0 6px 0;">🎢 Your Mood & Songs</h3>
153
+ <p style="margin:0;color:#B3B3B3;">Spotify playlist suggestions will appear here.</p>
 
 
154
  </div>
155
+ """)
 
 
156
 
157
+ output_md = gr.Markdown("Waiting for an image...", elem_id="mw-output")
158
+
159
+ # FOOTER CARD
160
+ gr.HTML("""
161
  <div style="
162
+ background:#181818;
163
+ border-radius:20px;
164
+ padding:18px;
165
+ margin:20px auto;
166
+ max-width:950px;
167
+ border:1px solid #282828;
168
+ color:#B3B3B3;
169
+ font-family:system-ui,-apple-system,'SF Pro Text';
170
+ font-size:0.95rem;
 
171
  ">
172
+ <h4 style="margin-top:0;color:white;">🧠 How it works</h4>
173
+ - Vision Transformer model (`trpakov/vit-face-expression`)
174
+ - Hugging Face `transformers` pipeline
175
+ - Custom rule-based Spotify recommender system
176
+ - Fully deployed on Hugging Face Spaces
 
 
 
177
  </div>
178
+ """)
179
+
180
+ # Make button Spotify-green and circular
181
+ gr.HTML("""
182
+ <style>
183
+ #mw-btn {
184
+ background:#1DB954 !important;
185
+ color:black !important;
186
+ border:none !important;
187
+ font-weight:600 !important;
188
+ border-radius:999px !important;
189
+ padding:12px 26px !important;
190
+ font-size:1rem !important;
191
+ }
192
+ #mw-btn:hover {
193
+ filter:brightness(1.08);
194
+ }
195
+ </style>
196
+ """)
197
+
198
+ submit_btn.click(analyze_image, image_input, output_md)
199
 
200
 
201
  if __name__ == "__main__":