Spaces:
Runtime error
Runtime error
update app
Browse files- .gitignore +3 -0
- app.py +72 -0
- requirements.txt +93 -0
- sample_utils/__init__.py +0 -0
- sample_utils/download.py +50 -0
- sample_utils/turn.py +39 -0
- yolov5s.pt +3 -0
.gitignore
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
venv/
|
2 |
+
__pycache__/
|
3 |
+
|
app.py
ADDED
@@ -0,0 +1,72 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import av
|
2 |
+
import cv2
|
3 |
+
import streamlit as st
|
4 |
+
from streamlit_webrtc import WebRtcMode, webrtc_streamer
|
5 |
+
import torch
|
6 |
+
|
7 |
+
from sample_utils.turn import get_ice_servers
|
8 |
+
|
9 |
+
st.markdown(
|
10 |
+
"# Object detection with YOLO"
|
11 |
+
)
|
12 |
+
|
13 |
+
# YOLO estandar model
|
14 |
+
model_yolo = torch.hub.load('Ultralytics/yolov5','yolov5s', pretrained = True, verbose = False)
|
15 |
+
model_yolo.eval()
|
16 |
+
labels = model_yolo.names
|
17 |
+
person_class_index = 0
|
18 |
+
|
19 |
+
|
20 |
+
def callback(frame: av.VideoFrame) -> av.VideoFrame:
|
21 |
+
|
22 |
+
# Get the image
|
23 |
+
img = frame.to_ndarray(format="bgr24")
|
24 |
+
|
25 |
+
# Preprocessing image
|
26 |
+
scale = 3 # percent of original size
|
27 |
+
width = int(img.shape[1] / scale)
|
28 |
+
height = int(img.shape[0] / scale)
|
29 |
+
dim = (width, height)
|
30 |
+
|
31 |
+
img2 = cv2.resize(img, dim, interpolation = cv2.INTER_AREA)
|
32 |
+
|
33 |
+
# model detections results
|
34 |
+
detections = model_yolo(img2)
|
35 |
+
#print(detections)
|
36 |
+
|
37 |
+
# Draw bounding boxes
|
38 |
+
for detection in detections.xyxy[0]:
|
39 |
+
x1, y1, x2, y2, p, category_id = detection
|
40 |
+
x1, y1, x2, y2, category_id = int(x1), int(y1), int(x2), int(y2), int(category_id)
|
41 |
+
#if category_id == person_class_index:
|
42 |
+
#cv2.rectangle(img, (x1*scale, y1*scale), (x2*scale, y2*scale), (55,139,241), 2)
|
43 |
+
cv2.putText(img,
|
44 |
+
labels[category_id],
|
45 |
+
(x1*scale, y1*scale - 5),
|
46 |
+
cv2.FONT_HERSHEY_TRIPLEX,
|
47 |
+
0.5, (255,255,255), 1)
|
48 |
+
xc = int((x1+x2)*scale/2.0)
|
49 |
+
yc = int((y1+y2)*scale/2.0)
|
50 |
+
cv2.circle(img, (xc, yc), 10, (255,255,255), -1)
|
51 |
+
cv2.line(img, (x1*scale, y1*scale), (xc, yc), (255,255,255), 2)
|
52 |
+
|
53 |
+
|
54 |
+
return av.VideoFrame.from_ndarray(img, format="bgr24")
|
55 |
+
|
56 |
+
|
57 |
+
webrtc_streamer(
|
58 |
+
key="opencv-filter",
|
59 |
+
mode=WebRtcMode.SENDRECV,
|
60 |
+
rtc_configuration={"iceServers": get_ice_servers()},
|
61 |
+
video_frame_callback=callback,
|
62 |
+
media_stream_constraints={"video": True, "audio": False},
|
63 |
+
async_processing=True,
|
64 |
+
)
|
65 |
+
|
66 |
+
|
67 |
+
|
68 |
+
st.markdown(
|
69 |
+
"This demo is based on "
|
70 |
+
"https://github.com/whitphx/streamlit-webrtc-example. "
|
71 |
+
"Many thanks to the project."
|
72 |
+
)
|
requirements.txt
ADDED
@@ -0,0 +1,93 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
aiohttp==3.8.6
|
2 |
+
aiohttp-retry==2.8.3
|
3 |
+
aioice==0.9.0
|
4 |
+
aiortc==1.5.0
|
5 |
+
aiosignal==1.3.1
|
6 |
+
altair==5.1.2
|
7 |
+
async-timeout==4.0.3
|
8 |
+
attrs==23.1.0
|
9 |
+
av==10.0.0
|
10 |
+
backports.zoneinfo==0.2.1
|
11 |
+
blinker==1.6.3
|
12 |
+
cachetools==5.3.1
|
13 |
+
certifi==2023.7.22
|
14 |
+
cffi==1.16.0
|
15 |
+
charset-normalizer==3.3.0
|
16 |
+
click==8.1.7
|
17 |
+
contourpy==1.1.1
|
18 |
+
cryptography==41.0.4
|
19 |
+
cycler==0.12.1
|
20 |
+
dnspython==2.4.2
|
21 |
+
filelock==3.12.4
|
22 |
+
fonttools==4.43.1
|
23 |
+
frozenlist==1.4.0
|
24 |
+
fsspec==2023.9.2
|
25 |
+
gitdb==4.0.10
|
26 |
+
GitPython==3.1.40
|
27 |
+
google-crc32c==1.5.0
|
28 |
+
idna==3.4
|
29 |
+
ifaddr==0.2.0
|
30 |
+
importlib-metadata==6.8.0
|
31 |
+
importlib-resources==6.1.0
|
32 |
+
Jinja2==3.1.2
|
33 |
+
jsonschema==4.19.1
|
34 |
+
jsonschema-specifications==2023.7.1
|
35 |
+
kiwisolver==1.4.5
|
36 |
+
markdown-it-py==3.0.0
|
37 |
+
MarkupSafe==2.1.3
|
38 |
+
matplotlib==3.7.3
|
39 |
+
mdurl==0.1.2
|
40 |
+
mpmath==1.3.0
|
41 |
+
multidict==6.0.4
|
42 |
+
networkx==3.1
|
43 |
+
numpy==1.24.4
|
44 |
+
opencv-contrib-python==4.8.1.78
|
45 |
+
opencv-python==4.8.1.78
|
46 |
+
packaging==23.2
|
47 |
+
pandas==2.0.3
|
48 |
+
Pillow==10.1.0
|
49 |
+
pkgutil_resolve_name==1.3.10
|
50 |
+
protobuf==4.24.4
|
51 |
+
psutil==5.9.6
|
52 |
+
py-cpuinfo==9.0.0
|
53 |
+
pyarrow==13.0.0
|
54 |
+
pycparser==2.21
|
55 |
+
pydeck==0.8.1b0
|
56 |
+
pydub==0.25.1
|
57 |
+
pyee==11.0.1
|
58 |
+
Pygments==2.16.1
|
59 |
+
PyJWT==2.8.0
|
60 |
+
pylibsrtp==0.8.0
|
61 |
+
pyOpenSSL==23.2.0
|
62 |
+
pyparsing==3.1.1
|
63 |
+
python-dateutil==2.8.2
|
64 |
+
pytz==2023.3.post1
|
65 |
+
PyYAML==6.0.1
|
66 |
+
referencing==0.30.2
|
67 |
+
requests==2.31.0
|
68 |
+
rich==13.6.0
|
69 |
+
rpds-py==0.10.6
|
70 |
+
scipy==1.10.1
|
71 |
+
seaborn==0.13.0
|
72 |
+
six==1.16.0
|
73 |
+
smmap==5.0.1
|
74 |
+
streamlit==1.27.2
|
75 |
+
streamlit-webrtc==0.47.1
|
76 |
+
sympy==1.12
|
77 |
+
tenacity==8.2.3
|
78 |
+
thop==0.1.1.post2209072238
|
79 |
+
toml==0.10.2
|
80 |
+
toolz==0.12.0
|
81 |
+
torch==2.1.0
|
82 |
+
torchvision==0.16.0
|
83 |
+
tornado==6.3.3
|
84 |
+
tqdm==4.66.1
|
85 |
+
twilio==8.9.1
|
86 |
+
typing_extensions==4.8.0
|
87 |
+
tzdata==2023.3
|
88 |
+
tzlocal==5.1
|
89 |
+
ultralytics==8.0.200
|
90 |
+
urllib3==2.0.7
|
91 |
+
validators==0.22.0
|
92 |
+
yarl==1.9.2
|
93 |
+
zipp==3.17.0
|
sample_utils/__init__.py
ADDED
File without changes
|
sample_utils/download.py
ADDED
@@ -0,0 +1,50 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import urllib.request
|
2 |
+
from pathlib import Path
|
3 |
+
|
4 |
+
import streamlit as st
|
5 |
+
|
6 |
+
|
7 |
+
# This code is based on https://github.com/streamlit/demo-self-driving/blob/230245391f2dda0cb464008195a470751c01770b/streamlit_app.py#L48 # noqa: E501
|
8 |
+
def download_file(url, download_to: Path, expected_size=None):
|
9 |
+
# Don't download the file twice.
|
10 |
+
# (If possible, verify the download using the file length.)
|
11 |
+
if download_to.exists():
|
12 |
+
if expected_size:
|
13 |
+
if download_to.stat().st_size == expected_size:
|
14 |
+
return
|
15 |
+
else:
|
16 |
+
st.info(f"{url} is already downloaded.")
|
17 |
+
if not st.button("Download again?"):
|
18 |
+
return
|
19 |
+
|
20 |
+
download_to.parent.mkdir(parents=True, exist_ok=True)
|
21 |
+
|
22 |
+
# These are handles to two visual elements to animate.
|
23 |
+
weights_warning, progress_bar = None, None
|
24 |
+
try:
|
25 |
+
weights_warning = st.warning("Downloading %s..." % url)
|
26 |
+
progress_bar = st.progress(0)
|
27 |
+
with open(download_to, "wb") as output_file:
|
28 |
+
with urllib.request.urlopen(url) as response:
|
29 |
+
length = int(response.info()["Content-Length"])
|
30 |
+
counter = 0.0
|
31 |
+
MEGABYTES = 2.0 ** 20.0
|
32 |
+
while True:
|
33 |
+
data = response.read(8192)
|
34 |
+
if not data:
|
35 |
+
break
|
36 |
+
counter += len(data)
|
37 |
+
output_file.write(data)
|
38 |
+
|
39 |
+
# We perform animation by overwriting the elements.
|
40 |
+
weights_warning.warning(
|
41 |
+
"Downloading %s... (%6.2f/%6.2f MB)"
|
42 |
+
% (url, counter / MEGABYTES, length / MEGABYTES)
|
43 |
+
)
|
44 |
+
progress_bar.progress(min(counter / length, 1.0))
|
45 |
+
# Finally, we remove these visual elements by calling .empty().
|
46 |
+
finally:
|
47 |
+
if weights_warning is not None:
|
48 |
+
weights_warning.empty()
|
49 |
+
if progress_bar is not None:
|
50 |
+
progress_bar.empty()
|
sample_utils/turn.py
ADDED
@@ -0,0 +1,39 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import logging
|
2 |
+
import os
|
3 |
+
|
4 |
+
import streamlit as st
|
5 |
+
from twilio.base.exceptions import TwilioRestException
|
6 |
+
from twilio.rest import Client
|
7 |
+
|
8 |
+
logger = logging.getLogger(__name__)
|
9 |
+
|
10 |
+
|
11 |
+
def get_ice_servers():
|
12 |
+
"""Use Twilio's TURN server because Streamlit Community Cloud has changed
|
13 |
+
its infrastructure and WebRTC connection cannot be established without TURN server now. # noqa: E501
|
14 |
+
We considered Open Relay Project (https://www.metered.ca/tools/openrelay/) too,
|
15 |
+
but it is not stable and hardly works as some people reported like https://github.com/aiortc/aiortc/issues/832#issuecomment-1482420656 # noqa: E501
|
16 |
+
See https://github.com/whitphx/streamlit-webrtc/issues/1213
|
17 |
+
"""
|
18 |
+
|
19 |
+
# Ref: https://www.twilio.com/docs/stun-turn/api
|
20 |
+
try:
|
21 |
+
account_sid = os.environ["TWILIO_ACCOUNT_SID"]
|
22 |
+
auth_token = os.environ["TWILIO_AUTH_TOKEN"]
|
23 |
+
except KeyError:
|
24 |
+
logger.warning(
|
25 |
+
"Twilio credentials are not set. Fallback to a free STUN server from Google." # noqa: E501
|
26 |
+
)
|
27 |
+
return [{"urls": ["stun:stun.l.google.com:19302"]}]
|
28 |
+
|
29 |
+
client = Client(account_sid, auth_token)
|
30 |
+
|
31 |
+
try:
|
32 |
+
token = client.tokens.create()
|
33 |
+
except TwilioRestException as e:
|
34 |
+
st.warning(
|
35 |
+
f"Error occurred while accessing Twilio API. Fallback to a free STUN server from Google. ({e})" # noqa: E501
|
36 |
+
)
|
37 |
+
return [{"urls": ["stun:stun.l.google.com:19302"]}]
|
38 |
+
|
39 |
+
return token.ice_servers
|
yolov5s.pt
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:8b3b748c1e592ddd8868022e8732fde20025197328490623cc16c6f24d0782ee
|
3 |
+
size 14808437
|