Anyone figure out how to cache cv2.VideoCaptures?

I’m building an app to benchmark a process running on a webcam video-feed. Every refresh means I have to re-initialize the camera.(Depending on the camera can take up to 2-3 seconds of waiting). I make many changes fast, and was hoping to cut the 2-3 seconds for each refresh by caching the video capture.

Here is how I’m trying to implement caching.

import cv2

@st.cache()
def load_camera() -> cv2.VideoCapture:
    CAMERA_FLAG = 0
    camera = cv2.VideoCapture(CAMERA_FLAG)
    return camera

camera = load_camera()

Here is the error that I get

Has anyone successfully been able to st.cache a cv2 video capture, or found a different way to take frames from a webcam?

Change the decorator line to @st.cache(allow_output_mutation=True). Usually Streamlit tries to hash output values from functions (camera in this case), but hashing mutable objects is generally bad news, so setting this flag to True prevents Streamlit from doing this.

Hi @conic, welcome to the forum :wave:

Another approach is to set your own hash function for the cv2.VideoCapture object.

By passing the hash_funcs param to your @st.cache decorator, for ex…

@st.cache(hash_funcs={cv2.VideoCapture: id})

This feature is already included in v0.51.0, but we’re still updating the documentation.

Here’s a link to the docstring that mentions the new hash_funcs param and provides example usage.

https://github.com/streamlit/streamlit/blob/develop/lib/streamlit/caching.py#L437

@andrewPoulton @Jonathan_Rhone

Thank you both for the response. I tried @andrewPoulton’s method and it worked. It seems less complicated so I went with that. I haven’t tried yours yet @Jonathan_Rhone