ch-tseng commited on
Commit
6a3a328
·
1 Parent(s): 5a99eea
Files changed (3) hide show
  1. app.py +75 -2
  2. config.py +45 -0
  3. utils.py +166 -0
app.py CHANGED
@@ -1,4 +1,77 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
  import streamlit as st
2
 
3
- x = st.slider('Select a value')
4
- st.write(x, 'squared is', x * x)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python
2
+ # -*- coding: utf-8 -*-
3
+ """
4
+ -------------------------------------------------
5
+ @File Name: app.py
6
+ @Author: Luyao.zhang
7
+ @Date: 2023/5/15
8
+ @Description:
9
+ -------------------------------------------------
10
+ """
11
+ from pathlib import Path
12
+ from PIL import Image
13
  import streamlit as st
14
 
15
+ import config
16
+ from utils import load_model, infer_uploaded_image, infer_uploaded_video, infer_uploaded_webcam
17
+
18
+ # setting page layout
19
+ st.set_page_config(
20
+ page_title="Interactive Interface for YOLOv8",
21
+ page_icon="🤖",
22
+ layout="wide",
23
+ initial_sidebar_state="expanded"
24
+ )
25
+
26
+ # main page heading
27
+ st.title("Interactive Interface for YOLOv8")
28
+
29
+ # sidebar
30
+ st.sidebar.header("DL Model Config")
31
+
32
+ # model options
33
+ task_type = st.sidebar.selectbox(
34
+ "Select Task",
35
+ ["Detection"]
36
+ )
37
+
38
+ model_type = None
39
+ if task_type == "Detection":
40
+ model_type = st.sidebar.selectbox(
41
+ "Select Model",
42
+ config.DETECTION_MODEL_LIST
43
+ )
44
+ else:
45
+ st.error("Currently only 'Detection' function is implemented")
46
+
47
+ confidence = float(st.sidebar.slider(
48
+ "Select Model Confidence", 30, 100, 50)) / 100
49
+
50
+ model_path = ""
51
+ if model_type:
52
+ model_path = Path(config.DETECTION_MODEL_DIR, str(model_type))
53
+ else:
54
+ st.error("Please Select Model in Sidebar")
55
+
56
+ # load pretrained DL model
57
+ try:
58
+ model = load_model(model_path)
59
+ except Exception as e:
60
+ st.error(f"Unable to load model. Please check the specified path: {model_path}")
61
+
62
+ # image/video options
63
+ st.sidebar.header("Image/Video Config")
64
+ source_selectbox = st.sidebar.selectbox(
65
+ "Select Source",
66
+ config.SOURCES_LIST
67
+ )
68
+
69
+ source_img = None
70
+ if source_selectbox == config.SOURCES_LIST[0]: # Image
71
+ infer_uploaded_image(confidence, model)
72
+ elif source_selectbox == config.SOURCES_LIST[1]: # Video
73
+ infer_uploaded_video(confidence, model)
74
+ elif source_selectbox == config.SOURCES_LIST[2]: # Webcam
75
+ infer_uploaded_webcam(confidence, model)
76
+ else:
77
+ st.error("Currently only 'Image' and 'Video' source are implemented")
config.py ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python
2
+ # -*- coding: utf-8 -*-
3
+ """
4
+ -------------------------------------------------
5
+ @File Name: config.py
6
+ @Author: Luyao.zhang
7
+ @Date: 2023/5/16
8
+ @Description: configuration file
9
+ -------------------------------------------------
10
+ """
11
+ from pathlib import Path
12
+ import sys
13
+
14
+ # Get the absolute path of the current file
15
+ file_path = Path(__file__).resolve()
16
+
17
+ # Get the parent directory of the current file
18
+ root_path = file_path.parent
19
+
20
+ # Add the root path to the sys.path list if it is not already there
21
+ if root_path not in sys.path:
22
+ sys.path.append(str(root_path))
23
+
24
+ # Get the relative path of the root directory with respect to the current working directory
25
+ ROOT = root_path.relative_to(Path.cwd())
26
+
27
+
28
+ # Source
29
+ SOURCES_LIST = ["Image", "Video", "Webcam"]
30
+
31
+
32
+ # DL model config
33
+ DETECTION_MODEL_DIR = ROOT / 'models' / 'detection'
34
+ YOLOv8n = DETECTION_MODEL_DIR / "yolov8n.pt"
35
+ YOLOv8s = DETECTION_MODEL_DIR / "yolov8s.pt"
36
+ YOLOv8m = DETECTION_MODEL_DIR / "yolov8m.pt"
37
+ YOLOv8l = DETECTION_MODEL_DIR / "yolov8l.pt"
38
+ YOLOv8x = DETECTION_MODEL_DIR / "yolov8x.pt"
39
+
40
+ DETECTION_MODEL_LIST = [
41
+ "yolov8n.pt",
42
+ "yolov8s.pt",
43
+ "yolov8m.pt",
44
+ "yolov8l.pt",
45
+ "yolov8x.pt"]
utils.py ADDED
@@ -0,0 +1,166 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python
2
+ # -*- coding: utf-8 -*-
3
+ """
4
+ -------------------------------------------------
5
+ @File Name: utils.py
6
+ @Author: Luyao.zhang
7
+ @Date: 2023/5/16
8
+ @Description:
9
+ -------------------------------------------------
10
+ """
11
+ from ultralytics import YOLO
12
+ import streamlit as st
13
+ import cv2
14
+ from PIL import Image
15
+ import tempfile
16
+
17
+
18
+ def _display_detected_frames(conf, model, st_frame, image):
19
+ """
20
+ Display the detected objects on a video frame using the YOLOv8 model.
21
+ :param conf (float): Confidence threshold for object detection.
22
+ :param model (YOLOv8): An instance of the `YOLOv8` class containing the YOLOv8 model.
23
+ :param st_frame (Streamlit object): A Streamlit object to display the detected video.
24
+ :param image (numpy array): A numpy array representing the video frame.
25
+ :return: None
26
+ """
27
+ # Resize the image to a standard size
28
+ image = cv2.resize(image, (720, int(720 * (9 / 16))))
29
+
30
+ # Predict the objects in the image using YOLOv8 model
31
+ res = model.predict(image, conf=conf)
32
+
33
+ # Plot the detected objects on the video frame
34
+ res_plotted = res[0].plot()
35
+ st_frame.image(res_plotted,
36
+ caption='Detected Video',
37
+ channels="BGR",
38
+ use_column_width=True
39
+ )
40
+
41
+
42
+ @st.cache_resource
43
+ def load_model(model_path):
44
+ """
45
+ Loads a YOLO object detection model from the specified model_path.
46
+
47
+ Parameters:
48
+ model_path (str): The path to the YOLO model file.
49
+
50
+ Returns:
51
+ A YOLO object detection model.
52
+ """
53
+ model = YOLO(model_path)
54
+ return model
55
+
56
+
57
+ def infer_uploaded_image(conf, model):
58
+ """
59
+ Execute inference for uploaded image
60
+ :param conf: Confidence of YOLOv8 model
61
+ :param model: An instance of the `YOLOv8` class containing the YOLOv8 model.
62
+ :return: None
63
+ """
64
+ source_img = st.sidebar.file_uploader(
65
+ label="Choose an image...",
66
+ type=("jpg", "jpeg", "png", 'bmp', 'webp')
67
+ )
68
+
69
+ col1, col2 = st.columns(2)
70
+
71
+ with col1:
72
+ if source_img:
73
+ uploaded_image = Image.open(source_img)
74
+ # adding the uploaded image to the page with caption
75
+ st.image(
76
+ image=source_img,
77
+ caption="Uploaded Image",
78
+ use_column_width=True
79
+ )
80
+
81
+ if source_img:
82
+ if st.button("Execution"):
83
+ with st.spinner("Running..."):
84
+ res = model.predict(uploaded_image,
85
+ conf=conf)
86
+ boxes = res[0].boxes
87
+ res_plotted = res[0].plot()[:, :, ::-1]
88
+
89
+ with col2:
90
+ st.image(res_plotted,
91
+ caption="Detected Image",
92
+ use_column_width=True)
93
+ try:
94
+ with st.expander("Detection Results"):
95
+ for box in boxes:
96
+ st.write(box.xywh)
97
+ except Exception as ex:
98
+ st.write("No image is uploaded yet!")
99
+ st.write(ex)
100
+
101
+
102
+ def infer_uploaded_video(conf, model):
103
+ """
104
+ Execute inference for uploaded video
105
+ :param conf: Confidence of YOLOv8 model
106
+ :param model: An instance of the `YOLOv8` class containing the YOLOv8 model.
107
+ :return: None
108
+ """
109
+ source_video = st.sidebar.file_uploader(
110
+ label="Choose a video..."
111
+ )
112
+
113
+ if source_video:
114
+ st.video(source_video)
115
+
116
+ if source_video:
117
+ if st.button("Execution"):
118
+ with st.spinner("Running..."):
119
+ try:
120
+ tfile = tempfile.NamedTemporaryFile()
121
+ tfile.write(source_video.read())
122
+ vid_cap = cv2.VideoCapture(
123
+ tfile.name)
124
+ st_frame = st.empty()
125
+ while (vid_cap.isOpened()):
126
+ success, image = vid_cap.read()
127
+ if success:
128
+ _display_detected_frames(conf,
129
+ model,
130
+ st_frame,
131
+ image
132
+ )
133
+ else:
134
+ vid_cap.release()
135
+ break
136
+ except Exception as e:
137
+ st.error(f"Error loading video: {e}")
138
+
139
+
140
+ def infer_uploaded_webcam(conf, model):
141
+ """
142
+ Execute inference for webcam.
143
+ :param conf: Confidence of YOLOv8 model
144
+ :param model: An instance of the `YOLOv8` class containing the YOLOv8 model.
145
+ :return: None
146
+ """
147
+ try:
148
+ flag = st.button(
149
+ label="Stop running"
150
+ )
151
+ vid_cap = cv2.VideoCapture(0) # local camera
152
+ st_frame = st.empty()
153
+ while not flag:
154
+ success, image = vid_cap.read()
155
+ if success:
156
+ _display_detected_frames(
157
+ conf,
158
+ model,
159
+ st_frame,
160
+ image
161
+ )
162
+ else:
163
+ vid_cap.release()
164
+ break
165
+ except Exception as e:
166
+ st.error(f"Error loading video: {str(e)}")