File size: 5,282 Bytes
095392e 3de05a3 095392e 835b197 db9aa6f 3de05a3 d40b455 3de05a3 095392e 58104c3 095392e 4138b04 3de05a3 095392e 3de05a3 095392e a1a5d57 23f926c 3de05a3 095392e 67969e1 16fa463 095392e 16fa463 095392e | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 | import openvino as ov
import cv2
import numpy as np
import PIL
import io
import tempfile
import streamlit as st
import moviepy.editor as mpy
class EmotionModel:
def __init__(self):
self.face_compiled_model, self.face_input_layer, self.face_output_layer = self.load_model('face-detection-adas-0001')
self.emotion_compiled_model, self.emotion_input_layer, self.emotion_output_layer = self.load_model('emotions-recognition-retail-0003')
self.emotions = {
0:"neutral",
1:"happy",
2:"sad",
3:"surprise",
4:"anger"
}
def load_model(self, model_name):
model_path = "models/" + model_name + ".xml"
core = ov.Core()
model = core.read_model(model=model_path)
compiled_model = core.compile_model(model=model, device_name="CPU")
input_layer = compiled_model.input(0)
output_layer = compiled_model.output(0)
return compiled_model, input_layer, output_layer
def preprocess(self, img, input_layer):
input_h, input_w = input_layer.shape[2], input_layer.shape[3]
input_img = cv2.resize(img, (input_w,input_h))
input_img = input_img.transpose(2, 0, 1)
input_img = np.expand_dims(input_img, 0)
return input_img
def detect_faces(self, uploaded_img_cv, conf = 0.5):
input_img = self.preprocess(uploaded_img_cv, self.face_input_layer)
result_face = self.face_compiled_model([input_img])[self.face_output_layer]
boxes = self.post_process_face(result_face, uploaded_img_cv, conf)
return boxes
def post_process_face(self, result_face, img, conf=0.5):
boxes = []
h,w,_ = img.shape
predictions = result_face[0][0] # ํ์ ์งํฉ ๋ฐ์ดํฐ ํ๋ ์
confidence = predictions[:,2] # conf ๊ฐ ๊ฐ์ ธ์ค๊ธฐ [img_id, label, conf, x_min, y_min, x_max, y_max]
top_predictions = predictions[(confidence>conf)] # ์๊ณ๊ฐ๋ณด๋ค ํฐ conf ๊ฐ์ ๊ฐ์ง ์์ธก๋ง ์ ํ
for detection in top_predictions:
box = (detection[3:7]* np.array([w, h, w, h])).astype("int") # ์์ ์์น ๊ฒฐ์
box = [0 if i < 0 else i for i in box]
(xmin, ymin, xmax, ymax) = box # xmin, ymin, xmax, ymax์ ์์ ์์น ๊ฐ ์ง์
boxes.append(box)
cv2.rectangle(img, (xmin, ymin), (xmax, ymax), (0, 0, 255), 2) # ์ฌ๊ฐํ ๋ง๋ค๊ธฐ
return boxes
def detect_emotions(self, uploaded_img_cv, boxes):
for box in boxes:
xmin, ymin, xmax, ymax = box
emotion_input = uploaded_img_cv[ymin:ymax,xmin:xmax]
input_img = self.preprocess(emotion_input, self.emotion_input_layer)
result_emotion = self.emotion_compiled_model([input_img])[self.emotion_output_layer]
self.post_process_emotion(result_emotion, uploaded_img_cv, box)
def post_process_emotion(self, result_emotion, img, face_position):
predictions = result_emotion[0,:,0,0]
topresult_index = np.argmax(predictions)
emotion = self.emotions[topresult_index]
font_size = img.shape[0]/1000
font_thickness = int(img.shape[0]/500)
text_offset = int(img.shape[0]/30)
cv2.putText(img, emotion,
(face_position[0],face_position[1]+text_offset),
cv2.FONT_HERSHEY_SIMPLEX, font_size,
(255, 255,255), font_thickness)
return emotion
def process(self, img):
if isinstance(img, np.ndarray):
uploaded_img_cv = img
else:
uploaded_img = PIL.Image.open(img)
uploaded_img_cv = np.array(uploaded_img)
boxes = self.detect_faces(uploaded_img_cv)
self.detect_emotions(uploaded_img_cv, boxes)
return uploaded_img_cv
def play_video(self, input_video):
uploaded_video = io.BytesIO(input_video.read())
temporary_location = "upload.mp4"
with open(temporary_location, "wb") as out:
out.write(uploaded_video.read())
out.close()
camera = cv2.VideoCapture(temporary_location)
fps = camera.get(cv2.CAP_PROP_FPS)
temp_file = tempfile.NamedTemporaryFile(delete=False, suffix='.mp4')
processed_frames=[]
total_frames = int(camera.get(cv2.CAP_PROP_FRAME_COUNT))
progress_bar = st.progress(0)
frame_count = 0
st_frame = st.empty()
while(camera.isOpened()):
ret, frame = camera.read()
if ret:
emotion_img = self.process(frame)
st_frame.image(emotion_img, channels = "BGR")
processed_frames.append(cv2.cvtColor(emotion_img,cv2.COLOR_BGR2RGB))
frame_count +=1
progress_bar.progress(frame_count/total_frames, text = None)
else:
camera.release()
st_frame.empty()
progress_bar.empty()
break
clip = mpy.ImageSequenceClip(processed_frames,fps=fps)
clip.write_videofile(temp_file.name)
return temp_file.name
|