PatriciaWening commited on
Commit
f6abaad
·
verified ·
1 Parent(s): 87ffea9

Upload 4 files

Browse files
Files changed (5) hide show
  1. .gitattributes +1 -0
  2. Dockerfile +21 -0
  3. app.py +165 -0
  4. moodDetection.keras +3 -0
  5. requirements.txt +6 -0
.gitattributes CHANGED
@@ -33,3 +33,4 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ moodDetection.keras filter=lfs diff=lfs merge=lfs -text
Dockerfile ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ FROM python:3.9-slim
2
+
3
+ # Install dependencies
4
+ RUN apt-get update && apt-get install -y \
5
+ libgl1-mesa-glx \
6
+ libglib2.0-0
7
+
8
+ WORKDIR /app
9
+
10
+ # Copy requirements and install
11
+ COPY requirements.txt .
12
+ RUN pip install --no-cache-dir -r requirements.txt
13
+
14
+ # Copy all files
15
+ COPY . .
16
+
17
+ # Expose port
18
+ EXPOSE 7860
19
+
20
+ # Run app with uvicorn
21
+ CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "7860"]
app.py ADDED
@@ -0,0 +1,165 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import cv2
3
+ import numpy as np
4
+ import base64
5
+ import json
6
+ from io import BytesIO
7
+ from PIL import Image
8
+ import tensorflow as tf
9
+ from tensorflow import keras
10
+ from fastapi import FastAPI, Request, Form, File, UploadFile
11
+ from fastapi.middleware.cors import CORSMiddleware
12
+ from fastapi.responses import JSONResponse
13
+ import uvicorn
14
+
15
+ model_path = 'moodDetection.keras'
16
+ emotion_model = keras.models.load_model(model_path)
17
+
18
+ emotion_labels = ['angry', 'disgust', 'fear', 'happy', 'neutral', 'sad', 'surprise']
19
+
20
+ face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml')
21
+
22
+ app = FastAPI()
23
+
24
+ app.add_middleware(
25
+ CORSMiddleware,
26
+ allow_origins=["*"],
27
+ allow_credentials=True,
28
+ allow_methods=["*"],
29
+ allow_headers=["*"],
30
+ )
31
+
32
+ sessions = {}
33
+
34
+ @app.post("/api/deteksi-emosi")
35
+ async def detect_emotion(request: Request):
36
+ try:
37
+ form = await request.form()
38
+ image_data = form.get("image")
39
+
40
+ print(f"Received request with sessionId: {form.get('sessionId', 'not provided')}")
41
+ print(f"Image data received: {bool(image_data)}")
42
+
43
+ if image_data and "base64" in image_data:
44
+ try:
45
+ base64_data = image_data.split(',')[1]
46
+ image_bytes = base64.b64decode(base64_data)
47
+
48
+ print("Successfully decoded base64 data")
49
+
50
+ img = Image.open(BytesIO(image_bytes))
51
+ img_array = np.array(img)
52
+
53
+ if len(img_array.shape) > 2 and img_array.shape[2] == 3:
54
+ gray = cv2.cvtColor(img_array, cv2.COLOR_RGB2GRAY)
55
+ else:
56
+ gray = img_array
57
+
58
+ print(f"Processed image shape: {gray.shape}")
59
+
60
+ faces = face_cascade.detectMultiScale(gray, 1.3, 5)
61
+ print(f"Detected {len(faces)} faces")
62
+
63
+ if len(faces) > 0:
64
+ (x, y, w, h) = faces[0]
65
+
66
+ face_roi = gray[y:y+h, x:x+w]
67
+
68
+ resized_face = cv2.resize(face_roi, (48, 48))
69
+ normalized_face = resized_face / 255.0
70
+ reshaped_face = normalized_face.reshape(1, 48, 48, 1)
71
+
72
+ prediction = emotion_model.predict(reshaped_face)
73
+ emotion_idx = np.argmax(prediction[0])
74
+ emotion = emotion_labels[emotion_idx]
75
+ confidence = float(prediction[0][emotion_idx])
76
+
77
+ stress_mapping = {
78
+ 'angry': 85, 'disgust': 65, 'fear': 70,
79
+ 'sad': 75, 'surprise': 45, 'neutral': 30, 'happy': 15
80
+ }
81
+
82
+ stress_level = stress_mapping.get(emotion, 50)
83
+
84
+ session_id = form.get("sessionId", "default")
85
+ if session_id not in sessions:
86
+ sessions[session_id] = {
87
+ "emotions": [],
88
+ "stress_levels": []
89
+ }
90
+
91
+ sessions[session_id]["emotions"].append(emotion)
92
+ sessions[session_id]["stress_levels"].append(stress_level)
93
+
94
+ result = {
95
+ "emotion": emotion,
96
+ "confidence": confidence,
97
+ "stressLevel": stress_level,
98
+ "faceDetected": True,
99
+ "faceRegion": {"x": int(x), "y": int(y), "width": int(w), "height": int(h)}
100
+ }
101
+ else:
102
+ result = {
103
+ "emotion": "unknown",
104
+ "confidence": 0,
105
+ "stressLevel": 0,
106
+ "faceDetected": False
107
+ }
108
+ except Exception as e:
109
+ print(f"Error processing image: {str(e)}")
110
+ import traceback
111
+ traceback.print_exc()
112
+ result = {"error": f"Image processing error: {str(e)}"}
113
+ else:
114
+ result = {"error": "Invalid image data"}
115
+
116
+ except Exception as e:
117
+ print(f"Request handling error: {str(e)}")
118
+ import traceback
119
+ traceback.print_exc()
120
+ result = {"error": f"Server error: {str(e)}"}
121
+
122
+ response = JSONResponse(content=result)
123
+ response.headers["Access-Control-Allow-Origin"] = "*"
124
+ response.headers["Access-Control-Allow-Credentials"] = "true"
125
+ return response
126
+
127
+ @app.get("/api/session-report/{session_id}")
128
+ async def session_report(session_id: str):
129
+ if session_id not in sessions:
130
+ return JSONResponse(content={"error": "Session not found"}, status_code=404)
131
+
132
+ session_data = sessions[session_id]
133
+
134
+ if session_data["emotions"]:
135
+ emotion_counts = {}
136
+ for emotion in session_data["emotions"]:
137
+ if emotion in emotion_counts:
138
+ emotion_counts[emotion] += 1
139
+ else:
140
+ emotion_counts[emotion] = 1
141
+
142
+ dominant_emotion = max(emotion_counts, key=emotion_counts.get)
143
+
144
+ avg_stress = sum(session_data["stress_levels"]) / len(session_data["stress_levels"])
145
+
146
+ min_stress = min(session_data["stress_levels"])
147
+ max_stress = max(session_data["stress_levels"])
148
+
149
+ result = {
150
+ "dominantEmotion": dominant_emotion,
151
+ "emotionCounts": emotion_counts,
152
+ "averageStressLevel": round(avg_stress, 2),
153
+ "minStressLevel": min_stress,
154
+ "maxStressLevel": max_stress,
155
+ "totalFrames": len(session_data["emotions"])
156
+ }
157
+ else:
158
+ result = {
159
+ "error": "No data in session"
160
+ }
161
+
162
+ return JSONResponse(content=result)
163
+
164
+ if __name__ == "__main__":
165
+ uvicorn.run("app:app", host="127.0.0.1", port=8080, reload=True)
moodDetection.keras ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:516d9a89bc3c07554c408f77ebb245e3a8bcf88a0857f9e666126cb2cba016a5
3
+ size 385480296
requirements.txt ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ fastapi
2
+ uvicorn
3
+ tensorflow
4
+ opencv-python-headless
5
+ pillow
6
+ python-multipart