question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Problem releasing the videoCapture (OpenCV) after Rerun the App

See original GitHub issue

I am able to stream the video from the webcam to streamlit UI. The problem occurs when I change a parameter in the application;

Here is the code to reproduce the bug:

import streamlit as st
import cv2 as cv

cap = cv.VideoCapture(0)

frameST = st.empty()
param=st.sidebar.slider('chose your value')

while True: 
    ret, frame = cap.read()
    # Stop the program if reached end of video
    if not ret:
        print("Done processing !!!")
        cv.waitKey(3000)
        # Release device
        cap.release()
        break

    frameST.image(frame, channels="BGR")

Any help ?

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Comments:6 (2 by maintainers)

github_iconTop GitHub Comments

8reactions
tvstcommented, Oct 24, 2019

Hi all

This seems like the kind of issue I need to stare at for a while so I can wrap my head around it 😖 …but it may be useful for me to jump in real quick to explain how Streamlit works internally.

Streamlit launches a new thread each time it needs to re-execute your script.

Meaning:

  • Whenever a new browser tab connects to your app
  • Whenever a user changes a widget value via the UI

So based on this:

new threads are automatically started while older one are still running

…from a cursory look it seems that things are actually working as designed.

But since in your case you’re grabbing a limited resource with VideoCapture(), you probably need to make all threads share that resource. The best way to do that is to put it in the Streamlit cache:

import streamlit as st
import cv2 as cv

@st.cache(allow_output_mutation=True)
def get_cap():
    return cv.VideoCapture(0)

cap = get_cap()

frameST = st.empty()
param=st.sidebar.slider('chose your value')

while True:
    ret, frame = cap.read()
    # Stop the program if reached end of video
    if not ret:
        print("Done processing !!!")
        cv.waitKey(3000)
        # Release device
        cap.release()
        break

    frameST.image(frame, channels="BGR")

Let me know if that works for you!

3reactions
imneonizercommented, Oct 23, 2019

Here is a clever workaround, i run a subthread inside while loop and keep on updating latest time frame, if that subthread finds a time gap greater than 1 sec then it gets terminated and ultimately releasing video capture object… one thing that i observed is if you use your code and stop it from UI, the lines below while loop are not been executed

import streamlit as st
from threading import Thread
import cv2
import time

cap = cv2.VideoCapture(0)
frameST = st.empty()
param = st.sidebar.slider('choose your value')

stopper_started = False
while True:
    success, frame = cap.read()
    if not success: break

    frameST.image(frame, channels="BGR")
    updated_time = time.time()

    if not stopper_started:
        #this block executes for once with every
        #streamlit re-run command
        def stopper(self):
            while True:
                try:
                    #if time difference increases this thread will be terminated
                    time_diff = round(time.time() - updated_time)
                    if time_diff >1: #1 second
                        print("Done processing !!!")
                        print("Releasing VideoCapture")
                        #if streamlit ui is stopped
                        #time gap will increase
                        #hence releasing camera resource
                        cap.release()
                        break
                except: pass
        th = Thread(target=stopper, args=(0,))
        th.daemon = True
        th.start()
        stopper_started = True
Read more comments on GitHub >

github_iconTop Results From Across the Web

OpenCv error can't open camera through video capture
In my case, I just reconnected cam to the usb port, and then it was solved! I think this error is caused by...
Read more >
upgrading to opencv 3.4.2 to run a programme the camera ...
It seems to be only related with opencv 3.4.2. CameraObject = cv.VideoCapture.release(). does not work. It does throw a type error. TypeError: ...
Read more >
How to use Arducam's camera & opencv for live inference?
First, according to Arducam, my device id is 3 rather than 0 when initializing cap = cv2.VideoCapture(3). From there I tried a simple...
Read more >
Loading Video Source OpenCV Python Tutorial
VideoCapture (0) . This will return video from the first webcam on your computer. If you are watching the tutorial videos, you will...
Read more >
Develop Streamlit-WebRTC Component for Real-Time Video ...
VideoCapture (0) consumes a video stream from the first (indexed as 0) ... After opening the app with a web browser, open the...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found