Spaces:
Sleeping
Sleeping
Add large file using
Browse files- .devcontainer/devcontainer.json +33 -0
- README.md +5 -12
- coco.names +80 -0
- detection_yolov4.py +245 -0
- helmet.cfg +281 -0
- helmet.names +3 -0
- requirements.txt +3 -0
- yolov4-tiny-custom.cfg +281 -0
.devcontainer/devcontainer.json
ADDED
@@ -0,0 +1,33 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"name": "Python 3",
|
3 |
+
// Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile
|
4 |
+
"image": "mcr.microsoft.com/devcontainers/python:1-3.11-bullseye",
|
5 |
+
"customizations": {
|
6 |
+
"codespaces": {
|
7 |
+
"openFiles": [
|
8 |
+
"README.md",
|
9 |
+
"detection_yolov4.py"
|
10 |
+
]
|
11 |
+
},
|
12 |
+
"vscode": {
|
13 |
+
"settings": {},
|
14 |
+
"extensions": [
|
15 |
+
"ms-python.python",
|
16 |
+
"ms-python.vscode-pylance"
|
17 |
+
]
|
18 |
+
}
|
19 |
+
},
|
20 |
+
"updateContentCommand": "[ -f packages.txt ] && sudo apt update && sudo apt upgrade -y && sudo xargs apt install -y <packages.txt; [ -f requirements.txt ] && pip3 install --user -r requirements.txt; pip3 install --user streamlit; echo '✅ Packages installed and Requirements met'",
|
21 |
+
"postAttachCommand": {
|
22 |
+
"server": "streamlit run detection_yolov4.py --server.enableCORS false --server.enableXsrfProtection false"
|
23 |
+
},
|
24 |
+
"portsAttributes": {
|
25 |
+
"8501": {
|
26 |
+
"label": "Application",
|
27 |
+
"onAutoForward": "openPreview"
|
28 |
+
}
|
29 |
+
},
|
30 |
+
"forwardPorts": [
|
31 |
+
8501
|
32 |
+
]
|
33 |
+
}
|
README.md
CHANGED
@@ -1,12 +1,5 @@
|
|
1 |
-
|
2 |
-
|
3 |
-
|
4 |
-
|
5 |
-
|
6 |
-
sdk: streamlit
|
7 |
-
sdk_version: 1.30.0
|
8 |
-
app_file: app.py
|
9 |
-
pinned: false
|
10 |
-
---
|
11 |
-
|
12 |
-
Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
|
|
|
1 |
+
# Проект на базе Streamlit для определения объектов на фотографии и видео
|
2 |
+
О проекте: наглядная демонтрация работы модели глубокого обучения компьютерного зрения yolov4
|
3 |
+
Название проекта| Цель | Вывод |Ключевые слова проекта | Используемые библиотеки
|
4 |
+
------------- |------------------|---------------- | ---------------- | -----------------------
|
5 |
+
[Определение объектов на фото\видео](https://github.com/Sazuppy/streamlit_yolov4_helmet/)|Задача - на основе набора фотографий людей обучить модель yolov4 на опеределение наличия каски\головного убора на работнике|С помощью сети yolov4, предобученной на датасете coco, было получено значение удовлетворительная работа модели|обработка изображений, нейронные сети|`OpenCV, Python, moviepy`|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
coco.names
ADDED
@@ -0,0 +1,80 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
person
|
2 |
+
bicycle
|
3 |
+
car
|
4 |
+
motorbike
|
5 |
+
aeroplane
|
6 |
+
bus
|
7 |
+
train
|
8 |
+
truck
|
9 |
+
boat
|
10 |
+
traffic light
|
11 |
+
fire hydrant
|
12 |
+
stop sign
|
13 |
+
parking meter
|
14 |
+
bench
|
15 |
+
bird
|
16 |
+
cat
|
17 |
+
dog
|
18 |
+
horse
|
19 |
+
sheep
|
20 |
+
cow
|
21 |
+
elephant
|
22 |
+
bear
|
23 |
+
zebra
|
24 |
+
giraffe
|
25 |
+
backpack
|
26 |
+
umbrella
|
27 |
+
handbag
|
28 |
+
tie
|
29 |
+
suitcase
|
30 |
+
frisbee
|
31 |
+
skis
|
32 |
+
snowboard
|
33 |
+
sports ball
|
34 |
+
kite
|
35 |
+
baseball bat
|
36 |
+
baseball glove
|
37 |
+
skateboard
|
38 |
+
surfboard
|
39 |
+
tennis racket
|
40 |
+
bottle
|
41 |
+
wine glass
|
42 |
+
cup
|
43 |
+
fork
|
44 |
+
knife
|
45 |
+
spoon
|
46 |
+
bowl
|
47 |
+
banana
|
48 |
+
apple
|
49 |
+
sandwich
|
50 |
+
orange
|
51 |
+
broccoli
|
52 |
+
carrot
|
53 |
+
hot dog
|
54 |
+
pizza
|
55 |
+
donut
|
56 |
+
cake
|
57 |
+
chair
|
58 |
+
sofa
|
59 |
+
pottedplant
|
60 |
+
bed
|
61 |
+
diningtable
|
62 |
+
toilet
|
63 |
+
tvmonitor
|
64 |
+
laptop
|
65 |
+
mouse
|
66 |
+
remote
|
67 |
+
keyboard
|
68 |
+
cell phone
|
69 |
+
microwave
|
70 |
+
oven
|
71 |
+
toaster
|
72 |
+
sink
|
73 |
+
refrigerator
|
74 |
+
book
|
75 |
+
clock
|
76 |
+
vase
|
77 |
+
scissors
|
78 |
+
teddy bear
|
79 |
+
hair drier
|
80 |
+
toothbrush
|
detection_yolov4.py
ADDED
@@ -0,0 +1,245 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import cv2 as cv
|
2 |
+
import streamlit as st
|
3 |
+
import tempfile
|
4 |
+
import time
|
5 |
+
from moviepy.editor import VideoClip
|
6 |
+
from moviepy.editor import AudioFileClip
|
7 |
+
import datetime
|
8 |
+
|
9 |
+
@st.cache_resource
|
10 |
+
def yolov4(names, weights, config, Conf_threshold, NMS_threshold):
|
11 |
+
Conf_threshold = Conf_threshold
|
12 |
+
NMS_threshold = NMS_threshold
|
13 |
+
COLORS = [(0, 255, 0), (0, 0, 255), (255, 0, 0),
|
14 |
+
(255, 255, 0), (255, 0, 255), (0, 255, 255)]
|
15 |
+
|
16 |
+
class_name = []
|
17 |
+
with open(names, 'r') as f:
|
18 |
+
class_name = [cname.strip() for cname in f.readlines()]
|
19 |
+
# Инициализация нейросети YOLOv4
|
20 |
+
net = cv.dnn.readNet(weights, config)
|
21 |
+
net.setPreferableBackend(cv.dnn.DNN_BACKEND_CUDA)
|
22 |
+
net.setPreferableTarget(cv.dnn.DNN_TARGET_CUDA_FP16)
|
23 |
+
|
24 |
+
model = cv.dnn_DetectionModel(net)
|
25 |
+
model.setInputParams(size=(416, 416), scale=1/255, swapRB=True)
|
26 |
+
return model, COLORS, class_name
|
27 |
+
|
28 |
+
|
29 |
+
def temp_file(data):
|
30 |
+
# Сохранение видеофайла во временный файл
|
31 |
+
temp_file = tempfile.NamedTemporaryFile(delete=False)
|
32 |
+
temp_file.write(data.read())
|
33 |
+
temp_file_path = temp_file.name
|
34 |
+
|
35 |
+
# Захват видео
|
36 |
+
cap = cv.VideoCapture(temp_file_path)
|
37 |
+
temp_file.close()
|
38 |
+
return cap, temp_file_path
|
39 |
+
|
40 |
+
def image_process(model, cap, Conf_threshold, NMS_threshold, COLORS, class_name):
|
41 |
+
|
42 |
+
ret, frame = cap.read()
|
43 |
+
# Обнаружение объектов с использованием YOLOv4
|
44 |
+
classes, scores, boxes = model.detect(frame, Conf_threshold, NMS_threshold)
|
45 |
+
for (classid, score, box) in zip(classes, scores, boxes):
|
46 |
+
color = COLORS[int(classid) % len(COLORS)]
|
47 |
+
label = "%s : %f" % (class_name[classid], score)
|
48 |
+
cv.rectangle(frame, box, color, 1)
|
49 |
+
cv.putText(frame, label, (box[0], box[1]-10),
|
50 |
+
cv.FONT_HERSHEY_COMPLEX, 0.3, color, 1)
|
51 |
+
frame = cv.resize(frame,(0,0), fx=0.8, fy=0.8)
|
52 |
+
return frame
|
53 |
+
|
54 |
+
def video_process(model, cap, Conf_threshold, NMS_threshold, COLORS, class_name):
|
55 |
+
starting_time = time.time()
|
56 |
+
frame_counter = 0
|
57 |
+
total_frames = int(cap.get(cv.CAP_PROP_FRAME_COUNT))
|
58 |
+
remaining_time = datetime.timedelta(seconds=0)
|
59 |
+
remaining_time_container = st.empty()
|
60 |
+
video_frames = []
|
61 |
+
while True:
|
62 |
+
ret, frame = cap.read()
|
63 |
+
frame_counter += 1
|
64 |
+
if ret == False:
|
65 |
+
break
|
66 |
+
# Обнаружение объектов с использованием YOLOv4
|
67 |
+
classes, scores, boxes = model.detect(frame, Conf_threshold, NMS_threshold)
|
68 |
+
for (classid, score, box) in zip(classes, scores, boxes):
|
69 |
+
color = COLORS[int(classid) % len(COLORS)]
|
70 |
+
label = "%s : %f" % (class_name[classid], score)
|
71 |
+
cv.rectangle(frame, box, color, 1)
|
72 |
+
cv.putText(frame, label, (box[0], box[1]-10),
|
73 |
+
cv.FONT_HERSHEY_COMPLEX, 0.3, color, 1)
|
74 |
+
if app_mode == 'Видео':
|
75 |
+
endingTime = time.time() - starting_time
|
76 |
+
fps = frame_counter/endingTime
|
77 |
+
remaining_frames = total_frames - frame_counter
|
78 |
+
remaining_time = datetime.timedelta(seconds=int(remaining_frames / fps))
|
79 |
+
|
80 |
+
# Преобразование кадра в формат RGB для отображения в Streamlit
|
81 |
+
frame = cv.cvtColor(frame, cv.COLOR_BGR2RGB)
|
82 |
+
video_frames.append(frame.copy())
|
83 |
+
remaining_time_container.markdown('Оставшееся время выполнения: ' + str(remaining_time))
|
84 |
+
|
85 |
+
if stop:
|
86 |
+
break
|
87 |
+
return video_frames
|
88 |
+
|
89 |
+
def concotinate_video(video_frames, data):
|
90 |
+
cap = cv.VideoCapture(data)
|
91 |
+
# Считывание видео для получения FPS
|
92 |
+
fps_original = cap.get(cv.CAP_PROP_FPS)
|
93 |
+
total_frames_original = int(cap.get(cv.CAP_PROP_FRAME_COUNT))
|
94 |
+
# Создание функции для извлечения кадров из списка video_frames
|
95 |
+
def get_frame(t):
|
96 |
+
index = int(t * fps_original)
|
97 |
+
|
98 |
+
if index < total_frames_original:
|
99 |
+
return video_frames[index]
|
100 |
+
else:
|
101 |
+
return video_frames[-1]
|
102 |
+
# Считывание аудио для получения длительности
|
103 |
+
audio_clip = AudioFileClip(data)
|
104 |
+
st.markdown('Сборка видео')
|
105 |
+
video_clip = VideoClip(get_frame, duration=total_frames_original / fps_original)
|
106 |
+
video_clip = video_clip.set_audio(audio_clip)
|
107 |
+
output_file_path = 'processed_video.mp4'
|
108 |
+
video_clip.write_videofile(output_file_path, codec="libx264", audio_codec="aac", fps=fps_original)
|
109 |
+
|
110 |
+
return output_file_path
|
111 |
+
|
112 |
+
st.set_page_config(layout="wide", page_title="Детекция с YOLO v4")
|
113 |
+
st.title("Детекция с YOLO v4")
|
114 |
+
|
115 |
+
st.sidebar.title('Информация и выбор режима')
|
116 |
+
|
117 |
+
app_mode = st.sidebar.selectbox(
|
118 |
+
'Параметры',
|
119 |
+
['О сервисе', 'Изображение', 'Видео']
|
120 |
+
)
|
121 |
+
|
122 |
+
# About Page
|
123 |
+
if app_mode == 'О сервисе':
|
124 |
+
st.markdown('''Проект создан с использованием фреймворка Streamlit и библиотеки OpenCV, при этом в его основе лежит сверточная нейросеть YOLOv4.
|
125 |
+
Проект предоставляет демонстрацию возможностей данной нейросети.
|
126 |
+
#### YOLOv4 с обученными весами:
|
127 |
+
- Проект включает в себя готовую модель YOLOv4 с предварительно обученными весами. Эта модель способна обнаруживать объекты из 80 различных классов, что обеспечивает широкий спектр применения для определения различных объектов на изображениях.
|
128 |
+
|
129 |
+
#### Переобученная модель YOLOv4-tiny:
|
130 |
+
- Кроме того, представлена переобученная модель YOLOv4-tiny, которая была адаптирована для специфической задачи - определения наличия надетой каски на человеке. В ходе этого процесса были взяты веса базовой модели YOLOv4-tiny, проведена разметка данных и выполнено обучение на домашнем компьютере с использованием технологии CUDA от NVIDIA. Обучение велось по двум классам: "helmet" (каска) и "head" (голова).
|
131 |
+
|
132 |
+
Этот проект не только демонстрирует работу нейросети, но и подчеркивает его возможности в адаптации к конкретным задачам и обучению на собственных данных.
|
133 |
+
''')
|
134 |
+
with st.expander("Пример видео на выходе после обработки"):
|
135 |
+
st.video('processed_test1.mp4')
|
136 |
+
st.video('processed_test2.mp4')
|
137 |
+
|
138 |
+
# Image Page
|
139 |
+
elif app_mode == 'Изображение':
|
140 |
+
genre = st.sidebar.radio(
|
141 |
+
"Выбор модели",
|
142 |
+
["yolov4", "helmet"],
|
143 |
+
index=0,
|
144 |
+
)
|
145 |
+
if genre == 'yolov4':
|
146 |
+
names = 'coco.names'
|
147 |
+
weights = 'yolov4-tiny.weights'
|
148 |
+
config = 'yolov4-tiny-custom.cfg'
|
149 |
+
elif genre == 'helmet':
|
150 |
+
names = 'helmet.names'
|
151 |
+
weights = 'helmet_final.weights'
|
152 |
+
config = 'helmet.cfg'
|
153 |
+
|
154 |
+
st.sidebar.markdown('---')
|
155 |
+
|
156 |
+
st.markdown("#### Определение объектов на изображении")
|
157 |
+
|
158 |
+
st.sidebar.markdown('---')
|
159 |
+
detection_confidence = st.sidebar.slider('Порог уверенности', min_value=0.0, max_value=1.0, value=0.5)
|
160 |
+
with st.sidebar.expander("Назначение:"):
|
161 |
+
st.markdown('''Определяет, насколько уверенной должна быть модель в том, что объект обнаружен, прежде чем результат будет рассматриваться как положительный.
|
162 |
+
Если уверенность модели ниже этого порога, объект не будет считаться детектированным.
|
163 |
+
Обычно устанавливается в диапазоне 0.1-0.9 в зависимости от ваших требований к уверенности.
|
164 |
+
Более низкие значения приведут к более широкому набору детекций, но с большим числом ложных срабатываний.''')
|
165 |
+
tracking_confidence = st.sidebar.slider('Порог подавления', min_value=0.0, max_value=1.0, value=0.5)
|
166 |
+
with st.sidebar.expander("Назначение:"):
|
167 |
+
st.markdown('''Используется для подавления (фильтрации) дублирующих детекций.
|
168 |
+
Когда модель обнаруживает несколько прямоугольных областей, перекрывающихся с высокой уверенностью, порог подавления помогает выбрать только одну из них.
|
169 |
+
Это предотвращает появление множественных детекций для одного и того же объекта.
|
170 |
+
Обычно устанавливается в диапазоне 0.1-0.5.
|
171 |
+
Более высокие значения делают алгоритм более консервативным, выбирая более уверенные детекции, но при этом может пропустить менее уверенные детекции.''')
|
172 |
+
st.sidebar.markdown('---')
|
173 |
+
|
174 |
+
img_file_buffer = st.sidebar.file_uploader("Загрузите изображение", type=["jpg", "jpeg", "png"])
|
175 |
+
|
176 |
+
|
177 |
+
st.sidebar.text('Исходное изображение')
|
178 |
+
if img_file_buffer:
|
179 |
+
st.sidebar.image(img_file_buffer)
|
180 |
+
if img_file_buffer:
|
181 |
+
start = st.button("Запуск обработки", type="primary")
|
182 |
+
stframe = st.empty()
|
183 |
+
if start:
|
184 |
+
model, COLORS, class_name = yolov4(names, weights, config, detection_confidence, tracking_confidence)
|
185 |
+
cap, temp_file_path = temp_file(img_file_buffer)
|
186 |
+
frame = image_process(model, cap, detection_confidence, tracking_confidence, COLORS, class_name)
|
187 |
+
stframe.image(frame,channels='BGR', use_column_width="auto")
|
188 |
+
# Video Page
|
189 |
+
elif app_mode == 'Видео':
|
190 |
+
st.set_option('deprecation.showfileUploaderEncoding', False)
|
191 |
+
|
192 |
+
genre = st.sidebar.radio(
|
193 |
+
"Выбор модели",
|
194 |
+
["yolov4", "helmet"],
|
195 |
+
index=0,
|
196 |
+
)
|
197 |
+
|
198 |
+
if genre == 'yolov4':
|
199 |
+
names = 'coco.names'
|
200 |
+
weights = 'yolov4-tiny.weights'
|
201 |
+
config = 'yolov4-tiny-custom.cfg'
|
202 |
+
elif genre == 'helmet':
|
203 |
+
names = 'helmet.names'
|
204 |
+
weights = 'helmet_final.weights'
|
205 |
+
config = 'helmet.cfg'
|
206 |
+
|
207 |
+
st.sidebar.markdown('---')
|
208 |
+
detection_confidence = st.sidebar.slider('Порог уверенности', min_value=0.0, max_value=1.0, value=0.5)
|
209 |
+
with st.sidebar.expander("Назначение:"):
|
210 |
+
st.markdown('''Определяет, насколько уверенной должна быть модель в том, что объект обнаружен, прежде чем результат будет рассматриваться как положительный.
|
211 |
+
Если уверенность модели ниже этого порога, объект не будет считаться детектированным.
|
212 |
+
Обычно устанавливается в диапазоне 0.1-0.9 в зависимости от ваших требований к уверенности.
|
213 |
+
Более низкие значения приведут к более широкому набору детекций, но с большим числом ложных срабатываний.''')
|
214 |
+
tracking_confidence = st.sidebar.slider('Порог подавления', min_value=0.0, max_value=1.0, value=0.5)
|
215 |
+
with st.sidebar.expander("Назначение:"):
|
216 |
+
st.markdown('''Используется для подавления (фильтрации) дублирующих детекций.
|
217 |
+
Когда модель обнаруживает несколько прямоугольных областей, перекрывающихся с высокой уверенностью, порог подавления помогает выбрать только одну из них.
|
218 |
+
Это предотвращает появление множественных детекций для одного и того же объекта.
|
219 |
+
Обычно устанавливается в диапазоне 0.1-0.5.
|
220 |
+
Более высокие значения делают алгоритм более консервативным, выбирая более уверенные детекции, но при этом может пропустить менее уверенные детекции.''')
|
221 |
+
st.sidebar.markdown('---')
|
222 |
+
|
223 |
+
## Get Video
|
224 |
+
|
225 |
+
video_file_buffer = st.sidebar.file_uploader("Загрузите видео", type=['mp4', 'mov', 'avi', 'asf', 'm4v'])
|
226 |
+
|
227 |
+
st.sidebar.text('Исходное видео')
|
228 |
+
if video_file_buffer:
|
229 |
+
st.sidebar.video(video_file_buffer)
|
230 |
+
|
231 |
+
st.markdown("#### Определение объектов на видео")
|
232 |
+
|
233 |
+
if video_file_buffer:
|
234 |
+
start = st.button("Запуск обработки", type="primary")
|
235 |
+
stop = st.button("Остановка обработки")
|
236 |
+
stframe = st.empty()
|
237 |
+
if start:
|
238 |
+
model, COLORS, class_name = yolov4(names, weights, config, detection_confidence, tracking_confidence)
|
239 |
+
cap, temp_file_path = temp_file(video_file_buffer)
|
240 |
+
video_frames = video_process(model, cap, detection_confidence, tracking_confidence, COLORS, class_name)
|
241 |
+
output_file_path = concotinate_video(video_frames, temp_file_path)
|
242 |
+
st.markdown('### Обработанное видео')
|
243 |
+
st.video(output_file_path)
|
244 |
+
|
245 |
+
|
helmet.cfg
ADDED
@@ -0,0 +1,281 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
[net]
|
2 |
+
# Testing
|
3 |
+
#batch=1
|
4 |
+
#subdivisions=1
|
5 |
+
# Training
|
6 |
+
batch=64
|
7 |
+
subdivisions=16
|
8 |
+
width=416
|
9 |
+
height=416
|
10 |
+
channels=3
|
11 |
+
momentum=0.9
|
12 |
+
decay=0.0005
|
13 |
+
angle=0
|
14 |
+
saturation = 1.5
|
15 |
+
exposure = 1.5
|
16 |
+
hue=.1
|
17 |
+
|
18 |
+
learning_rate=0.00261
|
19 |
+
burn_in=1000
|
20 |
+
max_batches = 6000
|
21 |
+
policy=steps
|
22 |
+
steps=4800,5400
|
23 |
+
scales=.1,.1
|
24 |
+
|
25 |
+
[convolutional]
|
26 |
+
batch_normalize=1
|
27 |
+
filters=32
|
28 |
+
size=3
|
29 |
+
stride=2
|
30 |
+
pad=1
|
31 |
+
activation=leaky
|
32 |
+
|
33 |
+
[convolutional]
|
34 |
+
batch_normalize=1
|
35 |
+
filters=64
|
36 |
+
size=3
|
37 |
+
stride=2
|
38 |
+
pad=1
|
39 |
+
activation=leaky
|
40 |
+
|
41 |
+
[convolutional]
|
42 |
+
batch_normalize=1
|
43 |
+
filters=64
|
44 |
+
size=3
|
45 |
+
stride=1
|
46 |
+
pad=1
|
47 |
+
activation=leaky
|
48 |
+
|
49 |
+
[route]
|
50 |
+
layers=-1
|
51 |
+
groups=2
|
52 |
+
group_id=1
|
53 |
+
|
54 |
+
[convolutional]
|
55 |
+
batch_normalize=1
|
56 |
+
filters=32
|
57 |
+
size=3
|
58 |
+
stride=1
|
59 |
+
pad=1
|
60 |
+
activation=leaky
|
61 |
+
|
62 |
+
[convolutional]
|
63 |
+
batch_normalize=1
|
64 |
+
filters=32
|
65 |
+
size=3
|
66 |
+
stride=1
|
67 |
+
pad=1
|
68 |
+
activation=leaky
|
69 |
+
|
70 |
+
[route]
|
71 |
+
layers = -1,-2
|
72 |
+
|
73 |
+
[convolutional]
|
74 |
+
batch_normalize=1
|
75 |
+
filters=64
|
76 |
+
size=1
|
77 |
+
stride=1
|
78 |
+
pad=1
|
79 |
+
activation=leaky
|
80 |
+
|
81 |
+
[route]
|
82 |
+
layers = -6,-1
|
83 |
+
|
84 |
+
[maxpool]
|
85 |
+
size=2
|
86 |
+
stride=2
|
87 |
+
|
88 |
+
[convolutional]
|
89 |
+
batch_normalize=1
|
90 |
+
filters=128
|
91 |
+
size=3
|
92 |
+
stride=1
|
93 |
+
pad=1
|
94 |
+
activation=leaky
|
95 |
+
|
96 |
+
[route]
|
97 |
+
layers=-1
|
98 |
+
groups=2
|
99 |
+
group_id=1
|
100 |
+
|
101 |
+
[convolutional]
|
102 |
+
batch_normalize=1
|
103 |
+
filters=64
|
104 |
+
size=3
|
105 |
+
stride=1
|
106 |
+
pad=1
|
107 |
+
activation=leaky
|
108 |
+
|
109 |
+
[convolutional]
|
110 |
+
batch_normalize=1
|
111 |
+
filters=64
|
112 |
+
size=3
|
113 |
+
stride=1
|
114 |
+
pad=1
|
115 |
+
activation=leaky
|
116 |
+
|
117 |
+
[route]
|
118 |
+
layers = -1,-2
|
119 |
+
|
120 |
+
[convolutional]
|
121 |
+
batch_normalize=1
|
122 |
+
filters=128
|
123 |
+
size=1
|
124 |
+
stride=1
|
125 |
+
pad=1
|
126 |
+
activation=leaky
|
127 |
+
|
128 |
+
[route]
|
129 |
+
layers = -6,-1
|
130 |
+
|
131 |
+
[maxpool]
|
132 |
+
size=2
|
133 |
+
stride=2
|
134 |
+
|
135 |
+
[convolutional]
|
136 |
+
batch_normalize=1
|
137 |
+
filters=256
|
138 |
+
size=3
|
139 |
+
stride=1
|
140 |
+
pad=1
|
141 |
+
activation=leaky
|
142 |
+
|
143 |
+
[route]
|
144 |
+
layers=-1
|
145 |
+
groups=2
|
146 |
+
group_id=1
|
147 |
+
|
148 |
+
[convolutional]
|
149 |
+
batch_normalize=1
|
150 |
+
filters=128
|
151 |
+
size=3
|
152 |
+
stride=1
|
153 |
+
pad=1
|
154 |
+
activation=leaky
|
155 |
+
|
156 |
+
[convolutional]
|
157 |
+
batch_normalize=1
|
158 |
+
filters=128
|
159 |
+
size=3
|
160 |
+
stride=1
|
161 |
+
pad=1
|
162 |
+
activation=leaky
|
163 |
+
|
164 |
+
[route]
|
165 |
+
layers = -1,-2
|
166 |
+
|
167 |
+
[convolutional]
|
168 |
+
batch_normalize=1
|
169 |
+
filters=256
|
170 |
+
size=1
|
171 |
+
stride=1
|
172 |
+
pad=1
|
173 |
+
activation=leaky
|
174 |
+
|
175 |
+
[route]
|
176 |
+
layers = -6,-1
|
177 |
+
|
178 |
+
[maxpool]
|
179 |
+
size=2
|
180 |
+
stride=2
|
181 |
+
|
182 |
+
[convolutional]
|
183 |
+
batch_normalize=1
|
184 |
+
filters=512
|
185 |
+
size=3
|
186 |
+
stride=1
|
187 |
+
pad=1
|
188 |
+
activation=leaky
|
189 |
+
|
190 |
+
##################################
|
191 |
+
|
192 |
+
[convolutional]
|
193 |
+
batch_normalize=1
|
194 |
+
filters=256
|
195 |
+
size=1
|
196 |
+
stride=1
|
197 |
+
pad=1
|
198 |
+
activation=leaky
|
199 |
+
|
200 |
+
[convolutional]
|
201 |
+
batch_normalize=1
|
202 |
+
filters=512
|
203 |
+
size=3
|
204 |
+
stride=1
|
205 |
+
pad=1
|
206 |
+
activation=leaky
|
207 |
+
|
208 |
+
[convolutional]
|
209 |
+
size=1
|
210 |
+
stride=1
|
211 |
+
pad=1
|
212 |
+
filters=24
|
213 |
+
activation=linear
|
214 |
+
|
215 |
+
|
216 |
+
|
217 |
+
[yolo]
|
218 |
+
mask = 3,4,5
|
219 |
+
anchors = 15, 17, 26, 28, 37, 46, 62, 60, 84, 96, 133,151
|
220 |
+
classes=3
|
221 |
+
num=6
|
222 |
+
jitter=.3
|
223 |
+
scale_x_y = 1.05
|
224 |
+
cls_normalizer=1.0
|
225 |
+
iou_normalizer=0.07
|
226 |
+
iou_loss=ciou
|
227 |
+
ignore_thresh = .7
|
228 |
+
truth_thresh = 1
|
229 |
+
random=0
|
230 |
+
resize=1.5
|
231 |
+
nms_kind=greedynms
|
232 |
+
beta_nms=0.6
|
233 |
+
|
234 |
+
[route]
|
235 |
+
layers = -4
|
236 |
+
|
237 |
+
[convolutional]
|
238 |
+
batch_normalize=1
|
239 |
+
filters=128
|
240 |
+
size=1
|
241 |
+
stride=1
|
242 |
+
pad=1
|
243 |
+
activation=leaky
|
244 |
+
|
245 |
+
[upsample]
|
246 |
+
stride=2
|
247 |
+
|
248 |
+
[route]
|
249 |
+
layers = -1, 23
|
250 |
+
|
251 |
+
[convolutional]
|
252 |
+
batch_normalize=1
|
253 |
+
filters=256
|
254 |
+
size=3
|
255 |
+
stride=1
|
256 |
+
pad=1
|
257 |
+
activation=leaky
|
258 |
+
|
259 |
+
[convolutional]
|
260 |
+
size=1
|
261 |
+
stride=1
|
262 |
+
pad=1
|
263 |
+
filters=24
|
264 |
+
activation=linear
|
265 |
+
|
266 |
+
[yolo]
|
267 |
+
mask = 0,1,2
|
268 |
+
anchors = 15, 17, 26, 28, 37, 46, 62, 60, 84, 96, 133,151
|
269 |
+
classes=3
|
270 |
+
num=6
|
271 |
+
jitter=.3
|
272 |
+
scale_x_y = 1.05
|
273 |
+
cls_normalizer=1.0
|
274 |
+
iou_normalizer=0.07
|
275 |
+
iou_loss=ciou
|
276 |
+
ignore_thresh = .7
|
277 |
+
truth_thresh = 1
|
278 |
+
random=0
|
279 |
+
resize=1.5
|
280 |
+
nms_kind=greedynms
|
281 |
+
beta_nms=0.6
|
helmet.names
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
helmet
|
2 |
+
person
|
3 |
+
head
|
requirements.txt
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
streamlit==1.28.0
|
2 |
+
opencv-python-headless==4.8.1.78
|
3 |
+
moviepy
|
yolov4-tiny-custom.cfg
ADDED
@@ -0,0 +1,281 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
[net]
|
2 |
+
# Testing
|
3 |
+
#batch=1
|
4 |
+
#subdivisions=1
|
5 |
+
# Training
|
6 |
+
batch=64
|
7 |
+
subdivisions=1
|
8 |
+
width=416
|
9 |
+
height=416
|
10 |
+
channels=3
|
11 |
+
momentum=0.9
|
12 |
+
decay=0.0005
|
13 |
+
angle=0
|
14 |
+
saturation = 1.5
|
15 |
+
exposure = 1.5
|
16 |
+
hue=.1
|
17 |
+
|
18 |
+
learning_rate=0.00261
|
19 |
+
burn_in=1000
|
20 |
+
max_batches = 500200
|
21 |
+
policy=steps
|
22 |
+
steps=400000,450000
|
23 |
+
scales=.1,.1
|
24 |
+
|
25 |
+
[convolutional]
|
26 |
+
batch_normalize=1
|
27 |
+
filters=32
|
28 |
+
size=3
|
29 |
+
stride=2
|
30 |
+
pad=1
|
31 |
+
activation=leaky
|
32 |
+
|
33 |
+
[convolutional]
|
34 |
+
batch_normalize=1
|
35 |
+
filters=64
|
36 |
+
size=3
|
37 |
+
stride=2
|
38 |
+
pad=1
|
39 |
+
activation=leaky
|
40 |
+
|
41 |
+
[convolutional]
|
42 |
+
batch_normalize=1
|
43 |
+
filters=64
|
44 |
+
size=3
|
45 |
+
stride=1
|
46 |
+
pad=1
|
47 |
+
activation=leaky
|
48 |
+
|
49 |
+
[route]
|
50 |
+
layers=-1
|
51 |
+
groups=2
|
52 |
+
group_id=1
|
53 |
+
|
54 |
+
[convolutional]
|
55 |
+
batch_normalize=1
|
56 |
+
filters=32
|
57 |
+
size=3
|
58 |
+
stride=1
|
59 |
+
pad=1
|
60 |
+
activation=leaky
|
61 |
+
|
62 |
+
[convolutional]
|
63 |
+
batch_normalize=1
|
64 |
+
filters=32
|
65 |
+
size=3
|
66 |
+
stride=1
|
67 |
+
pad=1
|
68 |
+
activation=leaky
|
69 |
+
|
70 |
+
[route]
|
71 |
+
layers = -1,-2
|
72 |
+
|
73 |
+
[convolutional]
|
74 |
+
batch_normalize=1
|
75 |
+
filters=64
|
76 |
+
size=1
|
77 |
+
stride=1
|
78 |
+
pad=1
|
79 |
+
activation=leaky
|
80 |
+
|
81 |
+
[route]
|
82 |
+
layers = -6,-1
|
83 |
+
|
84 |
+
[maxpool]
|
85 |
+
size=2
|
86 |
+
stride=2
|
87 |
+
|
88 |
+
[convolutional]
|
89 |
+
batch_normalize=1
|
90 |
+
filters=128
|
91 |
+
size=3
|
92 |
+
stride=1
|
93 |
+
pad=1
|
94 |
+
activation=leaky
|
95 |
+
|
96 |
+
[route]
|
97 |
+
layers=-1
|
98 |
+
groups=2
|
99 |
+
group_id=1
|
100 |
+
|
101 |
+
[convolutional]
|
102 |
+
batch_normalize=1
|
103 |
+
filters=64
|
104 |
+
size=3
|
105 |
+
stride=1
|
106 |
+
pad=1
|
107 |
+
activation=leaky
|
108 |
+
|
109 |
+
[convolutional]
|
110 |
+
batch_normalize=1
|
111 |
+
filters=64
|
112 |
+
size=3
|
113 |
+
stride=1
|
114 |
+
pad=1
|
115 |
+
activation=leaky
|
116 |
+
|
117 |
+
[route]
|
118 |
+
layers = -1,-2
|
119 |
+
|
120 |
+
[convolutional]
|
121 |
+
batch_normalize=1
|
122 |
+
filters=128
|
123 |
+
size=1
|
124 |
+
stride=1
|
125 |
+
pad=1
|
126 |
+
activation=leaky
|
127 |
+
|
128 |
+
[route]
|
129 |
+
layers = -6,-1
|
130 |
+
|
131 |
+
[maxpool]
|
132 |
+
size=2
|
133 |
+
stride=2
|
134 |
+
|
135 |
+
[convolutional]
|
136 |
+
batch_normalize=1
|
137 |
+
filters=256
|
138 |
+
size=3
|
139 |
+
stride=1
|
140 |
+
pad=1
|
141 |
+
activation=leaky
|
142 |
+
|
143 |
+
[route]
|
144 |
+
layers=-1
|
145 |
+
groups=2
|
146 |
+
group_id=1
|
147 |
+
|
148 |
+
[convolutional]
|
149 |
+
batch_normalize=1
|
150 |
+
filters=128
|
151 |
+
size=3
|
152 |
+
stride=1
|
153 |
+
pad=1
|
154 |
+
activation=leaky
|
155 |
+
|
156 |
+
[convolutional]
|
157 |
+
batch_normalize=1
|
158 |
+
filters=128
|
159 |
+
size=3
|
160 |
+
stride=1
|
161 |
+
pad=1
|
162 |
+
activation=leaky
|
163 |
+
|
164 |
+
[route]
|
165 |
+
layers = -1,-2
|
166 |
+
|
167 |
+
[convolutional]
|
168 |
+
batch_normalize=1
|
169 |
+
filters=256
|
170 |
+
size=1
|
171 |
+
stride=1
|
172 |
+
pad=1
|
173 |
+
activation=leaky
|
174 |
+
|
175 |
+
[route]
|
176 |
+
layers = -6,-1
|
177 |
+
|
178 |
+
[maxpool]
|
179 |
+
size=2
|
180 |
+
stride=2
|
181 |
+
|
182 |
+
[convolutional]
|
183 |
+
batch_normalize=1
|
184 |
+
filters=512
|
185 |
+
size=3
|
186 |
+
stride=1
|
187 |
+
pad=1
|
188 |
+
activation=leaky
|
189 |
+
|
190 |
+
##################################
|
191 |
+
|
192 |
+
[convolutional]
|
193 |
+
batch_normalize=1
|
194 |
+
filters=256
|
195 |
+
size=1
|
196 |
+
stride=1
|
197 |
+
pad=1
|
198 |
+
activation=leaky
|
199 |
+
|
200 |
+
[convolutional]
|
201 |
+
batch_normalize=1
|
202 |
+
filters=512
|
203 |
+
size=3
|
204 |
+
stride=1
|
205 |
+
pad=1
|
206 |
+
activation=leaky
|
207 |
+
|
208 |
+
[convolutional]
|
209 |
+
size=1
|
210 |
+
stride=1
|
211 |
+
pad=1
|
212 |
+
filters=255
|
213 |
+
activation=linear
|
214 |
+
|
215 |
+
|
216 |
+
|
217 |
+
[yolo]
|
218 |
+
mask = 3,4,5
|
219 |
+
anchors = 10,14, 23,27, 37,58, 81,82, 135,169, 344,319
|
220 |
+
classes=80
|
221 |
+
num=6
|
222 |
+
jitter=.3
|
223 |
+
scale_x_y = 1.05
|
224 |
+
cls_normalizer=1.0
|
225 |
+
iou_normalizer=0.07
|
226 |
+
iou_loss=ciou
|
227 |
+
ignore_thresh = .7
|
228 |
+
truth_thresh = 1
|
229 |
+
random=0
|
230 |
+
resize=1.5
|
231 |
+
nms_kind=greedynms
|
232 |
+
beta_nms=0.6
|
233 |
+
|
234 |
+
[route]
|
235 |
+
layers = -4
|
236 |
+
|
237 |
+
[convolutional]
|
238 |
+
batch_normalize=1
|
239 |
+
filters=128
|
240 |
+
size=1
|
241 |
+
stride=1
|
242 |
+
pad=1
|
243 |
+
activation=leaky
|
244 |
+
|
245 |
+
[upsample]
|
246 |
+
stride=2
|
247 |
+
|
248 |
+
[route]
|
249 |
+
layers = -1, 23
|
250 |
+
|
251 |
+
[convolutional]
|
252 |
+
batch_normalize=1
|
253 |
+
filters=256
|
254 |
+
size=3
|
255 |
+
stride=1
|
256 |
+
pad=1
|
257 |
+
activation=leaky
|
258 |
+
|
259 |
+
[convolutional]
|
260 |
+
size=1
|
261 |
+
stride=1
|
262 |
+
pad=1
|
263 |
+
filters=255
|
264 |
+
activation=linear
|
265 |
+
|
266 |
+
[yolo]
|
267 |
+
mask = 0,1,2
|
268 |
+
anchors = 10,14, 23,27, 37,58, 81,82, 135,169, 344,319
|
269 |
+
classes=80
|
270 |
+
num=6
|
271 |
+
jitter=.3
|
272 |
+
scale_x_y = 1.05
|
273 |
+
cls_normalizer=1.0
|
274 |
+
iou_normalizer=0.07
|
275 |
+
iou_loss=ciou
|
276 |
+
ignore_thresh = .7
|
277 |
+
truth_thresh = 1
|
278 |
+
random=0
|
279 |
+
resize=1.5
|
280 |
+
nms_kind=greedynms
|
281 |
+
beta_nms=0.6
|