img_list[0] is used outside with lock. list[0] is just a reference to another object, which is shared by both the main thread and recv()'s thread, so I think it should also be guarded with thread-safe lock, though I’m not sure if it is really necessary as I haven’t tested it yet.
Thank you for your reply and attention. I am trying to capture a series of high res images. Here is my code as requested:
Blockquote
import streamlit as st
import numpy as np
import pandas as pd
import threading
from typing import Union
import cv2
import av
import os
from streamlit_webrtc import VideoProcessorBase, webrtc_streamer
sports option in side bar
s_option = st.sidebar.selectbox(
‘Select anlysis mode :’,
df[‘first column’])
def main():
class VideoTransformer(VideoProcessorBase):
frame_lock: threading.Lock # transform() is running in another thread, then a lock object is used here for thread-safety.
in_image: Union[np.ndarray, None]
def __init__(self) -> None:
self.frame_lock = threading.Lock()
self.in_image = None
self.img_list = []
def recv(self, frame: av.VideoFrame) -> av.VideoFrame:
in_image = frame.to_ndarray(format="bgr24")
list_img = frame.to_ndarray(format="bgr24")
global img_counter
with self.frame_lock:
self.in_image = in_image
if img_counter > 0:
#print("capturing image")
self.img_list.append(list_img)
img_counter -= 1
return av.VideoFrame.from_ndarray(in_image, format="bgr24")
ctx = webrtc_streamer(key="snapshot", video_processor_factory=VideoTransformer)
if ctx.video_transformer:
if st.button("Snapshot"):
with ctx.video_transformer.frame_lock:
in_image = ctx.video_transformer.in_image
img_list = ctx.video_transformer.img_list
if in_image is not None: #put in column form 5 images in a row
st.write("Input image:")
st.image(in_image, channels="BGR")
st.image(img_list[0], channels="BGR") #lower resolution than the one above in_image
else:
st.warning("No frames available yet.")
Hi @whitphx , thank you again for your help. Just a quick question, would it be possible to change the resolution to HD at 1280, 720, it seems the default is 640, 480 for the frame.
media_stream_constraints parameter is passed to navigator.mediaDevices.getUserMedia() on the frontend code to configure the media devices. This page, for example, explains the details of that API. If you want more controls, this page can be a hint.
Note that the media_stream_constraints setting is a instruction for the browser to configure the media devices, but the browser sometimes does not follow it.
@nerilou.delacruz It’s simply a problem of these libraries related to M1 chip, not this component, IMO.
These libs contain C code and have to be built at installation, so may have problems on M1 platform.
Just for a reference, I paste my recipe on M1 mac here restored from my memory and some documents. pyenv installed via homebrew is required.
The point is to install the python in an x86-emulated environment. arch command does it.
Setting the PATH envvar is to use the x86 version of the Python dependency libraries installed via homebrew, during pyenv install.
Using the latest version of pip may also be a point.
Note that I haven’t tested this instruction from top to bottom. There can be a missing part.
And I don’t support it. Please use this info just as a clue.
Hi,
I just installed streamlit v.1.0 and want to use simply the webcam. So I tried the provided snippet from the newest blog entry:
from webcam_component import webcam
captured_image = webcam()
if captured_image is not None:
st.image(captured_image)
It says: “ModuleNotFoundError: No module named ‘webcam_component’”. I installed your package with pip install streamlit-webrtc. It still does not work somehow…
Then it is a bit misleading because it looks like that a webcam can be used with just those lines of code. Anyway, I just used your repo Just another question, is it possible to access the streamlit session state from inside of the callback function of VideoProcessor?
After some survey, I think it won’t be implemented because it seems to require not intuitive hacks to create.
However, as inspired from this conversation, I’m thinking of introducing a new state object like session_state shared both by inside and outside the callbacks.
For example, we will be able to use the shared state like below.
@Firehead1971
Do you think such design is helpful for your needs?
Can you tell me your use case where you want to pass the session_state directly to the callbacks?
And not only him but also everyone, please give me your opinion!
@ whitphx Thanks a lot for the great work, keep it up.
I was wondering if I can use the async def recv_queued function to provide a batch of frames to be processed by the model at once, i.e i will delay the stream by n secs, to be able to batch process it
is this applicable, and if not, what is your recommendation for providing the DL model a batch of frames at once instead of one frame at a time?
When recv_queued() is called first time, the input frames contain the first frame (probably len(frames) == 1).
If you call await asyncio.sleep(1) inside recv_queued() and returns the frames from the callback, these frames are displayed with 1 sec delay.
When recv_queued() is called next time, the input frames contain frames that have arrived after the previous frames. Probably len(frames) == 10 because the previous recv_queued() took 1sec in which 10 frames should have arrived.
So, now you can process these 10 frames at one time.
If this batch processing takes 1 sec again, the same thing continues in the successive calls…
@whitphx Just, maybe a simple question, when I am deploying the app on streamlit cloud it does not render the output of the webcam. Instead I get only a black screen. On localhost it works smoothly but on remote host it returns the black screen output.
MWE
import streamlit as st
import av
import cv2
from streamlit_webrtc import webrtc_streamer
from PIL import Image
webrtc_streamer(key="sample")
How can I fetch the video output when I am deploying the app on e.g. streamlit cloud?
Thanks for stopping by! We use cookies to help us understand how you interact with our website.
By clicking “Accept all”, you consent to our use of cookies. For more information, please see our privacy policy.
Cookie settings
Strictly necessary cookies
These cookies are necessary for the website to function and cannot be switched off. They are usually only set in response to actions made by you which amount to a request for services, such as setting your privacy preferences, logging in or filling in forms.
Performance cookies
These cookies allow us to count visits and traffic sources so we can measure and improve the performance of our site. They help us understand how visitors move around the site and which pages are most frequently visited.
Functional cookies
These cookies are used to record your choices and settings, maintain your preferences over time and recognize you when you return to our website. These cookies help us to personalize our content for you and remember your preferences.
Targeting cookies
These cookies may be deployed to our site by our advertising partners to build a profile of your interest and provide you with content that is relevant to you, including showing you relevant ads on other websites.