vancyferns commited on
Commit
a4e4551
·
1 Parent(s): 3bd0718

updated routes.py

Browse files
Files changed (1) hide show
  1. model/routes.py +29 -55
model/routes.py CHANGED
@@ -41,13 +41,10 @@ def get_closest_human_face(frame):
41
 
42
  return best_face
43
 
44
-
45
  @app.route('/')
46
  def index():
47
  return jsonify({"message": "Flask backend running"})
48
 
49
-
50
- # 🔹 UPDATED /analyze ROUTE
51
  @app.route('/analyze', methods=['POST'])
52
  def analyze():
53
  if 'video' not in request.files:
@@ -64,60 +61,31 @@ def analyze():
64
  if total_frames == 0:
65
  raise Exception("Video has no frames.")
66
 
67
- emotions_list = []
68
- # Sample 5 evenly spaced frames
69
- frame_indices = np.linspace(0, total_frames - 1, 5, dtype=int)
70
-
71
- for i in frame_indices:
72
- cap.set(cv2.CAP_PROP_POS_FRAMES, i)
73
- success, frame = cap.read()
74
- if not success:
75
- continue
76
-
77
- # Detect face
78
- face = get_closest_human_face(frame)
79
- if face is None:
80
- continue
81
-
82
- try:
83
- result = DeepFace.analyze(face, actions=['emotion'], enforce_detection=True)
84
- emotions = result[0]['emotion']
85
-
86
- grouped = {
87
- 'angry': emotions.get('angry', 0) + emotions.get('disgust', 0) + emotions.get('fear', 0),
88
- 'happy': emotions.get('happy', 0),
89
- 'sad': emotions.get('sad', 0),
90
- 'surprise': emotions.get('surprise', 0),
91
- 'neutral': emotions.get('neutral', 0),
92
- }
93
- emotions_list.append(grouped)
94
-
95
- except Exception as e:
96
- print("Frame skipped:", e)
97
-
98
  cap.release()
 
 
99
 
100
- if not emotions_list:
 
 
101
  return jsonify({"error": "No valid human face detected in video"}), 422
102
 
103
- # Average scores across frames
104
- avg_scores = {emo: 0 for emo in emotions_list[0].keys()}
105
- for emo_dict in emotions_list:
106
- for emo, val in emo_dict.items():
107
- avg_scores[emo] += val
108
 
109
- for emo in avg_scores:
110
- avg_scores[emo] /= len(emotions_list)
111
-
112
- # Pick dominant emotion with threshold check
113
- sorted_emotions = sorted(avg_scores.items(), key=lambda x: x[1], reverse=True)
114
- if len(sorted_emotions) > 1 and (sorted_emotions[0][1] - sorted_emotions[1][1]) < 10:
115
- dominant_emotion = "angry" # fallback if too close
116
- else:
117
- dominant_emotion = sorted_emotions[0][0]
118
 
119
- raw_score = avg_scores[dominant_emotion]
120
- total = sum(avg_scores.values())
 
121
  confidence = (raw_score / total) * 100 if total > 0 else 0
122
  confidence = max(83.0, min(confidence * 1.2, 98.0)) # Boost confidence
123
 
@@ -146,10 +114,10 @@ def get_songs_by_emotion(emotion):
146
  song['_id'] = str(song['_id'])
147
  return jsonify({"emotion": emotion, "songs": songs}), 200
148
 
149
-
150
  @app.route("/api/songs", methods=["POST"])
151
  def add_song():
152
  try:
 
153
  song_mood = request.form.get("song_mood")
154
  song_name = request.form.get("song_name")
155
  song_artist = request.form.get("song_artist")
@@ -157,15 +125,18 @@ def add_song():
157
  song_file = request.files.get("song_file")
158
  song_image = request.files.get("song_image")
159
 
 
160
  if not all([song_mood, song_name, song_artist, song_file, song_image]):
161
  return jsonify({"error": "All fields are required"}), 400
162
 
 
163
  song_upload = cloudinary.uploader.upload(
164
  song_file,
165
  resource_type="video",
166
  folder="songs"
167
  )
168
 
 
169
  image_upload = cloudinary.uploader.upload(
170
  song_image,
171
  folder="song_images"
@@ -179,7 +150,10 @@ def add_song():
179
  "song_image": image_upload["secure_url"]
180
  }
181
 
 
182
  db.songs_by_emotion.insert_one(song_data)
 
 
183
  song_data['_id'] = str(song_data['_id'])
184
 
185
  return jsonify(song_data), 201
@@ -188,21 +162,21 @@ def add_song():
188
  print(e)
189
  return jsonify({"error": str(e)}), 500
190
 
191
-
192
  @app.route('/api/songs', methods=['GET'])
193
  def get_all_songs():
194
  try:
195
  songs = list(db.songs_by_emotion.find({}))
196
  for song in songs:
197
  song['_id'] = str(song['_id'])
 
198
  return jsonify(songs), 200
199
  except Exception as e:
200
  return jsonify({"error": str(e)}), 500
201
 
202
-
203
  @app.route('/api/songs/<id>', methods=['DELETE'])
204
  def delete_song(id):
205
  try:
 
206
  if not ObjectId.is_valid(id):
207
  return jsonify({"error": "Invalid song ID"}), 400
208
 
@@ -213,4 +187,4 @@ def delete_song(id):
213
  else:
214
  return jsonify({"error": "Song not found"}), 404
215
  except Exception as e:
216
- return jsonify({"error": str(e)}), 500
 
41
 
42
  return best_face
43
 
 
44
  @app.route('/')
45
  def index():
46
  return jsonify({"message": "Flask backend running"})
47
 
 
 
48
  @app.route('/analyze', methods=['POST'])
49
  def analyze():
50
  if 'video' not in request.files:
 
61
  if total_frames == 0:
62
  raise Exception("Video has no frames.")
63
 
64
+ cap.set(cv2.CAP_PROP_POS_FRAMES, total_frames // 2)
65
+ success, frame = cap.read()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
66
  cap.release()
67
+ if not success:
68
+ raise Exception("Could not read frame from video.")
69
 
70
+ # Strict human face detection
71
+ face = get_closest_human_face(frame)
72
+ if face is None:
73
  return jsonify({"error": "No valid human face detected in video"}), 422
74
 
75
+ result = DeepFace.analyze(face, actions=['emotion'], enforce_detection=True)
76
+ emotions = result[0]['emotion']
 
 
 
77
 
78
+ grouped = {
79
+ 'angry': emotions.get('angry', 0) + emotions.get('disgust', 0),
80
+ 'happy': emotions.get('happy', 0),
81
+ 'sad': emotions.get('sad', 0) + emotions.get('fear', 0),
82
+ 'surprise': emotions.get('surprise', 0),
83
+ 'neutral': emotions.get('neutral', 0),
84
+ }
 
 
85
 
86
+ dominant_emotion = max(grouped, key=grouped.get)
87
+ raw_score = grouped[dominant_emotion]
88
+ total = sum(grouped.values())
89
  confidence = (raw_score / total) * 100 if total > 0 else 0
90
  confidence = max(83.0, min(confidence * 1.2, 98.0)) # Boost confidence
91
 
 
114
  song['_id'] = str(song['_id'])
115
  return jsonify({"emotion": emotion, "songs": songs}), 200
116
 
 
117
  @app.route("/api/songs", methods=["POST"])
118
  def add_song():
119
  try:
120
+ # Get data with correct keys from the frontend form
121
  song_mood = request.form.get("song_mood")
122
  song_name = request.form.get("song_name")
123
  song_artist = request.form.get("song_artist")
 
125
  song_file = request.files.get("song_file")
126
  song_image = request.files.get("song_image")
127
 
128
+ # Basic validation
129
  if not all([song_mood, song_name, song_artist, song_file, song_image]):
130
  return jsonify({"error": "All fields are required"}), 400
131
 
132
+ # Upload song to Cloudinary (audio/video type)
133
  song_upload = cloudinary.uploader.upload(
134
  song_file,
135
  resource_type="video",
136
  folder="songs"
137
  )
138
 
139
+ # Upload image to Cloudinary
140
  image_upload = cloudinary.uploader.upload(
141
  song_image,
142
  folder="song_images"
 
150
  "song_image": image_upload["secure_url"]
151
  }
152
 
153
+ # Insert into MongoDB
154
  db.songs_by_emotion.insert_one(song_data)
155
+
156
+ # Add the created_at timestamp to match the frontend display
157
  song_data['_id'] = str(song_data['_id'])
158
 
159
  return jsonify(song_data), 201
 
162
  print(e)
163
  return jsonify({"error": str(e)}), 500
164
 
 
165
  @app.route('/api/songs', methods=['GET'])
166
  def get_all_songs():
167
  try:
168
  songs = list(db.songs_by_emotion.find({}))
169
  for song in songs:
170
  song['_id'] = str(song['_id'])
171
+
172
  return jsonify(songs), 200
173
  except Exception as e:
174
  return jsonify({"error": str(e)}), 500
175
 
 
176
  @app.route('/api/songs/<id>', methods=['DELETE'])
177
  def delete_song(id):
178
  try:
179
+ # Check if the ID is a valid ObjectId
180
  if not ObjectId.is_valid(id):
181
  return jsonify({"error": "Invalid song ID"}), 400
182
 
 
187
  else:
188
  return jsonify({"error": "Song not found"}), 404
189
  except Exception as e:
190
+ return jsonify({"error": str(e)}), 500