pnicewiczoig commited on
Commit
f46a62b
·
1 Parent(s): 65509ad

minimal app

Browse files
Files changed (3) hide show
  1. Makefile +15 -0
  2. app.py +184 -0
  3. requirements.txt +26 -0
Makefile ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ install:
2
+ pip install --upgrade pip
3
+ pip install -r requirements.txt
4
+
5
+ test:
6
+ python -m pytest -vv app.py
7
+
8
+ format:
9
+ black *.py
10
+
11
+ lint:
12
+ pylint --disable=R, C *.py
13
+
14
+ all:
15
+ install lint test format
app.py ADDED
@@ -0,0 +1,184 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ from ultralyticsplus import YOLO, render_result
11
+
12
+
13
+ st.set_page_config(layout="wide")
14
+
15
+ cfg_model_path = 'models/yolov5s.pt'
16
+ model = None
17
+ confidence = .25
18
+
19
+
20
+ def image_input(data_src):
21
+ img_file = None
22
+ if data_src == 'Sample data':
23
+ # get all sample images
24
+ img_path = glob.glob('data/sample_images/*')
25
+ img_slider = st.slider("Select a test image.", min_value=1, max_value=len(img_path), step=1)
26
+ img_file = img_path[img_slider - 1]
27
+ else:
28
+ img_bytes = st.sidebar.file_uploader("Upload an image", type=['png', 'jpeg', 'jpg'])
29
+ if img_bytes:
30
+ img_file = "data/uploaded_data/upload." + img_bytes.name.split('.')[-1]
31
+ Image.open(img_bytes).save(img_file)
32
+
33
+ if img_file:
34
+ col1, col2 = st.columns(2)
35
+ with col1:
36
+ st.image(img_file, caption="Selected Image")
37
+ with col2:
38
+ img = infer_image(img_file)
39
+ st.image(img, caption="Model prediction")
40
+
41
+
42
+ def video_input(data_src):
43
+ vid_file = None
44
+ if data_src == 'Sample data':
45
+ vid_file = "data/sample_videos/sample.mp4"
46
+ else:
47
+ vid_bytes = st.sidebar.file_uploader("Upload a video", type=['mp4', 'mpv', 'avi'])
48
+ if vid_bytes:
49
+ vid_file = "data/uploaded_data/upload." + vid_bytes.name.split('.')[-1]
50
+ with open(vid_file, 'wb') as out:
51
+ out.write(vid_bytes.read())
52
+
53
+ if vid_file:
54
+ cap = cv2.VideoCapture(vid_file)
55
+ custom_size = st.sidebar.checkbox("Custom frame size")
56
+ width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
57
+ height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
58
+ if custom_size:
59
+ width = st.sidebar.number_input("Width", min_value=120, step=20, value=width)
60
+ height = st.sidebar.number_input("Height", min_value=120, step=20, value=height)
61
+
62
+ fps = 0
63
+ st1, st2, st3 = st.columns(3)
64
+ with st1:
65
+ st.markdown("## Height")
66
+ st1_text = st.markdown(f"{height}")
67
+ with st2:
68
+ st.markdown("## Width")
69
+ st2_text = st.markdown(f"{width}")
70
+ with st3:
71
+ st.markdown("## FPS")
72
+ st3_text = st.markdown(f"{fps}")
73
+
74
+ st.markdown("---")
75
+ output = st.empty()
76
+ prev_time = 0
77
+ curr_time = 0
78
+ while True:
79
+ ret, frame = cap.read()
80
+ if not ret:
81
+ st.write("Can't read frame, stream ended? Exiting ....")
82
+ break
83
+ frame = cv2.resize(frame, (width, height))
84
+ frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
85
+ output_img = infer_image(frame)
86
+ output.image(output_img)
87
+ curr_time = time.time()
88
+ fps = 1 / (curr_time - prev_time)
89
+ prev_time = curr_time
90
+ st1_text.markdown(f"**{height}**")
91
+ st2_text.markdown(f"**{width}**")
92
+ st3_text.markdown(f"**{fps:.2f}**")
93
+
94
+ cap.release()
95
+
96
+
97
+ def infer_image(img, size=None):
98
+ model.conf = confidence
99
+ result = model(img, size=size) if size else model(img)
100
+ result.render()
101
+ image = Image.fromarray(result.ims[0])
102
+ return image
103
+
104
+
105
+ @st.experimental_singleton
106
+ def load_model(path, device):
107
+ model_ = torch.hub.load('ultralytics/yolov5', 'custom', path=path, force_reload=True)
108
+ model_.to(device)
109
+ print("model to ", device)
110
+ return model_
111
+
112
+
113
+ @st.experimental_singleton
114
+ def download_model(url):
115
+ model_file = wget.download(url, out="models")
116
+ return model_file
117
+
118
+
119
+ def get_user_model():
120
+ model_src = st.sidebar.radio("Model source", ["file upload", "url"])
121
+ model_file = None
122
+ if model_src == "file upload":
123
+ model_bytes = st.sidebar.file_uploader("Upload a model file", type=['pt'])
124
+ if model_bytes:
125
+ model_file = "models/uploaded_" + model_bytes.name
126
+ with open(model_file, 'wb') as out:
127
+ out.write(model_bytes.read())
128
+ else:
129
+ url = st.sidebar.text_input("model url")
130
+ if url:
131
+ model_file_ = download_model(url)
132
+ if model_file_.split(".")[-1] == "pt":
133
+ model_file = model_file_
134
+
135
+ return model_file
136
+
137
+ def main():
138
+ # global variables
139
+ global model, confidence, cfg_model_path
140
+
141
+ st.title("Object Recognition Dashboard")
142
+
143
+ st.sidebar.title("Settings")
144
+
145
+ # device options
146
+ if torch.cuda.is_available():
147
+ device_option = st.sidebar.radio("Select Device", ['cpu', 'cuda'], disabled=False, index=0)
148
+ else:
149
+ device_option = st.sidebar.radio("Select Device", ['cpu', 'cuda'], disabled=True, index=0)
150
+
151
+ # load model
152
+ model = YOLO('ultralyticsplus/yolov8s')
153
+
154
+ # confidence slider
155
+ confidence = st.sidebar.slider('Confidence', min_value=0.1, max_value=1.0, value=.45)
156
+
157
+ # custom classes
158
+ if st.sidebar.checkbox("Custom Classes"):
159
+ model_names = list(model.names.values())
160
+ assigned_class = st.sidebar.multiselect("Select Classes", model_names, default=[model_names[0]])
161
+ classes = [model_names.index(name) for name in assigned_class]
162
+ model.classes = classes
163
+ else:
164
+ model.classes = list(model.names.keys())
165
+
166
+ st.sidebar.markdown("---")
167
+
168
+ # input options
169
+ input_option = st.sidebar.radio("Select input type: ", ['image', 'video'])
170
+
171
+ # input src option
172
+ data_src = st.sidebar.radio("Select input source: ", ['Sample data', 'Upload your own data'])
173
+
174
+ if input_option == 'image':
175
+ image_input(data_src)
176
+ else:
177
+ video_input(data_src)
178
+
179
+
180
+ if __name__ == "__main__":
181
+ try:
182
+ main()
183
+ except SystemExit:
184
+ pass
requirements.txt ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Base ----------------------------------------
2
+ ultralyticsplus
3
+ matplotlib>=3.2.2
4
+ numpy>=1.18.5
5
+ opencv-python-headless
6
+ Pillow>=7.1.2
7
+ PyYAML>=5.3.1
8
+ requests>=2.23.0
9
+ scipy>=1.4.1 # Google Colab version
10
+ torch>=1.7.0
11
+ torchvision>=0.8.1
12
+ tqdm>=4.41.0
13
+ protobuf<4.21.5 # https://github.com/ultralytics/yolov5/issues/8012
14
+
15
+
16
+ # Plotting ------------------------------------
17
+ pandas>=1.1.4
18
+ seaborn>=0.11.0
19
+
20
+
21
+ # Extras --------------------------------------
22
+ ipython # interactive notebook
23
+ psutil # system utilization
24
+ thop # FLOPs computation
25
+ streamlit
26
+ wget