eslam21 commited on
Commit
8ee37ef
·
1 Parent(s): 220e06e

Upload 12 files

Browse files
.gitattributes CHANGED
@@ -33,3 +33,5 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
 
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ data/sample_images/2.jpg filter=lfs diff=lfs merge=lfs -text
37
+ output.gif filter=lfs diff=lfs merge=lfs -text
README.md CHANGED
@@ -1,13 +1,39 @@
1
- ---
2
- title: Objects
3
- emoji: 🏢
4
- colorFrom: indigo
5
- colorTo: gray
6
- sdk: streamlit
7
- sdk_version: 1.26.0
8
- app_file: app.py
9
- pinned: false
10
- license: mit
11
- ---
12
-
13
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Yolov5 Real-time Inference using Streamlit
2
+ A web interface for real-time yolo inference using streamlit. It supports CPU and GPU inference, supports both images and videos and uploading your own custom models.
3
+
4
+ <img src="output.gif" alt="demo of the dashboard" width="800"/>
5
+
6
+ ### [Live Demo](https://moaaztaha-yolo-interface-using-streamlit-app-ioset2.streamlit.app/)
7
+
8
+
9
+ ## Features
10
+ - **Caches** the model for faster inference on both CPU and GPU.
11
+ - Supports uploading model files (<200MB) and downloading models from URL (any size)
12
+ - Supports both images and videos.
13
+ - Supports both CPU and GPU inference.
14
+ - Supports:
15
+ - Custom Classes
16
+ - Changing Confidence
17
+ - Changing input/frame size for videos
18
+
19
+
20
+ ## How to run
21
+ After cloning the repo:
22
+ 1. Install requirements
23
+ - `pip install -r requirements.txt`
24
+ 2. Add sample images to `data/sample_images`
25
+ 3. Add sample video to `data/sample_videos` and call it `sample.mp4` or change name in the code.
26
+ 4. Add the model file to `models/` and change `cfg_model_path` to its path.
27
+ ```bash
28
+ git clone https://github.com/moaaztaha/Yolo-Interface-using-Streamlit
29
+ cd Yolo-Interface-using-Streamlit
30
+ streamlit run app.py
31
+ ```
32
+
33
+ ### To-do Next
34
+ - [x] Allow model upload (file / url).
35
+ - [x] resizing video frames for faster processing.
36
+ - [ ] batch processing, processes the whole video and then show the results.
37
+
38
+ ## References
39
+ https://discuss.streamlit.io/t/deploy-yolov5-object-detection-on-streamlit/27675
app.py ADDED
@@ -0,0 +1,210 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import glob
2
+ import streamlit as st
3
+ import wget
4
+ from PIL import Image
5
+ import torch
6
+ import cv2
7
+ import os
8
+ import time
9
+
10
+ st.set_page_config(layout="wide")
11
+
12
+ cfg_model_path = 'models/yolov5s.pt'
13
+ model = None
14
+ confidence = .25
15
+
16
+
17
+ def image_input(data_src):
18
+ img_file = None
19
+ if data_src == 'Sample data':
20
+ # get all sample images
21
+ img_path = glob.glob('data/sample_images/*')
22
+ img_slider = st.slider("Select a test image.", min_value=1, max_value=len(img_path), step=1)
23
+ img_file = img_path[img_slider - 1]
24
+ else:
25
+ img_bytes = st.sidebar.file_uploader("Upload an image", type=['png', 'jpeg', 'jpg',"jfif","iff"])
26
+ if img_bytes:
27
+ img_file = "data/uploaded_data/upload." + img_bytes.name.split('.')[-1]
28
+ Image.open(img_bytes).save(img_file)
29
+
30
+ if img_file:
31
+ col1, col2 = st.columns(2)
32
+ with col1:
33
+ st.image(img_file, caption="Selected Image")
34
+ with col2:
35
+ img = infer_image(img_file)
36
+ st.image(img, caption="Model prediction")
37
+
38
+
39
+ def video_input(data_src):
40
+ vid_file = None
41
+ if data_src == 'Sample data':
42
+ vid_file = "data/sample_videos/sample.mp4"
43
+ else:
44
+ vid_bytes = st.sidebar.file_uploader("Upload a video", type=['mp4', 'mpv', 'avi'])
45
+ if vid_bytes:
46
+ vid_file = "data/uploaded_data/upload." + vid_bytes.name.split('.')[-1]
47
+ with open(vid_file, 'wb') as out:
48
+ out.write(vid_bytes.read())
49
+
50
+ if vid_file:
51
+ cap = cv2.VideoCapture(vid_file)
52
+ custom_size = st.sidebar.checkbox("Custom frame size")
53
+ width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
54
+ height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
55
+ if custom_size:
56
+ width = st.sidebar.number_input("Width", min_value=120, step=20, value=width)
57
+ height = st.sidebar.number_input("Height", min_value=120, step=20, value=height)
58
+
59
+ fps = 0
60
+ st1, st2, st3 = st.columns(3)
61
+ with st1:
62
+ st.markdown("## Height")
63
+ st1_text = st.markdown(f"{height}")
64
+ with st2:
65
+ st.markdown("## Width")
66
+ st2_text = st.markdown(f"{width}")
67
+ with st3:
68
+ st.markdown("## FPS")
69
+ st3_text = st.markdown(f"{fps}")
70
+
71
+ st.markdown("---")
72
+ output = st.empty()
73
+ prev_time = 0
74
+ curr_time = 0
75
+ update_frequency = 5 # Update every 5 frames
76
+ frames_processed = 0
77
+ last_fps_update = time.time()
78
+
79
+ while True:
80
+ ret, frame = cap.read()
81
+ if not ret:
82
+ st.write("Can't read frame, stream ended? Exiting ....")
83
+ break
84
+
85
+ frames_processed += 1
86
+ if frames_processed >= update_frequency:
87
+ frames_processed = 0 # Reset counter
88
+
89
+ frame = cv2.resize(frame, (width, height))
90
+ frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
91
+ output_img = infer_image(frame)
92
+
93
+ # Update the UI every update_frequency frames
94
+ output.image(output_img)
95
+
96
+ curr_time = time.time()
97
+ fps = 1 / (curr_time - prev_time)
98
+ prev_time = curr_time
99
+
100
+ # Update FPS UI every second
101
+ if curr_time - last_fps_update >= 1:
102
+ st3_text.markdown(f"**{fps:.2f}**")
103
+ last_fps_update = curr_time
104
+
105
+ cap.release()
106
+
107
+
108
+ def infer_image(img, size=None):
109
+ model.conf = confidence
110
+ result = model(img, size=size) if size else model(img)
111
+ result.render()
112
+ image = Image.fromarray(result.ims[0])
113
+ return image
114
+
115
+
116
+ @st.cache_resource
117
+ def load_model(path, device):
118
+ model_ = torch.hub.load('ultralytics/yolov5', 'custom', path=path, force_reload=True)
119
+ model_.to(device)
120
+ print("model to ", device)
121
+ return model_
122
+
123
+
124
+ @st.cache_resource
125
+ def download_model(url):
126
+ model_file = wget.download(url, out="models")
127
+ return model_file
128
+
129
+
130
+ def get_user_model():
131
+ model_src = st.sidebar.radio("Model source", ["file upload", "url"])
132
+ model_file = None
133
+ if model_src == "file upload":
134
+ model_bytes = st.sidebar.file_uploader("Upload a model file", type=['pt'])
135
+ if model_bytes:
136
+ model_file = "models/uploaded_" + model_bytes.name
137
+ with open(model_file, 'wb') as out:
138
+ out.write(model_bytes.read())
139
+ else:
140
+ url = st.sidebar.text_input("model url")
141
+ if url:
142
+ model_file_ = download_model(url)
143
+ if model_file_.split(".")[-1] == "pt":
144
+ model_file = model_file_
145
+
146
+ return model_file
147
+
148
+ def main():
149
+ # global variables
150
+ global model, confidence, cfg_model_path
151
+
152
+ st.title("Object Recognition Dashboard")
153
+
154
+ st.sidebar.title("Settings")
155
+
156
+ # upload model
157
+ model_src = st.sidebar.radio("Select yolov5 weight file", ["Use our demo model 5s", "Use your own model"])
158
+ # URL, upload file (max 200 mb)
159
+ if model_src == "Use your own model":
160
+ user_model_path = get_user_model()
161
+ if user_model_path:
162
+ cfg_model_path = user_model_path
163
+
164
+ st.sidebar.text(cfg_model_path.split("/")[-1])
165
+ st.sidebar.markdown("---")
166
+
167
+ # check if model file is available
168
+ if not os.path.isfile(cfg_model_path):
169
+ st.warning("Model file not available!!!, please added to the model folder.", icon="⚠️")
170
+ else:
171
+ # device options
172
+ if torch.cuda.is_available():
173
+ device_option = st.sidebar.radio("Select Device", ['cpu', 'cuda'], disabled=False, index=0)
174
+ else:
175
+ device_option = st.sidebar.radio("Select Device", ['cpu', 'cuda'], disabled=True, index=0)
176
+
177
+ # load model
178
+ model = load_model(cfg_model_path, device_option)
179
+
180
+ # confidence slider
181
+ confidence = st.sidebar.slider('Confidence', min_value=0.1, max_value=1.0, value=.45)
182
+
183
+ # custom classes
184
+ if st.sidebar.checkbox("Custom Classes"):
185
+ model_names = list(model.names.values())
186
+ assigned_class = st.sidebar.multiselect("Select Classes", model_names, default=[model_names[0]])
187
+ classes = [model_names.index(name) for name in assigned_class]
188
+ model.classes = classes
189
+ else:
190
+ model.classes = list(model.names.keys())
191
+
192
+ st.sidebar.markdown("---")
193
+
194
+ # input options
195
+ input_option = st.sidebar.radio("Select input type: ", ['image', 'video'])
196
+
197
+ # input src option
198
+ data_src = st.sidebar.radio("Select input source: ", ['Sample data', 'Upload your own data'])
199
+
200
+ if input_option == 'image':
201
+ image_input(data_src)
202
+ else:
203
+ video_input(data_src)
204
+
205
+
206
+ if __name__ == "__main__":
207
+ try:
208
+ main()
209
+ except SystemExit:
210
+ pass
data/sample_images/1.jpg ADDED
data/sample_images/2.jpg ADDED

Git LFS Details

  • SHA256: e14ef06472550646528e75d889545214cf84f04c3b2c176430a36b173f35dce4
  • Pointer size: 132 Bytes
  • Size of remote file: 1.09 MB
data/sample_images/3.jpg ADDED
data/sample_videos/sample.mp4 ADDED
Binary file (940 kB). View file
 
data/uploaded_data/upload.jfif ADDED
Binary file (72.3 kB). View file
 
data/uploaded_data/upload.jpg ADDED
data/uploaded_data/upload.mp4 ADDED
Binary file (995 kB). View file
 
models/yolov5s.pt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:8b3b748c1e592ddd8868022e8732fde20025197328490623cc16c6f24d0782ee
3
+ size 14808437
output.gif ADDED

Git LFS Details

  • SHA256: 835a7b1da90e820439831c8e7bc846a381d7db6ea06567e896c6e6711b430f6f
  • Pointer size: 132 Bytes
  • Size of remote file: 2.41 MB
requirements.txt ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # YOLOv5 requirements
2
+ # Usage: pip install -r requirements.txt
3
+
4
+ # Base ----------------------------------------
5
+ matplotlib>=3.2.2
6
+ numpy>=1.18.5
7
+ opencv-python-headless
8
+ Pillow>=7.1.2
9
+ PyYAML>=5.3.1
10
+ requests>=2.23.0
11
+ scipy>=1.4.1 # Google Colab version
12
+ torch>=1.7.0
13
+ torchvision>=0.8.1
14
+ ultralytics
15
+ tqdm>=4.41.0
16
+ protobuf<4.21.5 # https://github.com/ultralytics/yolov5/issues/8012
17
+
18
+
19
+ # Plotting ------------------------------------
20
+ pandas>=1.1.4
21
+ seaborn>=0.11.0
22
+
23
+
24
+ # Extras --------------------------------------
25
+ ipython # interactive notebook
26
+ psutil # system utilization
27
+ thop # FLOPs computation
28
+ streamlit
29
+ wget