Summary
Hey, all Iâm creating a web app that recognizes emotion from real-time video using Microsoftâs DeepFace library. I am able to get the webcam activated using the streamlit webrct_streamer library and have real-time analysis on my local computer. This works perfectly when the camera is running but when I hit the Stop button, I receive an error regarding setting the detected dominant emotion to st.session_state["user_emotion"]
. I am able to accurately set the âuser_emotionâ session_state variable to the emotion detected until I hit the Stop button My error is given below:
Steps to reproduce
Code snippet:
lock = threading.Lock()
img_container = {"img": None}
face_cascade=cv2.CascadeClassifier("haarcascade_frontalface_default.xml")
def video_frame_callback(frame):
img = frame.to_ndarray(format="bgr24")
with lock:
img_container["img"] = img
return frame
frame_rate = 1
ctx = webrtc_streamer(key="example", video_frame_callback=video_frame_callback,
media_stream_constraints={
"video": {"frameRate": {"ideal": frame_rate}},
},
video_html_attrs={
"style": {"width": "50%", "margin": "0 auto", "border": "5px purple solid"},
"controls": False,
"autoPlay": True,
},
)
if "user_emotion" not in st.session_state:
st.session_state["user_emotion"] =""
main_emotion = st.empty()
while ctx.state.playing:
with lock:
img = img_container["img"]
if img is None:
continue
emotion_data = DeepFace.analyze(img_path=img,actions=['emotion'],enforce_detection=False)
if emotion_data != []:
st.session_state["user_emotion"] = emotion_data[0]["dominant_emotion"]
curr_emotion = st.session_state["user_emotion"]
main_emotion.write(curr_emotion)
Expected behavior:
I would expect when i hit the Stop button of the streamlit webrtc module the last detected emotion would be saved in st.session_state["user_emotion]
like âangryâ âsadâ âhappyâ without erroring.
Actual behavior:
Error:
Traceback (most recent call last):
File "/Users/v.esau.hutcherson/.local/share/virtualenvs/StreamLit-ohTsyygW/lib/python3.10/site-packages/streamlit/runtime/scriptrunner/script_runner.py", line 565, in _run_script
exec(code, module.__dict__)
File "/Users/v.esau.hutcherson/StreamLit/pages/listings.py", line 146, in <module>
if st.session_state["user_emotion"] == "neutral" or "suprised" or "happy":
File "/Users/v.esau.hutcherson/.local/share/virtualenvs/StreamLit-ohTsyygW/lib/python3.10/site-packages/streamlit/runtime/state/session_state_proxy.py", line 90, in __getitem__
return get_session_state()[key]
File "/Users/v.esau.hutcherson/.local/share/virtualenvs/StreamLit-ohTsyygW/lib/python3.10/site-packages/streamlit/runtime/state/safe_session_state.py", line 111, in __getitem__
raise KeyError(key)
KeyError: 'user_emotion'
Additional Info:
The data received from DeepFace.analyze is a dictionary formatted like this for a frame instance analyzed:
[
0:{
"emotion":{
"angry":0.0645486346911639
"disgust":0.0000023556083306175424
"fear":0.0018471573639544658
"happy":95.05292773246765
"sad":0.23144783917814493
"surprise":0.10018055327236652
"neutral":4.549040272831917
}
"dominant_emotion":"happy"
"region":{
"x":206
"y":103
"w":241
"h":241
}
}
]
I would assume I can access the dominant emotion key value and assignment it toa st.session_state variable by doing st.session_state["user_emotion] = emotion_data[0]["dominant emotion]
and still works perfectly until i stop the live webcam stream. I am assuming it has something to do with this code inside safe_session_state.py:
def __getitem__(self, key: str) -> Any:
with self._lock:
if self._disconnected:
raise KeyError(key)
return self._state[key]
I assumed when webcam is stopped and disconnects that the last dominant emotion would be saved as the st.session_state variable but for some reason the self._disconnected condition is reached when i stop the camera can i receive some assistance with this?
Debug info
- Streamlit, version 1.22.0
- Python version: 3.10
- Using PipEnv
- OS version: Ventura 13.3.1