trttung1610 commited on
Commit
04f9904
1 Parent(s): 46bfff7

Upload 4 files

Browse files
Files changed (5) hide show
  1. .gitattributes +1 -0
  2. demo_video.mp4 +3 -0
  3. process_emotion_video.py +119 -0
  4. requirements.txt +7 -0
  5. web.py +41 -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
+ demo_video.mp4 filter=lfs diff=lfs merge=lfs -text
demo_video.mp4 ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:4cb921ae36d4d7ce8f9e13586166aaaba55ef9f3f384fcc43bffffae39f71cb0
3
+ size 4432717
process_emotion_video.py ADDED
@@ -0,0 +1,119 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import tempfile
3
+ import torch
4
+ import cv2
5
+ from PIL import Image
6
+ from torchvision import transforms
7
+ from facenet_pytorch import MTCNN
8
+
9
+ def process_emotion(input_video):
10
+ try:
11
+ # Load the pre-trained CNN model
12
+ model = torch.hub.load('pytorch/vision:v0.10.0', 'resnet18', pretrained=True)
13
+ num_ftrs = model.fc.in_features
14
+ model.fc = torch.nn.Linear(num_ftrs, 7) # 7 classes for emotions
15
+
16
+ # Load the pre-trained weights
17
+ model.eval()
18
+
19
+ # Define emotions
20
+ emotions = ["Angry", "Disgust", "Fear", "Happy", "Sad", "Surprise", "Neutral"]
21
+
22
+ # Initialize MTCNN for face detection
23
+ mtcnn = MTCNN()
24
+
25
+ # Open the video capture
26
+ cap = cv2.VideoCapture(input_video.name)
27
+
28
+ if not cap.isOpened():
29
+ return "Error: Could not open video capture."
30
+
31
+ # Create a temporary directory to store the frames
32
+ temp_dir = tempfile.mkdtemp()
33
+ frame_paths = []
34
+
35
+ # Define image transformations
36
+ preprocess = transforms.Compose([
37
+ transforms.Resize(224),
38
+ transforms.ToTensor(),
39
+ transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])
40
+ ])
41
+
42
+ # Process each frame of the video
43
+ frame_count = 0
44
+ while cap.isOpened():
45
+ ret, frame = cap.read()
46
+
47
+ if not ret:
48
+ break
49
+
50
+ if frame is None:
51
+ print("Error: Empty frame.")
52
+ continue
53
+
54
+ frame_count += 1
55
+
56
+ pil_frame = Image.fromarray(cv2.cvtColor(frame, cv2.COLOR_BGR2RGB))
57
+ face_boxes, _ = mtcnn.detect(pil_frame)
58
+
59
+ if face_boxes is None:
60
+ print(f"No face detected in frame {frame_count}.")
61
+ else:
62
+ for box in face_boxes:
63
+ x1, y1, x2, y2 = box.astype(int)
64
+ w = x2 - x1
65
+ h = y2 - y1
66
+
67
+ face_roi = frame[y1:y2, x1:x2]
68
+ pil_face = Image.fromarray(cv2.cvtColor(face_roi, cv2.COLOR_BGR2RGB))
69
+
70
+ input_tensor = preprocess(pil_face)
71
+ input_batch = input_tensor.unsqueeze(0)
72
+
73
+ with torch.no_grad():
74
+ output = model(input_batch)
75
+
76
+ predicted_emotion = output.argmax().item()
77
+
78
+ emotion_label = emotions[predicted_emotion]
79
+
80
+ cv2.rectangle(frame, (x1, y1), (x2, y2), (0, 255, 0), 2)
81
+ cv2.putText(frame, emotion_label, (x1, y1 - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.9, (0, 255, 0), 2)
82
+
83
+ frame_path = os.path.join(temp_dir, f"{frame_count:04d}.png")
84
+ cv2.imwrite(frame_path, frame)
85
+ frame_paths.append(frame_path)
86
+
87
+ cap.release()
88
+ cv2.destroyAllWindows()
89
+
90
+ if not frame_paths:
91
+ return "No faces detected in the video."
92
+
93
+ # Convert the frames to a video
94
+ output_path = "output_video.mp4"
95
+ fourcc = cv2.VideoWriter_fourcc(*'mp4v')
96
+
97
+ # Get dimensions from the first frame
98
+ sample_frame = cv2.imread(frame_paths[0])
99
+ if sample_frame is None:
100
+ return "Error: Unable to read sample frame."
101
+
102
+ frame_height, frame_width, _ = sample_frame.shape
103
+
104
+ out = cv2.VideoWriter(output_path, fourcc, 30, (frame_width, frame_height))
105
+
106
+ for frame_path in frame_paths:
107
+ frame = cv2.imread(frame_path)
108
+ if frame is not None:
109
+ out.write(frame)
110
+ os.remove(frame_path)
111
+ else:
112
+ print(f"Warning: Unable to read frame {frame_path}")
113
+
114
+ out.release()
115
+
116
+ return output_path
117
+
118
+ except Exception as e:
119
+ return f"An error occurred: {str(e)}"
requirements.txt ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ ffmpeg
2
+ facenet-pytorch
3
+ torch
4
+ torchvision
5
+ streamlit
6
+ opencv-python-headless
7
+ pyngrok
web.py ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ from process_emotion_video import process_emotion
3
+
4
+ def main():
5
+ st.title("Emotion Recognition in Video")
6
+ option = st.radio("Choose an option:", ("Upload a video file", "Example Video"))
7
+ if option == "Upload a video file":
8
+ # Upload video file
9
+ uploaded_file = st.file_uploader("Upload a video file", type=["mp4"])
10
+
11
+ if uploaded_file is not None:
12
+ st.write("Processing...")
13
+
14
+ # Process the video and get the output path
15
+ output_path = process_emotion(uploaded_file)
16
+
17
+ if output_path.endswith(".mp4"):
18
+ st.video(output_path)
19
+
20
+ # Add a download button for the processed video
21
+ st.download_button(
22
+ label="Download Processed Video",
23
+ data=output_path,
24
+ key="download_processed_video",
25
+ file_name="processed_video.mp4",
26
+ )
27
+ else:
28
+ st.error("An error occurred during video processing.")
29
+ else:
30
+ example_video_path = 'demo_video.mp4'
31
+ st.video(example_video_path)
32
+ st.download_button(
33
+ label="Download Processed Video",
34
+ data=example_video_path,
35
+ key="download_demo_video",
36
+ file_name="demo_video.mp4",
37
+ )
38
+
39
+
40
+ if __name__ == "__main__":
41
+ main()