Spaces:
Sleeping
Sleeping
EL GHAFRAOUI AYOUB
commited on
Commit
·
0135475
1
Parent(s):
2ccbdec
This view is limited to 50 files because it contains too many changes.
See raw diff
- .gitignore +1 -0
- MANIFEST.in +8 -0
- app.py +337 -0
- bisindo.pt +3 -0
- bisindov2.pt +3 -0
- camera_settings.py +53 -0
- img/confusion_matrix.png +0 -0
- img/results.png +0 -0
- requirements.txt +0 -0
- setup.cfg +56 -0
- setup.py +65 -0
- static/script.js +194 -0
- static/style.css +217 -0
- templates/hompage copy.html +65 -0
- templates/hompage.html +80 -0
- templates/index copy.html +72 -0
- templates/index.html +120 -0
- templates/indexv1.html +112 -0
- tests/test_cli.py +81 -0
- tests/test_engine.py +93 -0
- tests/test_python.py +222 -0
- train/result/F1_curve.png +0 -0
- train/result/PR_curve.png +0 -0
- train/result/P_curve.png +0 -0
- train/result/R_curve.png +0 -0
- train/result/best.pt +3 -0
- train/result/confusion_matrix.png +0 -0
- train/result/events.out.tfevents.1703117386.69c6eee73c8d.3549.0 +3 -0
- train/result/results.csv +51 -0
- train/result/results.png +0 -0
- train/result/train_batch0.jpg +0 -0
- train/result/train_batch1.jpg +0 -0
- train/result/train_batch2.jpg +0 -0
- train/result/train_batch6680.jpg +0 -0
- train/result/train_batch6681.jpg +0 -0
- train/result/train_batch6682.jpg +0 -0
- train/result/val_batch0_labels.jpg +0 -0
- train/result/val_batch0_pred.jpg +0 -0
- train/result/val_batch1_labels.jpg +0 -0
- train/result/val_batch1_pred.jpg +0 -0
- train/result/val_batch2_labels.jpg +0 -0
- train/result/val_batch2_pred.jpg +0 -0
- train/train_model.ipynb +928 -0
- ultralytics/__init__.py +9 -0
- ultralytics/__pycache__/__init__.cpython-310.pyc +0 -0
- ultralytics/__pycache__/__init__.cpython-311.pyc +0 -0
- ultralytics/abc +1 -0
- ultralytics/assets/bus.jpg +0 -0
- ultralytics/assets/zidane.jpg +0 -0
- ultralytics/datasets/Argoverse.yaml +73 -0
.gitignore
ADDED
@@ -0,0 +1 @@
|
|
|
|
|
1 |
+
.vercel
|
MANIFEST.in
ADDED
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
include *.md
|
2 |
+
include requirements.txt
|
3 |
+
include LICENSE
|
4 |
+
include setup.py
|
5 |
+
include ultralytics/assets/bus.jpg
|
6 |
+
include ultralytics/assets/zidane.jpg
|
7 |
+
recursive-include ultralytics *.yaml
|
8 |
+
recursive-exclude __pycache__ *
|
app.py
ADDED
@@ -0,0 +1,337 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from ultralytics import YOLO
|
2 |
+
import time
|
3 |
+
import numpy as np
|
4 |
+
import mediapipe as mp
|
5 |
+
|
6 |
+
|
7 |
+
import cv2
|
8 |
+
from flask import Flask, render_template, request, Response, session, redirect, url_for
|
9 |
+
|
10 |
+
from flask_socketio import SocketIO
|
11 |
+
import yt_dlp as youtube_dl
|
12 |
+
|
13 |
+
|
14 |
+
model_object_detection = YOLO("bisindov2.pt")
|
15 |
+
|
16 |
+
app = Flask(__name__)
|
17 |
+
|
18 |
+
app.config['SECRET_KEY'] = 'secret!'
|
19 |
+
socketio = SocketIO(app, async_mode='threading')
|
20 |
+
stop_flag = False
|
21 |
+
|
22 |
+
|
23 |
+
######################################################
|
24 |
+
classes_translation = {
|
25 |
+
"all": "الكل",
|
26 |
+
"A": "أ",
|
27 |
+
"B": "ب",
|
28 |
+
"C": "ج",
|
29 |
+
"D": "د",
|
30 |
+
"F": "ف",
|
31 |
+
"H": "هـ",
|
32 |
+
"I": "أنا",
|
33 |
+
"J": "جيم",
|
34 |
+
"L": "إل",
|
35 |
+
"M": "إم",
|
36 |
+
"O": "أو",
|
37 |
+
"R": "ر",
|
38 |
+
"T": "ت",
|
39 |
+
"U": "يو",
|
40 |
+
"V": "في",
|
41 |
+
"W": "دبليو",
|
42 |
+
"Z": "زد",
|
43 |
+
"additional": "إضافي",
|
44 |
+
"alcohol": "مدرسة",
|
45 |
+
"allergy": "حساسية",
|
46 |
+
"bacon": "لحم المقدد",
|
47 |
+
"bag": "حقيبة",
|
48 |
+
"barbecue": "شواء",
|
49 |
+
"bill": "فاتورة",
|
50 |
+
"biscuit": "بسكويت",
|
51 |
+
"bitter": "مر",
|
52 |
+
"bread": "خبز",
|
53 |
+
"burger": "برغر",
|
54 |
+
"bye": "وداعاً",
|
55 |
+
"cheese": "جبن",
|
56 |
+
"chicken": "دجاج",
|
57 |
+
"coke": "كوكاكولا",
|
58 |
+
"cold": "بارد",
|
59 |
+
"cost": "تكلفة",
|
60 |
+
"coupon": "كوبون",
|
61 |
+
"cup": "كوب",
|
62 |
+
"dessert": "حلوى",
|
63 |
+
"drink": "شراب",
|
64 |
+
"drive": "قيادة",
|
65 |
+
"eat": "تناول الطعام",
|
66 |
+
"eggs": "بيض",
|
67 |
+
"enjoy": "استمتع",
|
68 |
+
"fork": "شوكة",
|
69 |
+
"french fries": "بطاطس مقلية",
|
70 |
+
"fresh": "طازج",
|
71 |
+
"hello": "مرحبا",
|
72 |
+
"hot": "ساخن",
|
73 |
+
"icecream": "آيس كريم",
|
74 |
+
"ingredients": "مكونات",
|
75 |
+
"juicy": "عصيري",
|
76 |
+
"ketchup": "كاتشب",
|
77 |
+
"lactose": "لاكتوز",
|
78 |
+
"lettuce": "خس",
|
79 |
+
"lid": "غطاء",
|
80 |
+
"manager": "مدير",
|
81 |
+
"menu": "قائمة الطعام",
|
82 |
+
"milk": "حليب",
|
83 |
+
"mustard": "خردل",
|
84 |
+
"napkin": "منديل",
|
85 |
+
"no": "لا",
|
86 |
+
"order": "طلب",
|
87 |
+
"pepper": "فلفل",
|
88 |
+
"pickle": "مخلل",
|
89 |
+
"pizza": "بيتزا",
|
90 |
+
"please": "من فضلك",
|
91 |
+
"ready": "جاهز",
|
92 |
+
"refill": "إعادة ملء",
|
93 |
+
"repeat": "كرر",
|
94 |
+
"safe": "آمن",
|
95 |
+
"salt": "ملح",
|
96 |
+
"sandwich": "ساندويتش",
|
97 |
+
"sauce": "صلصة",
|
98 |
+
"small": "صغير",
|
99 |
+
"soda": "صودا",
|
100 |
+
"sorry": "آسف",
|
101 |
+
"spicy": "حار",
|
102 |
+
"spoon": "ملعقة",
|
103 |
+
"straw": "قش",
|
104 |
+
"sugar": "سكر",
|
105 |
+
"sweet": "حلو",
|
106 |
+
"tissues": "مناديل",
|
107 |
+
"total": "مجموع",
|
108 |
+
"urgent": "عاجل",
|
109 |
+
"vegetables": "خضروات",
|
110 |
+
"warm": "دافئ",
|
111 |
+
"water": "ماء",
|
112 |
+
"what": "ماذا",
|
113 |
+
"yoghurt": "زبادي",
|
114 |
+
"your": "لك",
|
115 |
+
"ILoveYou":"أحبك",
|
116 |
+
"Halo":"مرحبًا"
|
117 |
+
}
|
118 |
+
######################################################
|
119 |
+
class VideoStreaming(object):
|
120 |
+
def __init__(self):
|
121 |
+
super(VideoStreaming, self).__init__()
|
122 |
+
print ("===== Video Streaming =====")
|
123 |
+
self._preview = False
|
124 |
+
self._flipH = False
|
125 |
+
self._detect = False
|
126 |
+
self._model = False
|
127 |
+
self._mediaPipe = False
|
128 |
+
self._confidence = 75.0
|
129 |
+
self.mp_hands = mp.solutions.hands
|
130 |
+
self.hands = self.mp_hands.Hands()
|
131 |
+
|
132 |
+
@property
|
133 |
+
def confidence(self):
|
134 |
+
return self._confidence
|
135 |
+
|
136 |
+
@confidence.setter
|
137 |
+
def confidence(self, value):
|
138 |
+
self._confidence = int(value)
|
139 |
+
|
140 |
+
@property
|
141 |
+
def preview(self):
|
142 |
+
return self._preview
|
143 |
+
|
144 |
+
@preview.setter
|
145 |
+
def preview(self, value):
|
146 |
+
self._preview = bool(value)
|
147 |
+
|
148 |
+
@property
|
149 |
+
def flipH(self):
|
150 |
+
return self._flipH
|
151 |
+
|
152 |
+
@flipH.setter
|
153 |
+
def flipH(self, value):
|
154 |
+
self._flipH = bool(value)
|
155 |
+
|
156 |
+
@property
|
157 |
+
def detect(self):
|
158 |
+
return self._detect
|
159 |
+
|
160 |
+
@detect.setter
|
161 |
+
def detect(self, value):
|
162 |
+
self._detect = bool(value)
|
163 |
+
|
164 |
+
@property
|
165 |
+
def mediaPipe(self):
|
166 |
+
return self._mediaPipe
|
167 |
+
|
168 |
+
@mediaPipe.setter
|
169 |
+
def mediaPipe(self, value):
|
170 |
+
self._mediaPipe = bool(value)
|
171 |
+
|
172 |
+
def show(self, url):
|
173 |
+
print(url)
|
174 |
+
self._preview = False
|
175 |
+
self._flipH = False
|
176 |
+
self._detect = False
|
177 |
+
self._mediaPipe = False
|
178 |
+
|
179 |
+
self._confidence = 75.0
|
180 |
+
ydl_opts = {
|
181 |
+
"quiet": True,
|
182 |
+
"no_warnings": True,
|
183 |
+
"format": "best",
|
184 |
+
"forceurl": True,
|
185 |
+
}
|
186 |
+
|
187 |
+
if url == '0':
|
188 |
+
cap = cv2.VideoCapture(0)
|
189 |
+
else:
|
190 |
+
|
191 |
+
ydl = youtube_dl.YoutubeDL(ydl_opts)
|
192 |
+
|
193 |
+
info = ydl.extract_info(url, download=False)
|
194 |
+
url = info["url"]
|
195 |
+
|
196 |
+
cap = cv2.VideoCapture(url)
|
197 |
+
|
198 |
+
while True:
|
199 |
+
if self._preview:
|
200 |
+
if stop_flag:
|
201 |
+
print("Process Stopped")
|
202 |
+
return
|
203 |
+
|
204 |
+
grabbed, frame = cap.read()
|
205 |
+
if not grabbed:
|
206 |
+
break
|
207 |
+
if self.flipH:
|
208 |
+
frame = cv2.flip(frame, 1)
|
209 |
+
|
210 |
+
if self.detect:
|
211 |
+
frame_yolo = frame.copy()
|
212 |
+
results_yolo = model_object_detection.predict(frame_yolo, conf=self._confidence / 100)
|
213 |
+
|
214 |
+
frame_yolo, labels = results_yolo[0].plot()
|
215 |
+
list_labels = []
|
216 |
+
# labels_confidences
|
217 |
+
|
218 |
+
for label in labels:
|
219 |
+
confidence = label.split(" ")[-1]
|
220 |
+
label_name = " ".join(label.split(" ")[:-1])
|
221 |
+
# Translate the label if it exists in the translation dictionary
|
222 |
+
translated_label = classes_translation.get(label_name, label_name)
|
223 |
+
list_labels.append(translated_label)
|
224 |
+
list_labels.append(confidence)
|
225 |
+
socketio.emit('label', list_labels)
|
226 |
+
|
227 |
+
if self.mediaPipe:
|
228 |
+
# Convert the image to RGB for processing with MediaPipe
|
229 |
+
image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
|
230 |
+
results = self.hands.process(image)
|
231 |
+
|
232 |
+
if results.multi_hand_landmarks:
|
233 |
+
for hand_landmarks in results.multi_hand_landmarks:
|
234 |
+
mp.solutions.drawing_utils.draw_landmarks(
|
235 |
+
frame,
|
236 |
+
hand_landmarks,
|
237 |
+
self.mp_hands.HAND_CONNECTIONS,
|
238 |
+
landmark_drawing_spec=mp.solutions.drawing_utils.DrawingSpec(color=(255, 0, 0), thickness=4, circle_radius=3),
|
239 |
+
connection_drawing_spec=mp.solutions.drawing_utils.DrawingSpec(color=(255, 255, 255), thickness=2, circle_radius=2),
|
240 |
+
)
|
241 |
+
|
242 |
+
frame = cv2.imencode(".jpg", frame)[1].tobytes()
|
243 |
+
yield (
|
244 |
+
b'--frame\r\n'
|
245 |
+
b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n'
|
246 |
+
)
|
247 |
+
else:
|
248 |
+
snap = np.zeros((
|
249 |
+
1000,
|
250 |
+
1000
|
251 |
+
), np.uint8)
|
252 |
+
label = "Streaming Off"
|
253 |
+
H, W = snap.shape
|
254 |
+
font = cv2.FONT_HERSHEY_PLAIN
|
255 |
+
color = (255, 255, 255)
|
256 |
+
cv2.putText(snap, label, (W//2 - 100, H//2),
|
257 |
+
font, 2, color, 2)
|
258 |
+
frame = cv2.imencode(".jpg", snap)[1].tobytes()
|
259 |
+
yield (b'--frame\r\n'
|
260 |
+
b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n')
|
261 |
+
|
262 |
+
|
263 |
+
# check_settings()
|
264 |
+
VIDEO = VideoStreaming()
|
265 |
+
|
266 |
+
|
267 |
+
@app.route('/', methods=['GET', 'POST'])
|
268 |
+
def homepage():
|
269 |
+
return render_template('hompage.html')
|
270 |
+
|
271 |
+
|
272 |
+
@app.route('/index', methods=['GET', 'POST'])
|
273 |
+
def index():
|
274 |
+
print("index")
|
275 |
+
global stop_flag
|
276 |
+
stop_flag = False
|
277 |
+
if request.method == 'POST':
|
278 |
+
print("Index post request")
|
279 |
+
url = request.form['url']
|
280 |
+
print("index: ", url)
|
281 |
+
session['url'] = url
|
282 |
+
return redirect(url_for('index'))
|
283 |
+
return render_template('index.html')
|
284 |
+
|
285 |
+
@app.route('/video_feed')
|
286 |
+
def video_feed():
|
287 |
+
url = session.get('url', None)
|
288 |
+
print("video feed: ", url)
|
289 |
+
if url is None:
|
290 |
+
return redirect(url_for('homepage'))
|
291 |
+
|
292 |
+
return Response(VIDEO.show(url), mimetype='multipart/x-mixed-replace; boundary=frame')
|
293 |
+
|
294 |
+
# * Button requests
|
295 |
+
@app.route("/request_preview_switch")
|
296 |
+
def request_preview_switch():
|
297 |
+
VIDEO.preview = not VIDEO.preview
|
298 |
+
print("*"*10, VIDEO.preview)
|
299 |
+
return "nothing"
|
300 |
+
|
301 |
+
@app.route("/request_flipH_switch")
|
302 |
+
def request_flipH_switch():
|
303 |
+
VIDEO.flipH = not VIDEO.flipH
|
304 |
+
print("*"*10, VIDEO.flipH)
|
305 |
+
return "nothing"
|
306 |
+
|
307 |
+
@app.route("/request_run_model_switch")
|
308 |
+
def request_run_model_switch():
|
309 |
+
VIDEO.detect = not VIDEO.detect
|
310 |
+
print("*"*10, VIDEO.detect)
|
311 |
+
return "nothing"
|
312 |
+
|
313 |
+
@app.route("/request_mediapipe_switch")
|
314 |
+
def request_mediapipe_switch():
|
315 |
+
VIDEO.mediaPipe = not VIDEO.mediaPipe
|
316 |
+
print("*"*10, VIDEO.mediaPipe)
|
317 |
+
return "nothing"
|
318 |
+
|
319 |
+
@app.route('/update_slider_value', methods=['POST'])
|
320 |
+
def update_slider_value():
|
321 |
+
slider_value = request.form['sliderValue']
|
322 |
+
VIDEO.confidence = slider_value
|
323 |
+
return 'OK'
|
324 |
+
|
325 |
+
@app.route('/stop_process')
|
326 |
+
def stop_process():
|
327 |
+
print("Process stop Request")
|
328 |
+
global stop_flag
|
329 |
+
stop_flag = True
|
330 |
+
return 'Process Stop Request'
|
331 |
+
|
332 |
+
@socketio.on('connect')
|
333 |
+
def test_connect():
|
334 |
+
print('Connected')
|
335 |
+
|
336 |
+
if __name__ == "__main__":
|
337 |
+
socketio.run(app, debug=False)
|
bisindo.pt
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:4e83f02d6ca8848205da96f4f9b2f6ae828be81b04b3f85dcbe1aeb7aaeb92bc
|
3 |
+
size 22568291
|
bisindov2.pt
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:f8a7cf3abad3a097d891edc2c9fc23ecf1dde738335ea4edb70c7c3698e19a9c
|
3 |
+
size 22565368
|
camera_settings.py
ADDED
@@ -0,0 +1,53 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import os
|
2 |
+
import cv2
|
3 |
+
|
4 |
+
|
5 |
+
# attrib_list = {
|
6 |
+
# "exposure": cv2.CAP_PROP_EXPOSURE,
|
7 |
+
# "contrast": cv2.CAP_PROP_CONTRAST
|
8 |
+
# }
|
9 |
+
|
10 |
+
|
11 |
+
def check_settings():
|
12 |
+
VIDEO_CHECK = cv2.VideoCapture(0)
|
13 |
+
|
14 |
+
if not os.path.exists("camera_settings.log"):
|
15 |
+
f = open("camera_settings.log", "w")
|
16 |
+
for attrib, index in attrib_list.items():
|
17 |
+
f.writelines(f"{attrib} = {VIDEO_CHECK.get(index)}\n")
|
18 |
+
f.close()
|
19 |
+
|
20 |
+
else:
|
21 |
+
f = open("camera_settings.log", "r")
|
22 |
+
lines = f.read().split("\n")
|
23 |
+
for line in lines:
|
24 |
+
attrib = line.split(" = ")
|
25 |
+
if attrib[0] in attrib_list.keys():
|
26 |
+
VIDEO_CHECK.set(attrib_list[attrib[0]], eval(attrib[1]))
|
27 |
+
f.close()
|
28 |
+
|
29 |
+
print("*"*28)
|
30 |
+
print("* Checking camera settings *")
|
31 |
+
print("*"*28)
|
32 |
+
for attrib, index in attrib_list.items():
|
33 |
+
print(f"{attrib} = {VIDEO_CHECK.get(index)}")
|
34 |
+
|
35 |
+
VIDEO_CHECK.release()
|
36 |
+
|
37 |
+
|
38 |
+
def reset_settings():
|
39 |
+
if not os.path.exists("camera_settings.log"):
|
40 |
+
print("'camera_settings.log' does not exist!")
|
41 |
+
print("Verify your camera settings!")
|
42 |
+
return False
|
43 |
+
else:
|
44 |
+
VIDEO_CHECK = cv2.VideoCapture(0)
|
45 |
+
f = open("camera_settings.log", "r")
|
46 |
+
lines = f.read().split("\n")
|
47 |
+
for line in lines:
|
48 |
+
attrib = line.split(" = ")
|
49 |
+
if attrib[0] in attrib_list.keys():
|
50 |
+
VIDEO_CHECK.set(attrib_list[attrib[0]], eval(attrib[1]))
|
51 |
+
f.close()
|
52 |
+
VIDEO_CHECK.release()
|
53 |
+
return True
|
img/confusion_matrix.png
ADDED
![]() |
img/results.png
ADDED
![]() |
requirements.txt
ADDED
Binary file (1.92 kB). View file
|
|
setup.cfg
ADDED
@@ -0,0 +1,56 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# Project-wide configuration file, can be used for package metadata and other toll configurations
|
2 |
+
# Example usage: global configuration for PEP8 (via flake8) setting or default pytest arguments
|
3 |
+
# Local usage: pip install pre-commit, pre-commit run --all-files
|
4 |
+
|
5 |
+
[metadata]
|
6 |
+
license_files = LICENSE
|
7 |
+
description_file = README.md
|
8 |
+
|
9 |
+
[tool:pytest]
|
10 |
+
norecursedirs =
|
11 |
+
.git
|
12 |
+
dist
|
13 |
+
build
|
14 |
+
addopts =
|
15 |
+
--doctest-modules
|
16 |
+
--durations=25
|
17 |
+
--color=yes
|
18 |
+
|
19 |
+
[flake8]
|
20 |
+
max-line-length = 120
|
21 |
+
exclude = .tox,*.egg,build,temp
|
22 |
+
select = E,W,F
|
23 |
+
doctests = True
|
24 |
+
verbose = 2
|
25 |
+
# https://pep8.readthedocs.io/en/latest/intro.html#error-codes
|
26 |
+
format = pylint
|
27 |
+
# see: https://www.flake8rules.com/
|
28 |
+
ignore = E731,F405,E402,W504,E501
|
29 |
+
# E731: Do not assign a lambda expression, use a def
|
30 |
+
# F405: name may be undefined, or defined from star imports: module
|
31 |
+
# E402: module level import not at top of file
|
32 |
+
# W504: line break after binary operator
|
33 |
+
# E501: line too long
|
34 |
+
# removed:
|
35 |
+
# F401: module imported but unused
|
36 |
+
# E231: missing whitespace after ‘,’, ‘;’, or ‘:’
|
37 |
+
# E127: continuation line over-indented for visual indent
|
38 |
+
# F403: ‘from module import *’ used; unable to detect undefined names
|
39 |
+
|
40 |
+
|
41 |
+
[isort]
|
42 |
+
# https://pycqa.github.io/isort/docs/configuration/options.html
|
43 |
+
line_length = 120
|
44 |
+
# see: https://pycqa.github.io/isort/docs/configuration/multi_line_output_modes.html
|
45 |
+
multi_line_output = 0
|
46 |
+
|
47 |
+
[yapf]
|
48 |
+
based_on_style = pep8
|
49 |
+
spaces_before_comment = 2
|
50 |
+
COLUMN_LIMIT = 120
|
51 |
+
COALESCE_BRACKETS = True
|
52 |
+
SPACES_AROUND_POWER_OPERATOR = True
|
53 |
+
SPACE_BETWEEN_ENDING_COMMA_AND_CLOSING_BRACKET = True
|
54 |
+
SPLIT_BEFORE_CLOSING_BRACKET = False
|
55 |
+
SPLIT_BEFORE_FIRST_ARGUMENT = False
|
56 |
+
# EACH_DICT_ENTRY_ON_SEPARATE_LINE = False
|
setup.py
ADDED
@@ -0,0 +1,65 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# Ultralytics YOLO 🚀, GPL-3.0 license
|
2 |
+
|
3 |
+
import re
|
4 |
+
from pathlib import Path
|
5 |
+
|
6 |
+
import pkg_resources as pkg
|
7 |
+
from setuptools import find_packages, setup
|
8 |
+
|
9 |
+
# Settings
|
10 |
+
FILE = Path(__file__).resolve()
|
11 |
+
PARENT = FILE.parent # root directory
|
12 |
+
README = (PARENT / 'README.md').read_text(encoding='utf-8')
|
13 |
+
REQUIREMENTS = [f'{x.name}{x.specifier}' for x in pkg.parse_requirements((PARENT / 'requirements.txt').read_text())]
|
14 |
+
PKG_REQUIREMENTS = ['sentry_sdk'] # pip-only requirements
|
15 |
+
|
16 |
+
|
17 |
+
def get_version():
|
18 |
+
file = PARENT / 'ultralytics/__init__.py'
|
19 |
+
return re.search(r'^__version__ = [\'"]([^\'"]*)[\'"]', file.read_text(encoding='utf-8'), re.M)[1]
|
20 |
+
|
21 |
+
|
22 |
+
setup(
|
23 |
+
name='ultralytics', # name of pypi package
|
24 |
+
version=get_version(), # version of pypi package
|
25 |
+
python_requires='>=3.7',
|
26 |
+
license='GPL-3.0',
|
27 |
+
description='Ultralytics YOLOv8',
|
28 |
+
long_description=README,
|
29 |
+
long_description_content_type='text/markdown',
|
30 |
+
url='https://github.com/ultralytics/ultralytics',
|
31 |
+
project_urls={
|
32 |
+
'Bug Reports': 'https://github.com/ultralytics/ultralytics/issues',
|
33 |
+
'Funding': 'https://ultralytics.com',
|
34 |
+
'Source': 'https://github.com/ultralytics/ultralytics'},
|
35 |
+
author='Ultralytics',
|
36 |
+
author_email='[email protected]',
|
37 |
+
packages=find_packages(), # required
|
38 |
+
include_package_data=True,
|
39 |
+
install_requires=REQUIREMENTS + PKG_REQUIREMENTS,
|
40 |
+
extras_require={
|
41 |
+
'dev': ['check-manifest', 'pytest', 'pytest-cov', 'coverage', 'mkdocs-material', 'mkdocstrings[python]'],
|
42 |
+
'export': ['coremltools>=6.0', 'onnx', 'onnxsim', 'onnxruntime', 'openvino-dev>=2022.3'],
|
43 |
+
'tf': ['onnx2tf', 'sng4onnx', 'tflite_support', 'tensorflow']},
|
44 |
+
classifiers=[
|
45 |
+
'Development Status :: 4 - Beta',
|
46 |
+
'Intended Audience :: Developers',
|
47 |
+
'Intended Audience :: Education',
|
48 |
+
'Intended Audience :: Science/Research',
|
49 |
+
'License :: OSI Approved :: GNU General Public License v3 (GPLv3)',
|
50 |
+
'Programming Language :: Python :: 3',
|
51 |
+
'Programming Language :: Python :: 3.7',
|
52 |
+
'Programming Language :: Python :: 3.8',
|
53 |
+
'Programming Language :: Python :: 3.9',
|
54 |
+
'Programming Language :: Python :: 3.10',
|
55 |
+
'Programming Language :: Python :: 3.11',
|
56 |
+
'Topic :: Software Development',
|
57 |
+
'Topic :: Scientific/Engineering',
|
58 |
+
'Topic :: Scientific/Engineering :: Artificial Intelligence',
|
59 |
+
'Topic :: Scientific/Engineering :: Image Recognition',
|
60 |
+
'Operating System :: POSIX :: Linux',
|
61 |
+
'Operating System :: MacOS',
|
62 |
+
'Operating System :: Microsoft :: Windows', ],
|
63 |
+
keywords='machine-learning, deep-learning, vision, ML, DL, AI, YOLO, YOLOv3, YOLOv5, YOLOv8, HUB, Ultralytics',
|
64 |
+
entry_points={
|
65 |
+
'console_scripts': ['yolo = ultralytics.yolo.cfg:entrypoint', 'ultralytics = ultralytics.yolo.cfg:entrypoint']})
|
static/script.js
ADDED
@@ -0,0 +1,194 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
//Updating Frames in Image tag to Show Video Stream
|
2 |
+
window.addEventListener('load', function () {
|
3 |
+
console.log("Window UP")
|
4 |
+
});
|
5 |
+
var show_ad = false;
|
6 |
+
|
7 |
+
$(document).ready(function () {
|
8 |
+
|
9 |
+
|
10 |
+
$("#banner2").hide();
|
11 |
+
$("#closeAd").click(function () {
|
12 |
+
$("#banner2").hide(1000);
|
13 |
+
});
|
14 |
+
});
|
15 |
+
|
16 |
+
function startCamera() {
|
17 |
+
var url = '0';
|
18 |
+
$('#urlForm').attr('action', '/index');
|
19 |
+
$('#urlForm').attr('method', 'POST');
|
20 |
+
$('#urlForm').find('#url').val(url);
|
21 |
+
$('#urlForm').submit();
|
22 |
+
}
|
23 |
+
|
24 |
+
function startVideo() {
|
25 |
+
var url = $('#url').val();
|
26 |
+
$('#urlForm').attr('action', '/index');
|
27 |
+
$('#urlForm').attr('method', 'POST');
|
28 |
+
$('#urlForm').find('#url').val(url);
|
29 |
+
$('#urlForm').submit();
|
30 |
+
}
|
31 |
+
|
32 |
+
function stopProcess(message) {
|
33 |
+
console.log("Stop BUTTON");
|
34 |
+
const terminalData = document.getElementById('terminal').innerHTML;
|
35 |
+
document.getElementById('terminal').innerHTML = terminalData + "<br><br><center>" + message + "</center><br><br>";
|
36 |
+
fetch('/stop_process')
|
37 |
+
.then(response => response.text())
|
38 |
+
.then(message => {
|
39 |
+
console.log(message);
|
40 |
+
// Redirect to homepage after stopping the process
|
41 |
+
window.location.href = '/';
|
42 |
+
})
|
43 |
+
.catch(error => console.error(error));
|
44 |
+
}
|
45 |
+
|
46 |
+
|
47 |
+
//This Code is used to Communicate b/w Client & Server via SOCKETIO
|
48 |
+
var socket = io.connect('http://127.0.0.1:5000/');
|
49 |
+
|
50 |
+
// Variabel untuk menyimpan kata-kata berturut-turut
|
51 |
+
let consecutiveWords = [];
|
52 |
+
let finalSentence = "";
|
53 |
+
let wordCounter = 0;
|
54 |
+
|
55 |
+
function appendToTerminal(message) {
|
56 |
+
var terminal = document.getElementById("terminal");
|
57 |
+
var p = document.createElement("p");
|
58 |
+
p.innerHTML = `<table class="table table-striped text-center" style="border: none;">
|
59 |
+
<tr class="row">
|
60 |
+
<td class="col-md-6" style="color: #01ECEC; border: none;">${message[0]}</td>
|
61 |
+
<td class="col-md-6" style="color: #01ECEC; border: none;">${message[1]}</td>
|
62 |
+
</tr>
|
63 |
+
</table>`;
|
64 |
+
terminal.appendChild(p);
|
65 |
+
terminal.scrollTop = terminal.scrollHeight;
|
66 |
+
|
67 |
+
if (consecutiveWords.length === 0 || consecutiveWords[consecutiveWords.length - 1] === message[0]) {
|
68 |
+
consecutiveWords.push(message[0]);
|
69 |
+
wordCounter++; // Menambah jumlah kemunculan kata yang sama
|
70 |
+
} else {
|
71 |
+
consecutiveWords = [message[0]];
|
72 |
+
wordCounter = 1; // Mengatur ulang jumlah kemunculan kata yang sama
|
73 |
+
}
|
74 |
+
|
75 |
+
if (wordCounter >= 7 && message[0] !== "G") {
|
76 |
+
finalSentence += (finalSentence.length > 0 ? " " : "") + consecutiveWords[0];
|
77 |
+
document.getElementById("finalSentencePara").innerText = finalSentence;
|
78 |
+
consecutiveWords = [];
|
79 |
+
wordCounter = 0;
|
80 |
+
}
|
81 |
+
}
|
82 |
+
|
83 |
+
//Updating Terminal with Detected Objects
|
84 |
+
socket.on("label", (data) => {
|
85 |
+
appendToTerminal(data);
|
86 |
+
});
|
87 |
+
|
88 |
+
//Code For All Switches
|
89 |
+
function toggleHSwitch() {
|
90 |
+
var switchElement = $("#flip-horizontal");
|
91 |
+
var switchIsOn = switchElement.is(":checked");
|
92 |
+
|
93 |
+
if (switchIsOn) {
|
94 |
+
console.log("SWITCH ON")
|
95 |
+
$.getJSON("/request_flipH_switch", function (data) {
|
96 |
+
console.log("Switch on request sent.");
|
97 |
+
});
|
98 |
+
} else {
|
99 |
+
console.log("SWITCH OFF")
|
100 |
+
$.getJSON("/request_flipH_switch", function (data) {
|
101 |
+
console.log("Switch off request sent.");
|
102 |
+
});
|
103 |
+
}
|
104 |
+
}
|
105 |
+
|
106 |
+
function toggleMediaPipeSwitch() {
|
107 |
+
var switchElement = $("#mediapipe");
|
108 |
+
var switchIsOn = switchElement.is(":checked");
|
109 |
+
|
110 |
+
if (switchIsOn) {
|
111 |
+
console.log("SWITCH ON")
|
112 |
+
$.getJSON("/request_mediapipe_switch", function (data) {
|
113 |
+
console.log("Switch on request sent.");
|
114 |
+
});
|
115 |
+
} else {
|
116 |
+
console.log("SWITCH OFF")
|
117 |
+
$.getJSON("/request_mediapipe_switch", function (data) {
|
118 |
+
console.log("Switch off request sent.");
|
119 |
+
});
|
120 |
+
}
|
121 |
+
}
|
122 |
+
|
123 |
+
function toggleDetSwitch() {
|
124 |
+
|
125 |
+
var switchElement = $("#run_detection");
|
126 |
+
var switchIsOn = switchElement.is(":checked");
|
127 |
+
|
128 |
+
if (switchIsOn) {
|
129 |
+
console.log("SWITCH ON")
|
130 |
+
$.getJSON("/request_run_model_switch", function (data) {
|
131 |
+
console.log("Switch on request sent.");
|
132 |
+
});
|
133 |
+
} else {
|
134 |
+
console.log("SWITCH OFF")
|
135 |
+
$.getJSON("/request_run_model_switch", function (data) {
|
136 |
+
console.log("Switch off request sent.");
|
137 |
+
});
|
138 |
+
}
|
139 |
+
}
|
140 |
+
|
141 |
+
function toggleOffSwitch() {
|
142 |
+
var switchElement = $("#turn_off");
|
143 |
+
var switchIsOn = switchElement.is(":checked");
|
144 |
+
|
145 |
+
if (switchIsOn) {
|
146 |
+
console.log("Camera ON")
|
147 |
+
$.getJSON("/request_preview_switch", function (data) {
|
148 |
+
console.log("Switch on request sent.");
|
149 |
+
});
|
150 |
+
} else {
|
151 |
+
console.log("Camera OFF")
|
152 |
+
$.getJSON("/request_preview_switch", function (data) {
|
153 |
+
console.log("Switch off request sent.");
|
154 |
+
});
|
155 |
+
}
|
156 |
+
}
|
157 |
+
|
158 |
+
$(document).ready(function () {
|
159 |
+
// Get the slider element
|
160 |
+
var slider = $('#slider');
|
161 |
+
|
162 |
+
// Attach the event listener to the slider element
|
163 |
+
slider.on('input', function () {
|
164 |
+
// Get the value of the slider
|
165 |
+
var sliderValue = slider.val();
|
166 |
+
|
167 |
+
// Call the updateSliderValue() function and pass in the slider value
|
168 |
+
updateSliderValue(sliderValue);
|
169 |
+
});
|
170 |
+
});
|
171 |
+
|
172 |
+
|
173 |
+
function updateSliderValue(sliderValue) {
|
174 |
+
console.log(sliderValue)
|
175 |
+
$.ajax({
|
176 |
+
type: 'POST',
|
177 |
+
url: '/update_slider_value',
|
178 |
+
data: {'sliderValue': sliderValue},
|
179 |
+
success: function () {
|
180 |
+
console.log('Slider value updated successfully!');
|
181 |
+
},
|
182 |
+
error: function () {
|
183 |
+
console.log('Error updating slider value!');
|
184 |
+
}
|
185 |
+
});
|
186 |
+
document.getElementById("conf_display").innerHTML = sliderValue
|
187 |
+
}
|
188 |
+
|
189 |
+
function toggleTheme() {
|
190 |
+
if (document.body.classList.contains("dark"))
|
191 |
+
document.body.classList.remove("dark");
|
192 |
+
else
|
193 |
+
document.body.classList.add("dark");
|
194 |
+
}
|
static/style.css
ADDED
@@ -0,0 +1,217 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/* * Reset all elements */
|
2 |
+
* {
|
3 |
+
margin: 0;
|
4 |
+
padding: 0;
|
5 |
+
}
|
6 |
+
|
7 |
+
|
8 |
+
/* * HTML elements */
|
9 |
+
body {
|
10 |
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
|
11 |
+
font-size: 18px;
|
12 |
+
font-weight: normal;
|
13 |
+
line-height: 1.5em;
|
14 |
+
}
|
15 |
+
|
16 |
+
|
17 |
+
/* * Local selectors */
|
18 |
+
#container {
|
19 |
+
width: 100%;
|
20 |
+
height: 586px;
|
21 |
+
border: 8px #2c374a solid;
|
22 |
+
background-color: #0F172A;
|
23 |
+
border-radius: 5px;
|
24 |
+
}
|
25 |
+
|
26 |
+
#videoElement {
|
27 |
+
height: 570px;
|
28 |
+
width: 100%;
|
29 |
+
background-color: #0F172A;
|
30 |
+
|
31 |
+
display: block;
|
32 |
+
margin-left: auto;
|
33 |
+
margin-right: auto;
|
34 |
+
}
|
35 |
+
|
36 |
+
#terminal {
|
37 |
+
border-radius: 5px;
|
38 |
+
border: 5px #1C2637 solid;
|
39 |
+
font-family: monospace;
|
40 |
+
font-size: 12px;
|
41 |
+
background-color: #0F172A;
|
42 |
+
height: 490px;
|
43 |
+
overflow-y: scroll;
|
44 |
+
}
|
45 |
+
|
46 |
+
#control {
|
47 |
+
margin-top: 40px;
|
48 |
+
}
|
49 |
+
|
50 |
+
.switch {
|
51 |
+
position: relative;
|
52 |
+
display: inline-block;
|
53 |
+
width: 60px;
|
54 |
+
height: 34px;
|
55 |
+
}
|
56 |
+
|
57 |
+
.switch input {
|
58 |
+
display: none;
|
59 |
+
}
|
60 |
+
|
61 |
+
.slider {
|
62 |
+
position: absolute;
|
63 |
+
cursor: pointer;
|
64 |
+
top: 0;
|
65 |
+
left: 0;
|
66 |
+
right: 0;
|
67 |
+
bottom: 0;
|
68 |
+
background-color: #1C2637;
|
69 |
+
transition: .4s;
|
70 |
+
}
|
71 |
+
|
72 |
+
.slider:before {
|
73 |
+
position: absolute;
|
74 |
+
content: "";
|
75 |
+
height: 26px;
|
76 |
+
width: 26px;
|
77 |
+
left: 4px;
|
78 |
+
bottom: 4px;
|
79 |
+
background-color: #0275d8;
|
80 |
+
transition: .4s;
|
81 |
+
}
|
82 |
+
|
83 |
+
input:checked + .slider {
|
84 |
+
background-color: #03DD6F;
|
85 |
+
}
|
86 |
+
|
87 |
+
input:focus + .slider {
|
88 |
+
box-shadow: 0 0 1px #000000;
|
89 |
+
}
|
90 |
+
|
91 |
+
input:checked + .slider:before {
|
92 |
+
transform: translateX(26px);
|
93 |
+
background-color: #1C2637;
|
94 |
+
}
|
95 |
+
|
96 |
+
/* Rounded sliders */
|
97 |
+
.slider.round {
|
98 |
+
border-radius: 34px;
|
99 |
+
}
|
100 |
+
|
101 |
+
.slider.round:before {
|
102 |
+
border-radius: 50%;
|
103 |
+
}
|
104 |
+
|
105 |
+
|
106 |
+
.container1 {
|
107 |
+
position: relative;
|
108 |
+
z-index: 0;
|
109 |
+
}
|
110 |
+
|
111 |
+
.overlay1 {
|
112 |
+
font-size: 13px;
|
113 |
+
position: absolute;
|
114 |
+
bottom: 0;
|
115 |
+
right: 80px;
|
116 |
+
z-index: 1;
|
117 |
+
background-color: rgba(255, 255, 255, 0.9);
|
118 |
+
}
|
119 |
+
|
120 |
+
.overlay2 {
|
121 |
+
font-size: 13px;
|
122 |
+
position: absolute;
|
123 |
+
bottom: 25px;
|
124 |
+
right: 80px;
|
125 |
+
z-index: 1;
|
126 |
+
background-color: rgba(255, 255, 255, 0.9);
|
127 |
+
}
|
128 |
+
|
129 |
+
.overlay3 {
|
130 |
+
font-size: 13px;
|
131 |
+
position: absolute;
|
132 |
+
bottom: 50px;
|
133 |
+
right: 80px;
|
134 |
+
z-index: 1;
|
135 |
+
background-color: rgba(255, 255, 255, 0.9);
|
136 |
+
}
|
137 |
+
|
138 |
+
.no-link {
|
139 |
+
color: inherit;
|
140 |
+
text-decoration: none;
|
141 |
+
}
|
142 |
+
|
143 |
+
button.frame {
|
144 |
+
background: none !important;
|
145 |
+
border: none;
|
146 |
+
padding: 0 !important;
|
147 |
+
/*optional*/
|
148 |
+
font-family: arial, sans-serif;
|
149 |
+
/*input has OS specific font-family*/
|
150 |
+
color: darkred;
|
151 |
+
cursor: pointer;
|
152 |
+
}
|
153 |
+
|
154 |
+
@keyframes jumbo {
|
155 |
+
from {
|
156 |
+
background-position: 50% 50%, 50% 50%;
|
157 |
+
}
|
158 |
+
to {
|
159 |
+
background-position: 350% 50%, 350% 50%;
|
160 |
+
}
|
161 |
+
}
|
162 |
+
|
163 |
+
.jumbo {
|
164 |
+
--stripes: repeating-linear-gradient(
|
165 |
+
100deg,
|
166 |
+
#0f172a 0%,
|
167 |
+
#0f172a 7%,
|
168 |
+
transparent 10%,
|
169 |
+
transparent 12%,
|
170 |
+
#0f172a 16%
|
171 |
+
);
|
172 |
+
--stripesDark: repeating-linear-gradient(
|
173 |
+
100deg,
|
174 |
+
#0f172a 0%,
|
175 |
+
#0f172a 7%,
|
176 |
+
transparent 10%,
|
177 |
+
transparent 12%,
|
178 |
+
#0f172a 16%
|
179 |
+
);
|
180 |
+
--rainbow: repeating-linear-gradient(
|
181 |
+
100deg,
|
182 |
+
#60a5fa 10%,
|
183 |
+
#e879f9 15%,
|
184 |
+
#60a5fa 20%,
|
185 |
+
#5eead4 25%,
|
186 |
+
#60a5fa 30%
|
187 |
+
);
|
188 |
+
background-image: var(--stripesDark), var(--rainbow);
|
189 |
+
|
190 |
+
background-size: 300%, 200%;
|
191 |
+
background-position: 50% 50%, 50% 50%;
|
192 |
+
|
193 |
+
filter: blur(10px) opacity(50%) saturate(200%);
|
194 |
+
|
195 |
+
mask-image: radial-gradient(ellipse at 100% 0%, black 40%, transparent 70%);
|
196 |
+
|
197 |
+
pointer-events: none;
|
198 |
+
}
|
199 |
+
|
200 |
+
.jumbo::after {
|
201 |
+
content: "";
|
202 |
+
position: absolute;
|
203 |
+
inset: 0;
|
204 |
+
background-image: var(--stripes), var(--rainbow);
|
205 |
+
background-size: 200%, 100%;
|
206 |
+
animation: jumbo 60s linear infinite;
|
207 |
+
background-attachment: fixed;
|
208 |
+
mix-blend-mode: difference;
|
209 |
+
}
|
210 |
+
|
211 |
+
.dark .jumbo {
|
212 |
+
background-image: var(--stripesDark), var(--rainbow);
|
213 |
+
filter: blur(10px) opacity(50%) saturate(200%);
|
214 |
+
}
|
215 |
+
.dark .jumbo::after {
|
216 |
+
background-image: var(--stripesDark), var(--rainbow);
|
217 |
+
}
|
templates/hompage copy.html
ADDED
@@ -0,0 +1,65 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<!DOCTYPE html>
|
2 |
+
<html lang="en">
|
3 |
+
|
4 |
+
<head>
|
5 |
+
<meta charset="UTF-8">
|
6 |
+
<title>BISINDO Translator</title>
|
7 |
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/tailwindcss/2.2.19/tailwind.min.css">
|
8 |
+
|
9 |
+
<style>
|
10 |
+
html {
|
11 |
+
font-family: 'Inter', sans-serif;
|
12 |
+
}
|
13 |
+
body {
|
14 |
+
background-color: #1F2937;
|
15 |
+
display: flex;
|
16 |
+
justify-content: center;
|
17 |
+
align-items: center;
|
18 |
+
height: 100vh;
|
19 |
+
margin: 0;
|
20 |
+
}
|
21 |
+
.card {
|
22 |
+
max-width: 400px;
|
23 |
+
background-color: #4B5563;
|
24 |
+
padding: 30px;
|
25 |
+
border-radius: 10px;
|
26 |
+
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
|
27 |
+
}
|
28 |
+
.card h1, .card h2 {
|
29 |
+
text-align: center;
|
30 |
+
margin-bottom: 20px;
|
31 |
+
}
|
32 |
+
input, button {
|
33 |
+
border: 1px solid #CBD5E0;
|
34 |
+
background-color: #4C566A;
|
35 |
+
color: #E5E7EB;
|
36 |
+
padding: 10px;
|
37 |
+
border-radius: 5px;
|
38 |
+
transition: all 0.3s ease;
|
39 |
+
}
|
40 |
+
input:focus, button:focus {
|
41 |
+
outline: none;
|
42 |
+
border-color: #2563EB;
|
43 |
+
}
|
44 |
+
button {
|
45 |
+
cursor: pointer;
|
46 |
+
}
|
47 |
+
button:hover {
|
48 |
+
background-color: #6B7280;
|
49 |
+
}
|
50 |
+
</style>
|
51 |
+
</head>
|
52 |
+
|
53 |
+
<body>
|
54 |
+
<div class="card">
|
55 |
+
<h1 class="text-4xl font-bold">Mohamed_sign_language</h1>
|
56 |
+
<h2 class="text-4xl font-bold">Sign Language Translation</h2>
|
57 |
+
<form id="urlForm">
|
58 |
+
<input type="text" id="url" name="url" class="text-sm rounded-lg block w-full mb-4" placeholder="Enter your video URL here..." required>
|
59 |
+
</form>
|
60 |
+
<button id="startStream" type="button" onclick="startVideo()" class="font-medium rounded-lg text-sm px-5 py-3 bg-gray-800 hover:bg-gray-600 focus:ring-gray-600">Stream</button>
|
61 |
+
<button id="startCamera" type="button" onclick="startCamera()" class="font-medium rounded-lg text-sm px-5 py-3 bg-gray-800 hover:bg-gray-600 focus:ring-gray-600">Camera</button>
|
62 |
+
</div>
|
63 |
+
</body>
|
64 |
+
|
65 |
+
</html>
|
templates/hompage.html
ADDED
@@ -0,0 +1,80 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}"/>
|
2 |
+
<html lang="en">
|
3 |
+
<head>
|
4 |
+
<meta charset="UTF-8">
|
5 |
+
<title>Mohamed</title>
|
6 |
+
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
|
7 |
+
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
|
8 |
+
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.6.1/socket.io.js"></script>
|
9 |
+
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"
|
10 |
+
integrity="sha384-kenU1KFdBIe4zVF0s0G1M5b4hcpxyD9F7jL+jjXkk+Q2h455rYXK/7HAuoJl+0I4"
|
11 |
+
crossorigin="anonymous"></script>
|
12 |
+
|
13 |
+
<script type="text/javascript" src="{{ url_for('static', filename='script.js') }}"></script>
|
14 |
+
<!-- Add this to the <head> section of your HTML file -->
|
15 |
+
|
16 |
+
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.12.0/css/dataTables.bootstrap5.min.css">
|
17 |
+
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
|
18 |
+
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
|
19 |
+
|
20 |
+
<script src="https://cdn.tailwindcss.com"></script>
|
21 |
+
<link href="https://cdnjs.cloudflare.com/ajax/libs/flowbite/2.2.0/flowbite.min.css" rel="stylesheet" />
|
22 |
+
<script src="https://cdnjs.cloudflare.com/ajax/libs/flowbite/2.2.0/flowbite.min.js"></script>
|
23 |
+
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&display=swap">
|
24 |
+
<style>
|
25 |
+
html {
|
26 |
+
font-family: 'Inter', sans-serif;
|
27 |
+
}
|
28 |
+
body {
|
29 |
+
background-color: #1F2937;
|
30 |
+
display: flex;
|
31 |
+
justify-content: center;
|
32 |
+
align-items: center;
|
33 |
+
height: 100vh;
|
34 |
+
margin: 0;
|
35 |
+
}
|
36 |
+
.card {
|
37 |
+
max-width: 400px;
|
38 |
+
background-color: #4B5563;
|
39 |
+
padding: 30px;
|
40 |
+
border-radius: 10px;
|
41 |
+
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
|
42 |
+
}
|
43 |
+
.card h1, .card h2 {
|
44 |
+
text-align: center;
|
45 |
+
margin-bottom: 20px;
|
46 |
+
}
|
47 |
+
input, button {
|
48 |
+
border: 1px solid #CBD5E0;
|
49 |
+
background-color: #4C566A;
|
50 |
+
color: #E5E7EB;
|
51 |
+
padding: 10px;
|
52 |
+
border-radius: 5px;
|
53 |
+
transition: all 0.3s ease;
|
54 |
+
}
|
55 |
+
input:focus, button:focus {
|
56 |
+
outline: none;
|
57 |
+
border-color: #2563EB;
|
58 |
+
}
|
59 |
+
button {
|
60 |
+
cursor: pointer;
|
61 |
+
}
|
62 |
+
button:hover {
|
63 |
+
background-color: #6B7280;
|
64 |
+
}
|
65 |
+
</style>
|
66 |
+
</head>
|
67 |
+
|
68 |
+
<body>
|
69 |
+
<div class="card">
|
70 |
+
<h1 class="text-2xl font-bold">محمد لغة الإشارة</h1>
|
71 |
+
<h2 class="text-4xl font-bold">ترجمة اللغة الإشارية</h2>
|
72 |
+
<form id="urlForm">
|
73 |
+
<input type="text" id="url" name="url" class="text-sm rounded-lg block w-full mb-4" placeholder="أدخل رابط الفيديو هنا..." required>
|
74 |
+
</form>
|
75 |
+
<button id="startStream" type="button" onclick="startVideo()" class="font-medium rounded-lg text-sm px-5 py-3 bg-gray-800 hover:bg-gray-600 focus:ring-gray-600">URL بث</button>
|
76 |
+
<button id="startCamera" type="button" onclick="startCamera()" class="font-medium rounded-lg text-sm px-5 py-3 bg-gray-800 hover:bg-gray-600 focus:ring-gray-600">كاميرا</button>
|
77 |
+
</div>
|
78 |
+
</body>
|
79 |
+
|
80 |
+
</html>
|
templates/index copy.html
ADDED
@@ -0,0 +1,72 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{#L1 labels/object#}
|
2 |
+
{#L2 Logo Detection#}
|
3 |
+
{#L3 Text/OCR#}
|
4 |
+
|
5 |
+
<!DOCTYPE html>
|
6 |
+
<html lang="en">
|
7 |
+
|
8 |
+
<head>
|
9 |
+
<meta charset="UTF-8">
|
10 |
+
<title>BISINDO Translator</title>
|
11 |
+
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}"/>
|
12 |
+
<!-- Bootstrap CSS -->
|
13 |
+
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet"
|
14 |
+
integrity="sha384-rbsA2VBKQhggwzxH7pPCaAqO46MgnOM80zW1RWuH61DGLwZJEdK2Kadq2F9CUG65" crossorigin="anonymous">
|
15 |
+
<!-- Font Awesome CSS -->
|
16 |
+
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.1/css/fontawesome.min.css"
|
17 |
+
integrity="sha512-xX2rYBFJSj86W54Fyv1de80DWBq7zYLn2z0I9bIhQG+rxIF6XVJUpdGnsNHWRa6AvP89vtFupEPDP8eZAtu9qA=="
|
18 |
+
crossorigin="anonymous" referrerpolicy="no-referrer"/>
|
19 |
+
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.1/css/brands.min.css"
|
20 |
+
integrity="sha512-OivR4OdSsE1onDm/i3J3Hpsm5GmOVvr9r49K3jJ0dnsxVzZgaOJ5MfxEAxCyGrzWozL9uJGKz6un3A7L+redIQ=="
|
21 |
+
crossorigin="anonymous" referrerpolicy="no-referrer"/>
|
22 |
+
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.1/css/all.min.css"
|
23 |
+
integrity="sha512-KfkfwYDsLkIlwQp6LFnl8zNdLGxu9YAA1QvwINks4PhcElQSvqcyVLLD9aMhXd13uQjoXtEKNosOWaZqXgel0g=="
|
24 |
+
crossorigin="anonymous" referrerpolicy="no-referrer"/>
|
25 |
+
<!-- Bootstrap Icons CSS -->
|
26 |
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/font/bootstrap-icons.css">
|
27 |
+
<!-- DataTables Bootstrap CSS -->
|
28 |
+
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.12.0/css/dataTables.bootstrap5.min.css">
|
29 |
+
<!-- Flowbite CSS -->
|
30 |
+
<link href="https://cdnjs.cloudflare.com/ajax/libs/flowbite/2.2.0/flowbite.min.css" rel="stylesheet" />
|
31 |
+
<!-- Google Fonts -->
|
32 |
+
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&display=swap">
|
33 |
+
</head>
|
34 |
+
|
35 |
+
<body class="bg-light-grey">
|
36 |
+
<div class="container mt-5">
|
37 |
+
<div class="card bg-medium-grey text-white">
|
38 |
+
<div class="card-header bg-dark-grey">
|
39 |
+
BISINDO Translator
|
40 |
+
</div>
|
41 |
+
<div class="card-body">
|
42 |
+
<div class="grid grid-cols-12 gap-4">
|
43 |
+
<!-- Controls -->
|
44 |
+
<div class="col-span-2">
|
45 |
+
<h2 class="border-b border-grey py-4 mb-4 text-3xl font-bold leading-none tracking-tight md:text-4xl lg:text-4xl text-light-grey">Controls</h2>
|
46 |
+
<!-- Controls content here -->
|
47 |
+
</div>
|
48 |
+
<!-- Video -->
|
49 |
+
<div class="col-span-8">
|
50 |
+
<!-- Video content here -->
|
51 |
+
</div>
|
52 |
+
<!-- Terminal -->
|
53 |
+
<div class="col-span-2">
|
54 |
+
<h2 class="border-b border-grey py-4 mb-4 text-3xl flex justify-end font-bold leading-none tracking-tight md:text-4xl lg:text-4xl text-light-grey">Output</h2>
|
55 |
+
<!-- Terminal content here -->
|
56 |
+
</div>
|
57 |
+
</div>
|
58 |
+
<!-- Final Sentence -->
|
59 |
+
<div class="flex items-center mx-12 text-center content-start gap-4 border-b border-grey py-4 justify-center">
|
60 |
+
<span class="text-center inline-block px-3 py-1 text-xs font-bold tracking-wide text-dark-grey bg-info rounded-full">Collecting every 10 consecutive occurrences of the same word</span>
|
61 |
+
</div>
|
62 |
+
<div>
|
63 |
+
<p id="finalSentencePara" class="text-light-grey mt-4 text-center"></p>
|
64 |
+
</div>
|
65 |
+
</div>
|
66 |
+
</div>
|
67 |
+
</div>
|
68 |
+
<!-- Bootstrap JS -->
|
69 |
+
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
|
70 |
+
</body>
|
71 |
+
|
72 |
+
</html>
|
templates/index.html
ADDED
@@ -0,0 +1,120 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{#L1 labels/object#}
|
2 |
+
{#L2 Logo Detection#}
|
3 |
+
{#L3 Text/OCR#}
|
4 |
+
|
5 |
+
|
6 |
+
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}"/>
|
7 |
+
<html lang="en">
|
8 |
+
<head>
|
9 |
+
<meta charset="UTF-8">
|
10 |
+
<title>Mohamed sign</title>
|
11 |
+
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
|
12 |
+
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
|
13 |
+
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.6.1/socket.io.js"></script>
|
14 |
+
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"
|
15 |
+
integrity="sha384-kenU1KFdBIe4zVF0s0G1M5b4hcpxyD9F7jL+jjXkk+Q2h455rYXK/7HAuoJl+0I4"
|
16 |
+
crossorigin="anonymous"></script>
|
17 |
+
<script type="text/javascript" src="{{ url_for('static', filename='script.js') }}"></script>
|
18 |
+
<!-- Add this to the <head> section of your HTML file -->
|
19 |
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/font/bootstrap-icons.css">
|
20 |
+
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet"
|
21 |
+
integrity="sha384-rbsA2VBKQhggwzxH7pPCaAqO46MgnOM80zW1RWuH61DGLwZJEdK2Kadq2F9CUG65" crossorigin="anonymous">
|
22 |
+
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}"/>
|
23 |
+
|
24 |
+
|
25 |
+
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.1/css/fontawesome.min.css"
|
26 |
+
integrity="sha512-xX2rYBFJSj86W54Fyv1de80DWBq7zYLn2z0I9bIhQG+rxIF6XVJUpdGnsNHWRa6AvP89vtFupEPDP8eZAtu9qA=="
|
27 |
+
crossorigin="anonymous" referrerpolicy="no-referrer"/>
|
28 |
+
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.1/css/brands.min.css"
|
29 |
+
integrity="sha512-OivR4OdSsE1onDm/i3J3Hpsm5GmOVvr9r49K3jJ0dnsxVzZgaOJ5MfxEAxCyGrzWozL9uJGKz6un3A7L+redIQ=="
|
30 |
+
crossorigin="anonymous" referrerpolicy="no-referrer"/>
|
31 |
+
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.1/css/all.min.css"
|
32 |
+
integrity="sha512-KfkfwYDsLkIlwQp6LFnl8zNdLGxu9YAA1QvwINks4PhcElQSvqcyVLLD9aMhXd13uQjoXtEKNosOWaZqXgel0g=="
|
33 |
+
crossorigin="anonymous" referrerpolicy="no-referrer"/>
|
34 |
+
|
35 |
+
<link rel="stylesheet" type="text/css"
|
36 |
+
href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/5.1.3/css/bootstrap.min.css">
|
37 |
+
|
38 |
+
|
39 |
+
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.12.0/css/dataTables.bootstrap5.min.css">
|
40 |
+
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
|
41 |
+
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
|
42 |
+
|
43 |
+
<script src="https://cdn.tailwindcss.com"></script>
|
44 |
+
<link href="https://cdnjs.cloudflare.com/ajax/libs/flowbite/2.2.0/flowbite.min.css" rel="stylesheet" />
|
45 |
+
<script src="https://cdnjs.cloudflare.com/ajax/libs/flowbite/2.2.0/flowbite.min.js"></script>
|
46 |
+
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&display=swap">
|
47 |
+
|
48 |
+
</head>
|
49 |
+
<body class="bg-gray-900"> <!-- تغيير لون الخلفية إلى رمادي 900 -->
|
50 |
+
|
51 |
+
<div class="grid grid-cols-12 gap-4 mx-8 mt-8" style="color: gray; border-radius: 10px;"> <!-- أضفت أسلوبًا لحاوية الشبكة -->
|
52 |
+
|
53 |
+
<!-- Controls -->
|
54 |
+
<div class="col-span-2 ml-4" style="background-color: lightgrey; border-radius: 10px;"> <!-- أضفت لون خلفية ونصبت دائرة لـ div التحكم -->
|
55 |
+
<h2 class="border-b border-gray-800 py-4 mb-4 text-3xl font-bold leading-none tracking-tight md:text-4xl lg:text-4xl text-gray-500">التحكم</h1> <!-- تغيير لون الحدود والنص -->
|
56 |
+
<div class="border-b border-gray-800" style="padding: 10px;"> <!-- أضفت حشوًا للحدود الداخلية -->
|
57 |
+
<div class="flex gap-3 mb-4">
|
58 |
+
<label class="switch">
|
59 |
+
<input id="turn_off" value="1" name="turn_off" type="checkbox" onclick="toggleOffSwitch()"/>
|
60 |
+
<span class="slider round"></span>
|
61 |
+
</label>
|
62 |
+
<label for="turn_off" class="form-label text-gray-500">عرض الفيديو</label><br>
|
63 |
+
</div>
|
64 |
+
<div class="flex gap-3 mb-4">
|
65 |
+
<label class="switch">
|
66 |
+
<input id="run_detection" value="0" name="run_detection" type="checkbox" onclick="toggleDetSwitch()"/>
|
67 |
+
<span class="slider round"></span>
|
68 |
+
</label>
|
69 |
+
<label for="run_detection" class="form-label text-gray-500">تشغيل الكشف</label><br>
|
70 |
+
</div>
|
71 |
+
<div class="flex gap-3 mb-4">
|
72 |
+
<label class="switch">
|
73 |
+
<input id="mediapipe" value="0" name="mediapipe" type="checkbox" onclick="toggleMediaPipeSwitch()"/>
|
74 |
+
<span class="slider round"></span>
|
75 |
+
</label>
|
76 |
+
<label for="mediapipe" class="form-label text-gray-500">عرض العلامات</label><br>
|
77 |
+
</div>
|
78 |
+
<div class="flex gap-3 mb-4">
|
79 |
+
<label class="switch">
|
80 |
+
<input id="flip-horizontal" value="0" name="flip-horizontal" type="checkbox" onclick="toggleHSwitch()"/>
|
81 |
+
<span class="slider round"></span>
|
82 |
+
</label>
|
83 |
+
<label for="flip-horizontal" class="form-label text-gray-500">قلب الفيديو</label><br>
|
84 |
+
</div>
|
85 |
+
</div>
|
86 |
+
<div class="gap-3 py-4 text-center border-b border-gray-800 mb-5">
|
87 |
+
<form action="/" method="POST" style="text-align: center;" class="mb-4" >
|
88 |
+
<label for="slider" class="form-label text-gray-500">حد الثقة</label>
|
89 |
+
<input type="range" id="slider" name="slider" min="1" max="100">
|
90 |
+
</form>
|
91 |
+
<input type="hidden" id="sliderValue" name="sliderValue" value="75">
|
92 |
+
<span class="rounded-lg py-2 px-3 bg-gray-800 text-gray-500" id="conf_display">75</span> <!-- تغيير لون الخلفية والنص -->
|
93 |
+
</div>
|
94 |
+
<button class="text-white focus:ring-4 focus:outline-none mt-1.5 font-medium rounded-lg text-sm w-full py-2.5 text-center bg-gray-700 hover:bg-gray-800 focus:ring-gray-900" id="stop-button" type="button" onclick="stopProcess('Stop Request')">العودة للصفحة الرئيسية</button> <!-- تغيير نمط الزر -->
|
95 |
+
</div>
|
96 |
+
|
97 |
+
<!-- Video -->
|
98 |
+
<div class="col-span-8 mx-4 mt-3" style="background-color: lightgrey; border-radius: 10px;"> <!-- أضفت لون خلفية ونصبت دائرة لـ div الفيديو -->
|
99 |
+
<div id="container">
|
100 |
+
<img class="center" src="/video_feed" id="videoElement">
|
101 |
+
</div>
|
102 |
+
</div>
|
103 |
+
|
104 |
+
<!-- Terminal -->
|
105 |
+
<div class="col-span-2 mr-4" style="background-color: lightgrey; border-radius: 10px;"> <!-- أضفت لون خلفية ونصبت دائرة لـ div الطرفية -->
|
106 |
+
<h2 class="border-b border-gray-800 py-4 mb-4 text-3xl flex justify-end font-bold leading-none tracking-tight md:text-4xl lg:text-4xl text-gray-500">الناتج</h1> <!-- تغيير لون الحدود والنص -->
|
107 |
+
<div id="terminal" class="w-full"></div>
|
108 |
+
</div>
|
109 |
+
</div>
|
110 |
+
|
111 |
+
<div>
|
112 |
+
<p id="finalSentencePara" class="text-gray-500 mt-4 text-center"> <!-- تغيير لون النص -->
|
113 |
+
</p>
|
114 |
+
</div>
|
115 |
+
</body>
|
116 |
+
|
117 |
+
|
118 |
+
|
119 |
+
|
120 |
+
</html>
|
templates/indexv1.html
ADDED
@@ -0,0 +1,112 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{#L1 labels/object#}
|
2 |
+
{#L2 Logo Detection#}
|
3 |
+
{#L3 Text/OCR#}
|
4 |
+
|
5 |
+
|
6 |
+
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}"/>
|
7 |
+
<html lang="en">
|
8 |
+
<head>
|
9 |
+
<meta charset="UTF-8">
|
10 |
+
<title>Live Object Detection</title>
|
11 |
+
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
|
12 |
+
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
|
13 |
+
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.6.1/socket.io.js"></script>
|
14 |
+
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"
|
15 |
+
integrity="sha384-kenU1KFdBIe4zVF0s0G1M5b4hcpxyD9F7jL+jjXkk+Q2h455rYXK/7HAuoJl+0I4"
|
16 |
+
crossorigin="anonymous"></script>
|
17 |
+
<script type="text/javascript" src="{{ url_for('static', filename='script.js') }}"></script>
|
18 |
+
<!-- Add this to the <head> section of your HTML file -->
|
19 |
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/font/bootstrap-icons.css">
|
20 |
+
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet"
|
21 |
+
integrity="sha384-rbsA2VBKQhggwzxH7pPCaAqO46MgnOM80zW1RWuH61DGLwZJEdK2Kadq2F9CUG65" crossorigin="anonymous">
|
22 |
+
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}"/>
|
23 |
+
|
24 |
+
|
25 |
+
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.1/css/fontawesome.min.css"
|
26 |
+
integrity="sha512-xX2rYBFJSj86W54Fyv1de80DWBq7zYLn2z0I9bIhQG+rxIF6XVJUpdGnsNHWRa6AvP89vtFupEPDP8eZAtu9qA=="
|
27 |
+
crossorigin="anonymous" referrerpolicy="no-referrer"/>
|
28 |
+
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.1/css/brands.min.css"
|
29 |
+
integrity="sha512-OivR4OdSsE1onDm/i3J3Hpsm5GmOVvr9r49K3jJ0dnsxVzZgaOJ5MfxEAxCyGrzWozL9uJGKz6un3A7L+redIQ=="
|
30 |
+
crossorigin="anonymous" referrerpolicy="no-referrer"/>
|
31 |
+
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.1/css/all.min.css"
|
32 |
+
integrity="sha512-KfkfwYDsLkIlwQp6LFnl8zNdLGxu9YAA1QvwINks4PhcElQSvqcyVLLD9aMhXd13uQjoXtEKNosOWaZqXgel0g=="
|
33 |
+
crossorigin="anonymous" referrerpolicy="no-referrer"/>
|
34 |
+
|
35 |
+
<link rel="stylesheet" type="text/css"
|
36 |
+
href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/5.1.3/css/bootstrap.min.css">
|
37 |
+
|
38 |
+
|
39 |
+
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.12.0/css/dataTables.bootstrap5.min.css">
|
40 |
+
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
|
41 |
+
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
|
42 |
+
|
43 |
+
<script src="https://cdn.tailwindcss.com"></script>
|
44 |
+
<link href="https://cdnjs.cloudflare.com/ajax/libs/flowbite/2.2.0/flowbite.min.css" rel="stylesheet" />
|
45 |
+
<script src="https://cdnjs.cloudflare.com/ajax/libs/flowbite/2.2.0/flowbite.min.js"></script>
|
46 |
+
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&display=swap">
|
47 |
+
|
48 |
+
</head>
|
49 |
+
<body class="bg-slate-900">
|
50 |
+
<div class="grid grid-cols-12 gap-4 m-8">
|
51 |
+
<div class="col-span-6">
|
52 |
+
<div class="container1" style="text-align: center;">
|
53 |
+
<div id="container">
|
54 |
+
<img class="center" src="/video_feed" id="videoElement">
|
55 |
+
</div>
|
56 |
+
</div>
|
57 |
+
<div id="terminal" class="w-full"></div>
|
58 |
+
</div>
|
59 |
+
<div class="col-span-6 mx-2">
|
60 |
+
<div class="flex justify-between border-b border-gray-700 py-4 mt-10 mx-8 mb-4 ">
|
61 |
+
<h2 class="text-3xl font-bold leading-none tracking-tight md:text-4xl lg:text-5xl text-cyan-500 ">Video Stream</h1>
|
62 |
+
<button class="text-white focus:ring-4 focus:outline-none font-medium rounded-lg text-sm w-full sm:w-auto px-4 py-2.5 text-center bg-blue-600 hover:bg-blue-700 focus:ring-blue-800" id="stop-button" type="button" onclick="stopProcess('Stop Request')">Back to Homepage</button>
|
63 |
+
</div>
|
64 |
+
<div class="mx-8 border-b border-gray-700">
|
65 |
+
<div class="flex gap-3 mb-4">
|
66 |
+
<label class="switch">
|
67 |
+
<input id="turn_off" value="1" name="turn_off" type="checkbox" onclick="toggleOffSwitch()"/>
|
68 |
+
<span class="slider round"></span>
|
69 |
+
</label>
|
70 |
+
<label for="turn_off" class="form-label text-cyan-500">Show Stream</label><br>
|
71 |
+
</div>
|
72 |
+
<div class="flex gap-3 mb-4">
|
73 |
+
<label class="switch">
|
74 |
+
<input id="run_detection" value="0" name="run_detection" type="checkbox"
|
75 |
+
onclick="toggleDetSwitch()"/>
|
76 |
+
<span class="slider round"></span>
|
77 |
+
</label>
|
78 |
+
<label for="run_detection" class="form-label text-cyan-500">Run Detection</label><br>
|
79 |
+
</div>
|
80 |
+
<div class="flex gap-3 mb-4">
|
81 |
+
<label class="switch">
|
82 |
+
<input id="flip-horizontal" value="0" name="flip-horizontal" type="checkbox"
|
83 |
+
onclick="toggleHSwitch()"/>
|
84 |
+
<span class="slider round"></span>
|
85 |
+
</label>
|
86 |
+
<label for="flip-horizontal" class="form-label text-cyan-500">Flip Horizontally</label><br>
|
87 |
+
</div>
|
88 |
+
</div>
|
89 |
+
|
90 |
+
<div class="mx-8 flex items-center content-center gap-3 justify-between py-4">
|
91 |
+
<form action="/" method="POST" style="text-align: center;" class="flex justify-between w-full">
|
92 |
+
<label for="slider" class="form-label text-cyan-500">Confidence Threshold</label>
|
93 |
+
<input type="range" id="slider" name="slider" min="50" max="100">
|
94 |
+
</form>
|
95 |
+
<input type="hidden" id="sliderValue" name="sliderValue" value="75">
|
96 |
+
<span class="rounded-lg py-2 px-3 bg-slate-800 mr-6 text-cyan-500" id="conf_display">75</span>
|
97 |
+
</div>
|
98 |
+
|
99 |
+
<div class="flex items-center content-start gap-4 border-b border-gray-700 py-4 mt-10 mx-8 mb-4">
|
100 |
+
<h2 class=" text-2xl font-semibold leading-none tracking-tight md:text-3xl lg:text-4xl text-cyan-500 ">Final Sentence</h1>
|
101 |
+
<span class="inline-block px-3 py-1 text-xs font-bold tracking-wide mt-2 text-gray-900 bg-blue-500 rounded-full">Collecting every 10 consecutive occurrences of the same word</span>
|
102 |
+
</div>
|
103 |
+
|
104 |
+
<div>
|
105 |
+
<p id="finalSentencePara" class="text-cyan-200 mx-8">
|
106 |
+
</p>
|
107 |
+
</div>
|
108 |
+
|
109 |
+
</div>
|
110 |
+
</div>
|
111 |
+
</body>
|
112 |
+
</html>
|
tests/test_cli.py
ADDED
@@ -0,0 +1,81 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# Ultralytics YOLO 🚀, GPL-3.0 license
|
2 |
+
|
3 |
+
import subprocess
|
4 |
+
from pathlib import Path
|
5 |
+
|
6 |
+
from ultralytics.yolo.utils import LINUX, ONLINE, ROOT, SETTINGS
|
7 |
+
|
8 |
+
MODEL = Path(SETTINGS['weights_dir']) / 'yolov8n'
|
9 |
+
CFG = 'yolov8n'
|
10 |
+
|
11 |
+
|
12 |
+
def run(cmd):
|
13 |
+
# Run a subprocess command with check=True
|
14 |
+
subprocess.run(cmd.split(), check=True)
|
15 |
+
|
16 |
+
|
17 |
+
def test_special_modes():
|
18 |
+
run('yolo checks')
|
19 |
+
run('yolo settings')
|
20 |
+
run('yolo help')
|
21 |
+
|
22 |
+
|
23 |
+
# Train checks ---------------------------------------------------------------------------------------------------------
|
24 |
+
def test_train_det():
|
25 |
+
run(f'yolo train detect model={CFG}.yaml data=coco8.yaml imgsz=32 epochs=1 v5loader')
|
26 |
+
|
27 |
+
|
28 |
+
def test_train_seg():
|
29 |
+
run(f'yolo train segment model={CFG}-seg.yaml data=coco8-seg.yaml imgsz=32 epochs=1')
|
30 |
+
|
31 |
+
|
32 |
+
def test_train_cls():
|
33 |
+
run(f'yolo train classify model={CFG}-cls.yaml data=imagenet10 imgsz=32 epochs=1')
|
34 |
+
|
35 |
+
|
36 |
+
# Val checks -----------------------------------------------------------------------------------------------------------
|
37 |
+
def test_val_detect():
|
38 |
+
run(f'yolo val detect model={MODEL}.pt data=coco8.yaml imgsz=32')
|
39 |
+
|
40 |
+
|
41 |
+
def test_val_segment():
|
42 |
+
run(f'yolo val segment model={MODEL}-seg.pt data=coco8-seg.yaml imgsz=32')
|
43 |
+
|
44 |
+
|
45 |
+
def test_val_classify():
|
46 |
+
run(f'yolo val classify model={MODEL}-cls.pt data=imagenet10 imgsz=32')
|
47 |
+
|
48 |
+
|
49 |
+
# Predict checks -------------------------------------------------------------------------------------------------------
|
50 |
+
def test_predict_detect():
|
51 |
+
run(f"yolo predict model={MODEL}.pt source={ROOT / 'assets'} imgsz=32 save save_crop save_txt")
|
52 |
+
if ONLINE:
|
53 |
+
run(f'yolo predict model={MODEL}.pt source=https://ultralytics.com/images/bus.jpg imgsz=32')
|
54 |
+
run(f'yolo predict model={MODEL}.pt source=https://ultralytics.com/assets/decelera_landscape_min.mov imgsz=32')
|
55 |
+
run(f'yolo predict model={MODEL}.pt source=https://ultralytics.com/assets/decelera_portrait_min.mov imgsz=32')
|
56 |
+
|
57 |
+
|
58 |
+
def test_predict_segment():
|
59 |
+
run(f"yolo predict model={MODEL}-seg.pt source={ROOT / 'assets'} imgsz=32 save save_txt")
|
60 |
+
|
61 |
+
|
62 |
+
def test_predict_classify():
|
63 |
+
run(f"yolo predict model={MODEL}-cls.pt source={ROOT / 'assets'} imgsz=32 save save_txt")
|
64 |
+
|
65 |
+
|
66 |
+
# Export checks --------------------------------------------------------------------------------------------------------
|
67 |
+
def test_export_detect_torchscript():
|
68 |
+
run(f'yolo export model={MODEL}.pt format=torchscript')
|
69 |
+
|
70 |
+
|
71 |
+
def test_export_segment_torchscript():
|
72 |
+
run(f'yolo export model={MODEL}-seg.pt format=torchscript')
|
73 |
+
|
74 |
+
|
75 |
+
def test_export_classify_torchscript():
|
76 |
+
run(f'yolo export model={MODEL}-cls.pt format=torchscript')
|
77 |
+
|
78 |
+
|
79 |
+
def test_export_detect_edgetpu(enabled=False):
|
80 |
+
if enabled and LINUX:
|
81 |
+
run(f'yolo export model={MODEL}.pt format=edgetpu')
|
tests/test_engine.py
ADDED
@@ -0,0 +1,93 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# Ultralytics YOLO 🚀, GPL-3.0 license
|
2 |
+
|
3 |
+
from pathlib import Path
|
4 |
+
|
5 |
+
from ultralytics.yolo.cfg import get_cfg
|
6 |
+
from ultralytics.yolo.utils import DEFAULT_CFG, ROOT, SETTINGS
|
7 |
+
from ultralytics.yolo.v8 import classify, detect, segment
|
8 |
+
|
9 |
+
CFG_DET = 'yolov8n.yaml'
|
10 |
+
CFG_SEG = 'yolov8n-seg.yaml'
|
11 |
+
CFG_CLS = 'squeezenet1_0'
|
12 |
+
CFG = get_cfg(DEFAULT_CFG)
|
13 |
+
MODEL = Path(SETTINGS['weights_dir']) / 'yolov8n'
|
14 |
+
SOURCE = ROOT / 'assets'
|
15 |
+
|
16 |
+
|
17 |
+
def test_detect():
|
18 |
+
overrides = {'data': 'coco8.yaml', 'model': CFG_DET, 'imgsz': 32, 'epochs': 1, 'save': False}
|
19 |
+
CFG.data = 'coco8.yaml'
|
20 |
+
|
21 |
+
# Trainer
|
22 |
+
trainer = detect.DetectionTrainer(overrides=overrides)
|
23 |
+
trainer.train()
|
24 |
+
|
25 |
+
# Validator
|
26 |
+
val = detect.DetectionValidator(args=CFG)
|
27 |
+
val(model=trainer.best) # validate best.pt
|
28 |
+
|
29 |
+
# Predictor
|
30 |
+
pred = detect.DetectionPredictor(overrides={'imgsz': [64, 64]})
|
31 |
+
result = pred(source=SOURCE, model=f'{MODEL}.pt')
|
32 |
+
assert len(result), 'predictor test failed'
|
33 |
+
|
34 |
+
overrides['resume'] = trainer.last
|
35 |
+
trainer = detect.DetectionTrainer(overrides=overrides)
|
36 |
+
try:
|
37 |
+
trainer.train()
|
38 |
+
except Exception as e:
|
39 |
+
print(f'Expected exception caught: {e}')
|
40 |
+
return
|
41 |
+
|
42 |
+
Exception('Resume test failed!')
|
43 |
+
|
44 |
+
|
45 |
+
def test_segment():
|
46 |
+
overrides = {'data': 'coco8-seg.yaml', 'model': CFG_SEG, 'imgsz': 32, 'epochs': 1, 'save': False}
|
47 |
+
CFG.data = 'coco8-seg.yaml'
|
48 |
+
CFG.v5loader = False
|
49 |
+
# YOLO(CFG_SEG).train(**overrides) # works
|
50 |
+
|
51 |
+
# trainer
|
52 |
+
trainer = segment.SegmentationTrainer(overrides=overrides)
|
53 |
+
trainer.train()
|
54 |
+
|
55 |
+
# Validator
|
56 |
+
val = segment.SegmentationValidator(args=CFG)
|
57 |
+
val(model=trainer.best) # validate best.pt
|
58 |
+
|
59 |
+
# Predictor
|
60 |
+
pred = segment.SegmentationPredictor(overrides={'imgsz': [64, 64]})
|
61 |
+
result = pred(source=SOURCE, model=f'{MODEL}-seg.pt')
|
62 |
+
assert len(result), 'predictor test failed'
|
63 |
+
|
64 |
+
# Test resume
|
65 |
+
overrides['resume'] = trainer.last
|
66 |
+
trainer = segment.SegmentationTrainer(overrides=overrides)
|
67 |
+
try:
|
68 |
+
trainer.train()
|
69 |
+
except Exception as e:
|
70 |
+
print(f'Expected exception caught: {e}')
|
71 |
+
return
|
72 |
+
|
73 |
+
Exception('Resume test failed!')
|
74 |
+
|
75 |
+
|
76 |
+
def test_classify():
|
77 |
+
overrides = {'data': 'imagenet10', 'model': 'yolov8n-cls.yaml', 'imgsz': 32, 'epochs': 1, 'save': False}
|
78 |
+
CFG.data = 'imagenet10'
|
79 |
+
CFG.imgsz = 32
|
80 |
+
# YOLO(CFG_SEG).train(**overrides) # works
|
81 |
+
|
82 |
+
# Trainer
|
83 |
+
trainer = classify.ClassificationTrainer(overrides=overrides)
|
84 |
+
trainer.train()
|
85 |
+
|
86 |
+
# Validator
|
87 |
+
val = classify.ClassificationValidator(args=CFG)
|
88 |
+
val(model=trainer.best)
|
89 |
+
|
90 |
+
# Predictor
|
91 |
+
pred = classify.ClassificationPredictor(overrides={'imgsz': [64, 64]})
|
92 |
+
result = pred(source=SOURCE, model=trainer.best)
|
93 |
+
assert len(result), 'predictor test failed'
|
tests/test_python.py
ADDED
@@ -0,0 +1,222 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# Ultralytics YOLO 🚀, GPL-3.0 license
|
2 |
+
|
3 |
+
from pathlib import Path
|
4 |
+
|
5 |
+
import cv2
|
6 |
+
import numpy as np
|
7 |
+
import torch
|
8 |
+
from PIL import Image
|
9 |
+
|
10 |
+
from ultralytics import YOLO
|
11 |
+
from ultralytics.yolo.data.build import load_inference_source
|
12 |
+
from ultralytics.yolo.utils import LINUX, ONLINE, ROOT, SETTINGS
|
13 |
+
|
14 |
+
MODEL = Path(SETTINGS['weights_dir']) / 'yolov8n.pt'
|
15 |
+
CFG = 'yolov8n.yaml'
|
16 |
+
SOURCE = ROOT / 'assets/bus.jpg'
|
17 |
+
SOURCE_GREYSCALE = Path(f'{SOURCE.parent / SOURCE.stem}_greyscale.jpg')
|
18 |
+
SOURCE_RGBA = Path(f'{SOURCE.parent / SOURCE.stem}_4ch.png')
|
19 |
+
|
20 |
+
# Convert SOURCE to greyscale and 4-ch
|
21 |
+
im = Image.open(SOURCE)
|
22 |
+
im.convert('L').save(SOURCE_GREYSCALE) # greyscale
|
23 |
+
im.convert('RGBA').save(SOURCE_RGBA) # 4-ch PNG with alpha
|
24 |
+
|
25 |
+
|
26 |
+
def test_model_forward():
|
27 |
+
model = YOLO(CFG)
|
28 |
+
model(SOURCE)
|
29 |
+
|
30 |
+
|
31 |
+
def test_model_info():
|
32 |
+
model = YOLO(CFG)
|
33 |
+
model.info()
|
34 |
+
model = YOLO(MODEL)
|
35 |
+
model.info(verbose=True)
|
36 |
+
|
37 |
+
|
38 |
+
def test_model_fuse():
|
39 |
+
model = YOLO(CFG)
|
40 |
+
model.fuse()
|
41 |
+
model = YOLO(MODEL)
|
42 |
+
model.fuse()
|
43 |
+
|
44 |
+
|
45 |
+
def test_predict_dir():
|
46 |
+
model = YOLO(MODEL)
|
47 |
+
model(source=ROOT / 'assets')
|
48 |
+
|
49 |
+
|
50 |
+
def test_predict_img():
|
51 |
+
model = YOLO(MODEL)
|
52 |
+
seg_model = YOLO('yolov8n-seg.pt')
|
53 |
+
cls_model = YOLO('yolov8n-cls.pt')
|
54 |
+
im = cv2.imread(str(SOURCE))
|
55 |
+
assert len(model(source=Image.open(SOURCE), save=True, verbose=True)) == 1 # PIL
|
56 |
+
assert len(model(source=im, save=True, save_txt=True)) == 1 # ndarray
|
57 |
+
assert len(model(source=[im, im], save=True, save_txt=True)) == 2 # batch
|
58 |
+
assert len(list(model(source=[im, im], save=True, stream=True))) == 2 # stream
|
59 |
+
assert len(model(torch.zeros(320, 640, 3).numpy())) == 1 # tensor to numpy
|
60 |
+
batch = [
|
61 |
+
str(SOURCE), # filename
|
62 |
+
Path(SOURCE), # Path
|
63 |
+
'https://ultralytics.com/images/zidane.jpg' if ONLINE else SOURCE, # URI
|
64 |
+
cv2.imread(str(SOURCE)), # OpenCV
|
65 |
+
Image.open(SOURCE), # PIL
|
66 |
+
np.zeros((320, 640, 3))] # numpy
|
67 |
+
assert len(model(batch)) == len(batch) # multiple sources in a batch
|
68 |
+
|
69 |
+
# Test tensor inference
|
70 |
+
im = cv2.imread(str(SOURCE)) # OpenCV
|
71 |
+
t = cv2.resize(im, (32, 32))
|
72 |
+
t = torch.from_numpy(t.transpose((2, 0, 1)))
|
73 |
+
t = torch.stack([t, t, t, t])
|
74 |
+
results = model(t)
|
75 |
+
assert len(results) == t.shape[0]
|
76 |
+
results = seg_model(t)
|
77 |
+
assert len(results) == t.shape[0]
|
78 |
+
results = cls_model(t)
|
79 |
+
assert len(results) == t.shape[0]
|
80 |
+
|
81 |
+
|
82 |
+
def test_predict_grey_and_4ch():
|
83 |
+
model = YOLO(MODEL)
|
84 |
+
for f in SOURCE_RGBA, SOURCE_GREYSCALE:
|
85 |
+
for source in Image.open(f), cv2.imread(str(f)), f:
|
86 |
+
model(source, save=True, verbose=True)
|
87 |
+
|
88 |
+
|
89 |
+
def test_val():
|
90 |
+
model = YOLO(MODEL)
|
91 |
+
model.val(data='coco8.yaml', imgsz=32)
|
92 |
+
|
93 |
+
|
94 |
+
def test_val_scratch():
|
95 |
+
model = YOLO(CFG)
|
96 |
+
model.val(data='coco8.yaml', imgsz=32)
|
97 |
+
|
98 |
+
|
99 |
+
def test_amp():
|
100 |
+
if torch.cuda.is_available():
|
101 |
+
from ultralytics.yolo.engine.trainer import check_amp
|
102 |
+
model = YOLO(MODEL).model.cuda()
|
103 |
+
assert check_amp(model)
|
104 |
+
|
105 |
+
|
106 |
+
def test_train_scratch():
|
107 |
+
model = YOLO(CFG)
|
108 |
+
model.train(data='coco8.yaml', epochs=1, imgsz=32)
|
109 |
+
model(SOURCE)
|
110 |
+
|
111 |
+
|
112 |
+
def test_train_pretrained():
|
113 |
+
model = YOLO(MODEL)
|
114 |
+
model.train(data='coco8.yaml', epochs=1, imgsz=32)
|
115 |
+
model(SOURCE)
|
116 |
+
|
117 |
+
|
118 |
+
def test_export_torchscript():
|
119 |
+
model = YOLO(MODEL)
|
120 |
+
f = model.export(format='torchscript')
|
121 |
+
YOLO(f)(SOURCE) # exported model inference
|
122 |
+
|
123 |
+
|
124 |
+
def test_export_torchscript_scratch():
|
125 |
+
model = YOLO(CFG)
|
126 |
+
f = model.export(format='torchscript')
|
127 |
+
YOLO(f)(SOURCE) # exported model inference
|
128 |
+
|
129 |
+
|
130 |
+
def test_export_onnx():
|
131 |
+
model = YOLO(MODEL)
|
132 |
+
f = model.export(format='onnx')
|
133 |
+
YOLO(f)(SOURCE) # exported model inference
|
134 |
+
|
135 |
+
|
136 |
+
def test_export_openvino():
|
137 |
+
model = YOLO(MODEL)
|
138 |
+
f = model.export(format='openvino')
|
139 |
+
YOLO(f)(SOURCE) # exported model inference
|
140 |
+
|
141 |
+
|
142 |
+
def test_export_coreml(): # sourcery skip: move-assign
|
143 |
+
model = YOLO(MODEL)
|
144 |
+
model.export(format='coreml')
|
145 |
+
# if MACOS:
|
146 |
+
# YOLO(f)(SOURCE) # model prediction only supported on macOS
|
147 |
+
|
148 |
+
|
149 |
+
def test_export_tflite(enabled=False):
|
150 |
+
# TF suffers from install conflicts on Windows and macOS
|
151 |
+
if enabled and LINUX:
|
152 |
+
model = YOLO(MODEL)
|
153 |
+
f = model.export(format='tflite')
|
154 |
+
YOLO(f)(SOURCE)
|
155 |
+
|
156 |
+
|
157 |
+
def test_export_pb(enabled=False):
|
158 |
+
# TF suffers from install conflicts on Windows and macOS
|
159 |
+
if enabled and LINUX:
|
160 |
+
model = YOLO(MODEL)
|
161 |
+
f = model.export(format='pb')
|
162 |
+
YOLO(f)(SOURCE)
|
163 |
+
|
164 |
+
|
165 |
+
def test_export_paddle(enabled=False):
|
166 |
+
# Paddle protobuf requirements conflicting with onnx protobuf requirements
|
167 |
+
if enabled:
|
168 |
+
model = YOLO(MODEL)
|
169 |
+
model.export(format='paddle')
|
170 |
+
|
171 |
+
|
172 |
+
def test_all_model_yamls():
|
173 |
+
for m in list((ROOT / 'models').rglob('*.yaml')):
|
174 |
+
YOLO(m.name)
|
175 |
+
|
176 |
+
|
177 |
+
def test_workflow():
|
178 |
+
model = YOLO(MODEL)
|
179 |
+
model.train(data='coco8.yaml', epochs=1, imgsz=32)
|
180 |
+
model.val()
|
181 |
+
model.predict(SOURCE)
|
182 |
+
model.export(format='onnx') # export a model to ONNX format
|
183 |
+
|
184 |
+
|
185 |
+
def test_predict_callback_and_setup():
|
186 |
+
# test callback addition for prediction
|
187 |
+
def on_predict_batch_end(predictor): # results -> List[batch_size]
|
188 |
+
path, _, im0s, _, _ = predictor.batch
|
189 |
+
# print('on_predict_batch_end', im0s[0].shape)
|
190 |
+
im0s = im0s if isinstance(im0s, list) else [im0s]
|
191 |
+
bs = [predictor.dataset.bs for _ in range(len(path))]
|
192 |
+
predictor.results = zip(predictor.results, im0s, bs)
|
193 |
+
|
194 |
+
model = YOLO(MODEL)
|
195 |
+
model.add_callback('on_predict_batch_end', on_predict_batch_end)
|
196 |
+
|
197 |
+
dataset = load_inference_source(source=SOURCE, transforms=model.transforms)
|
198 |
+
bs = dataset.bs # noqa access predictor properties
|
199 |
+
results = model.predict(dataset, stream=True) # source already setup
|
200 |
+
for _, (result, im0, bs) in enumerate(results):
|
201 |
+
print('test_callback', im0.shape)
|
202 |
+
print('test_callback', bs)
|
203 |
+
boxes = result.boxes # Boxes object for bbox outputs
|
204 |
+
print(boxes)
|
205 |
+
|
206 |
+
|
207 |
+
def test_result():
|
208 |
+
model = YOLO('yolov8n-seg.pt')
|
209 |
+
res = model([SOURCE, SOURCE])
|
210 |
+
res[0].plot(show_conf=False)
|
211 |
+
res[0] = res[0].cpu().numpy()
|
212 |
+
print(res[0].path, res[0].masks.masks)
|
213 |
+
|
214 |
+
model = YOLO('yolov8n.pt')
|
215 |
+
res = model(SOURCE)
|
216 |
+
res[0].plot()
|
217 |
+
print(res[0].path)
|
218 |
+
|
219 |
+
model = YOLO('yolov8n-cls.pt')
|
220 |
+
res = model(SOURCE)
|
221 |
+
res[0].plot()
|
222 |
+
print(res[0].path)
|
train/result/F1_curve.png
ADDED
![]() |
train/result/PR_curve.png
ADDED
![]() |
train/result/P_curve.png
ADDED
![]() |
train/result/R_curve.png
ADDED
![]() |
train/result/best.pt
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:4e83f02d6ca8848205da96f4f9b2f6ae828be81b04b3f85dcbe1aeb7aaeb92bc
|
3 |
+
size 22568291
|
train/result/confusion_matrix.png
ADDED
![]() |
train/result/events.out.tfevents.1703117386.69c6eee73c8d.3549.0
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:a27ee90f4ada28008b97d7d4083116bd94ff86aa9d6cedfe85ae0a9a82a0ef37
|
3 |
+
size 1321836
|
train/result/results.csv
ADDED
@@ -0,0 +1,51 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
epoch, train/box_loss, train/cls_loss, train/dfl_loss, metrics/precision(B), metrics/recall(B), metrics/mAP50(B), metrics/mAP50-95(B), val/box_loss, val/cls_loss, val/dfl_loss, lr/pg0, lr/pg1, lr/pg2
|
2 |
+
0, 1.3943, 5.3965, 1.7656, 0.52008, 0.29315, 0.35115, 0.23941, 1.2228, 2.5211, 1.7095, 0.07018, 0.0033134, 0.0033134
|
3 |
+
1, 1.0957, 2.3879, 1.425, 0.67407, 0.66647, 0.76456, 0.57626, 1.0231, 1.4538, 1.5037, 0.040048, 0.0065151, 0.0065151
|
4 |
+
2, 1.0909, 1.854, 1.3809, 0.76436, 0.63647, 0.74185, 0.53108, 1.117, 1.6168, 1.6028, 0.0097844, 0.0095848, 0.0095848
|
5 |
+
3, 1.139, 1.6765, 1.4237, 0.67585, 0.74256, 0.77575, 0.55398, 1.1557, 1.5061, 1.5957, 0.009406, 0.009406, 0.009406
|
6 |
+
4, 1.1085, 1.5045, 1.385, 0.84713, 0.7969, 0.8784, 0.65151, 1.0578, 1.0557, 1.5447, 0.009406, 0.009406, 0.009406
|
7 |
+
5, 1.068, 1.3402, 1.3493, 0.87581, 0.75073, 0.85493, 0.65046, 1.01, 1.1246, 1.5047, 0.009208, 0.009208, 0.009208
|
8 |
+
6, 1.0475, 1.2473, 1.3379, 0.90986, 0.852, 0.93209, 0.70152, 0.97208, 0.87563, 1.4116, 0.00901, 0.00901, 0.00901
|
9 |
+
7, 1.0083, 1.1668, 1.3092, 0.91183, 0.81664, 0.92471, 0.68771, 0.99811, 0.89281, 1.4867, 0.008812, 0.008812, 0.008812
|
10 |
+
8, 0.97265, 1.0787, 1.27, 0.85922, 0.81718, 0.9133, 0.68808, 0.97119, 0.91105, 1.4201, 0.008614, 0.008614, 0.008614
|
11 |
+
9, 0.9359, 1.0149, 1.2475, 0.92773, 0.93911, 0.9804, 0.76781, 0.82578, 0.67889, 1.3124, 0.008416, 0.008416, 0.008416
|
12 |
+
10, 0.92692, 0.99297, 1.2458, 0.94159, 0.89818, 0.97481, 0.75688, 0.87143, 0.6741, 1.3353, 0.008218, 0.008218, 0.008218
|
13 |
+
11, 0.91531, 0.92136, 1.2292, 0.93804, 0.91749, 0.97578, 0.77347, 0.83713, 0.63057, 1.2873, 0.00802, 0.00802, 0.00802
|
14 |
+
12, 0.90491, 0.91221, 1.2346, 0.93929, 0.90441, 0.97159, 0.75345, 0.87527, 0.64437, 1.3628, 0.007822, 0.007822, 0.007822
|
15 |
+
13, 0.88162, 0.90044, 1.2238, 0.93827, 0.92706, 0.97901, 0.77037, 0.8561, 0.59532, 1.3175, 0.007624, 0.007624, 0.007624
|
16 |
+
14, 0.86089, 0.845, 1.2, 0.94078, 0.90385, 0.97265, 0.76704, 0.83484, 0.59525, 1.3135, 0.007426, 0.007426, 0.007426
|
17 |
+
15, 0.84251, 0.79662, 1.1836, 0.95938, 0.93805, 0.98763, 0.79348, 0.79267, 0.52314, 1.2832, 0.007228, 0.007228, 0.007228
|
18 |
+
16, 0.83622, 0.79077, 1.1887, 0.94655, 0.92611, 0.9792, 0.79344, 0.78439, 0.52228, 1.269, 0.00703, 0.00703, 0.00703
|
19 |
+
17, 0.8243, 0.77297, 1.1704, 0.96865, 0.95038, 0.98743, 0.79909, 0.77058, 0.49297, 1.2646, 0.006832, 0.006832, 0.006832
|
20 |
+
18, 0.81351, 0.74555, 1.1677, 0.93462, 0.94813, 0.97801, 0.7942, 0.76714, 0.53705, 1.2401, 0.006634, 0.006634, 0.006634
|
21 |
+
19, 0.78967, 0.71817, 1.1456, 0.95858, 0.95986, 0.98414, 0.80379, 0.75204, 0.47804, 1.2391, 0.006436, 0.006436, 0.006436
|
22 |
+
20, 0.77246, 0.70666, 1.1409, 0.96397, 0.93831, 0.98219, 0.7984, 0.75419, 0.50211, 1.2527, 0.006238, 0.006238, 0.006238
|
23 |
+
21, 0.77247, 0.70521, 1.1468, 0.97088, 0.95931, 0.98769, 0.80524, 0.74903, 0.46267, 1.2429, 0.00604, 0.00604, 0.00604
|
24 |
+
22, 0.74288, 0.6583, 1.1203, 0.94444, 0.98033, 0.99014, 0.8154, 0.72644, 0.44399, 1.2342, 0.005842, 0.005842, 0.005842
|
25 |
+
23, 0.75258, 0.65464, 1.1312, 0.95997, 0.96409, 0.98626, 0.81721, 0.71529, 0.45629, 1.2058, 0.005644, 0.005644, 0.005644
|
26 |
+
24, 0.74541, 0.63347, 1.129, 0.97377, 0.97256, 0.98718, 0.82631, 0.70684, 0.44788, 1.1952, 0.005446, 0.005446, 0.005446
|
27 |
+
25, 0.72792, 0.62454, 1.1118, 0.97493, 0.9797, 0.99013, 0.8349, 0.68843, 0.41908, 1.1934, 0.005248, 0.005248, 0.005248
|
28 |
+
26, 0.70686, 0.58767, 1.1022, 0.96681, 0.97581, 0.98858, 0.81522, 0.73092, 0.42983, 1.2235, 0.00505, 0.00505, 0.00505
|
29 |
+
27, 0.70378, 0.5787, 1.1033, 0.97741, 0.97201, 0.98914, 0.83059, 0.70443, 0.4094, 1.2259, 0.004852, 0.004852, 0.004852
|
30 |
+
28, 0.69172, 0.56769, 1.0945, 0.97356, 0.97641, 0.98421, 0.8305, 0.68605, 0.39824, 1.2049, 0.004654, 0.004654, 0.004654
|
31 |
+
29, 0.68151, 0.56353, 1.0906, 0.96161, 0.97742, 0.98511, 0.82967, 0.68371, 0.40559, 1.1874, 0.004456, 0.004456, 0.004456
|
32 |
+
30, 0.68021, 0.55879, 1.0929, 0.97889, 0.98372, 0.98785, 0.83714, 0.668, 0.37307, 1.1832, 0.004258, 0.004258, 0.004258
|
33 |
+
31, 0.66176, 0.54269, 1.0707, 0.9674, 0.98919, 0.98956, 0.84952, 0.66505, 0.38466, 1.1738, 0.00406, 0.00406, 0.00406
|
34 |
+
32, 0.65861, 0.52677, 1.0774, 0.97646, 0.98601, 0.99199, 0.84259, 0.67371, 0.37715, 1.1801, 0.003862, 0.003862, 0.003862
|
35 |
+
33, 0.65137, 0.52748, 1.0773, 0.97669, 0.98341, 0.98851, 0.83893, 0.67566, 0.37633, 1.1854, 0.003664, 0.003664, 0.003664
|
36 |
+
34, 0.64541, 0.50415, 1.0702, 0.98119, 0.99023, 0.99127, 0.84832, 0.66121, 0.3737, 1.1784, 0.003466, 0.003466, 0.003466
|
37 |
+
35, 0.62748, 0.49499, 1.0638, 0.97031, 0.98634, 0.99042, 0.84376, 0.65157, 0.35552, 1.1639, 0.003268, 0.003268, 0.003268
|
38 |
+
36, 0.63135, 0.48207, 1.064, 0.97523, 0.98614, 0.98985, 0.84671, 0.65972, 0.36057, 1.1783, 0.00307, 0.00307, 0.00307
|
39 |
+
37, 0.61064, 0.4718, 1.0482, 0.98072, 0.98071, 0.99109, 0.85346, 0.64444, 0.34325, 1.1588, 0.002872, 0.002872, 0.002872
|
40 |
+
38, 0.61294, 0.46575, 1.0534, 0.97902, 0.98661, 0.99173, 0.85542, 0.64202, 0.34811, 1.1502, 0.002674, 0.002674, 0.002674
|
41 |
+
39, 0.59466, 0.44286, 1.0405, 0.9765, 0.98751, 0.99189, 0.85487, 0.64831, 0.34407, 1.1564, 0.002476, 0.002476, 0.002476
|
42 |
+
40, 0.52085, 0.31875, 1.0323, 0.97859, 0.99306, 0.99165, 0.85463, 0.64686, 0.33968, 1.1779, 0.002278, 0.002278, 0.002278
|
43 |
+
41, 0.50485, 0.30879, 1.0087, 0.97876, 0.98606, 0.99188, 0.86257, 0.62123, 0.33428, 1.156, 0.00208, 0.00208, 0.00208
|
44 |
+
42, 0.49148, 0.29756, 1.0017, 0.98101, 0.97505, 0.99248, 0.8608, 0.62874, 0.32825, 1.1479, 0.001882, 0.001882, 0.001882
|
45 |
+
43, 0.48247, 0.29054, 0.99939, 0.98812, 0.98166, 0.9922, 0.86423, 0.62497, 0.32037, 1.1494, 0.001684, 0.001684, 0.001684
|
46 |
+
44, 0.47167, 0.28362, 0.98868, 0.98411, 0.97913, 0.98948, 0.86945, 0.61179, 0.32392, 1.1534, 0.001486, 0.001486, 0.001486
|
47 |
+
45, 0.45215, 0.2727, 0.9841, 0.98521, 0.98055, 0.99179, 0.86415, 0.61675, 0.31416, 1.1466, 0.001288, 0.001288, 0.001288
|
48 |
+
46, 0.44647, 0.26576, 0.96937, 0.98348, 0.98055, 0.99161, 0.86787, 0.60871, 0.30391, 1.1544, 0.00109, 0.00109, 0.00109
|
49 |
+
47, 0.43148, 0.25571, 0.96668, 0.98864, 0.98048, 0.99181, 0.86828, 0.59663, 0.30073, 1.1472, 0.000892, 0.000892, 0.000892
|
50 |
+
48, 0.4194, 0.24958, 0.95462, 0.98468, 0.97979, 0.99169, 0.87124, 0.6007, 0.30279, 1.1365, 0.000694, 0.000694, 0.000694
|
51 |
+
49, 0.40691, 0.24267, 0.94509, 0.98899, 0.98105, 0.99192, 0.86847, 0.5956, 0.29325, 1.1394, 0.000496, 0.000496, 0.000496
|
train/result/results.png
ADDED
![]() |
train/result/train_batch0.jpg
ADDED
![]() |
train/result/train_batch1.jpg
ADDED
![]() |
train/result/train_batch2.jpg
ADDED
![]() |
train/result/train_batch6680.jpg
ADDED
![]() |
train/result/train_batch6681.jpg
ADDED
![]() |
train/result/train_batch6682.jpg
ADDED
![]() |
train/result/val_batch0_labels.jpg
ADDED
![]() |
train/result/val_batch0_pred.jpg
ADDED
![]() |
train/result/val_batch1_labels.jpg
ADDED
![]() |
train/result/val_batch1_pred.jpg
ADDED
![]() |
train/result/val_batch2_labels.jpg
ADDED
![]() |
train/result/val_batch2_pred.jpg
ADDED
![]() |
train/train_model.ipynb
ADDED
@@ -0,0 +1,928 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"cells": [
|
3 |
+
{
|
4 |
+
"cell_type": "markdown",
|
5 |
+
"metadata": {
|
6 |
+
"id": "FyRdDYkqAKN4"
|
7 |
+
},
|
8 |
+
"source": [
|
9 |
+
"# BISINDO Sign Language Translator"
|
10 |
+
]
|
11 |
+
},
|
12 |
+
{
|
13 |
+
"cell_type": "markdown",
|
14 |
+
"metadata": {},
|
15 |
+
"source": [
|
16 |
+
"## Description\n",
|
17 |
+
"\n",
|
18 |
+
"This project is a final project for \"Rekayasa Sistem Berbasis Pengetahuan (RSBP)\". This project is a web-based application that can translate BISINDO sign language to Indonesian language. This application is made to help people who are not familiar with BISINDO sign language to communicate with people who are deaf. </br>\n",
|
19 |
+
"\n",
|
20 |
+
"## Appoarch Method\n",
|
21 |
+
"\n",
|
22 |
+
"This project employs the Object Detection method to identify hand gestures, utilizing a customized YOLO v8 dataset model. This model is designed to detect various hand gestures and provide the bounding box coordinates delineating these gestures. Once the bounding box is identified, the corresponding region of interest (ROI) containing the hand gesture is cropped. Subsequently, this cropped image undergoes further processing through a Convolutional Neural Network (CNN) model for precise classification of the detected hand gesture. The CNN model's output yields the specific label corresponding to the gesture identified. To enhance user experience, these labels are translated into Indonesian using a Rule-Based method before being displayed on the screen interface. </br>\n",
|
23 |
+
"\n",
|
24 |
+
"In terms of visualization, the project harnesses MediaPipe, a tool enabling the drawing of hand gesture bounding boxes and their associated labels directly on the screen. This integration ensures users can visually comprehend the detected gestures in real-time with graphical representations. </br>\n",
|
25 |
+
"\n",
|
26 |
+
"Moreover, the project is built as a web-based application using Flask, allowing seamless accessibility and interaction through a web interface. This framework facilitates the deployment of the hand gesture detection system within a browser, ensuring ease of use across various devices without necessitating complex setups or installations. </br>\n",
|
27 |
+
"\n",
|
28 |
+
"## Visual Demo\n",
|
29 |
+
"\n",
|
30 |
+
"### Dashboard\n",
|
31 |
+
"</br>\n",
|
32 |
+
"\n",
|
33 |
+
"### Stream Youtube Detection\n",
|
34 |
+
"</br>\n",
|
35 |
+
"\n",
|
36 |
+
"### Camera Detection\n",
|
37 |
+
"</br>\n",
|
38 |
+
"\n",
|
39 |
+
"## Step by Step Method\n",
|
40 |
+
"- Train the model using YOLOv8 with custom dataset\n",
|
41 |
+
"- Create a CNN model to classify the cropped image\n",
|
42 |
+
"- Create a Flask app to run the model\n",
|
43 |
+
"- Create a web interface using HTML and CSS\n",
|
44 |
+
"- Create feature interaction using Javascript \n",
|
45 |
+
"\n",
|
46 |
+
"## Features\n",
|
47 |
+
"- Detect hand gesture from Camera\n",
|
48 |
+
"- Detect hand gesture from Youtube video\n",
|
49 |
+
"- Switch on/off the detection\n",
|
50 |
+
"- Switch on/off the landmark\n",
|
51 |
+
"- Flip the video\n",
|
52 |
+
"- Modify Confidence Threshold\n",
|
53 |
+
"- The result accumulates the detected words over 10 sequential frames"
|
54 |
+
]
|
55 |
+
},
|
56 |
+
{
|
57 |
+
"cell_type": "markdown",
|
58 |
+
"metadata": {},
|
59 |
+
"source": [
|
60 |
+
"# Training Model"
|
61 |
+
]
|
62 |
+
},
|
63 |
+
{
|
64 |
+
"cell_type": "markdown",
|
65 |
+
"metadata": {},
|
66 |
+
"source": [
|
67 |
+
"### Check GPU"
|
68 |
+
]
|
69 |
+
},
|
70 |
+
{
|
71 |
+
"cell_type": "code",
|
72 |
+
"execution_count": null,
|
73 |
+
"metadata": {
|
74 |
+
"colab": {
|
75 |
+
"base_uri": "https://localhost:8080/"
|
76 |
+
},
|
77 |
+
"id": "Y8cDtxLIBHgQ",
|
78 |
+
"outputId": "d2185ab5-0f43-47b6-b675-937ee56331d5"
|
79 |
+
},
|
80 |
+
"outputs": [],
|
81 |
+
"source": [
|
82 |
+
"!nvidia-smi"
|
83 |
+
]
|
84 |
+
},
|
85 |
+
{
|
86 |
+
"cell_type": "markdown",
|
87 |
+
"metadata": {},
|
88 |
+
"source": [
|
89 |
+
"### Import OS"
|
90 |
+
]
|
91 |
+
},
|
92 |
+
{
|
93 |
+
"cell_type": "code",
|
94 |
+
"execution_count": null,
|
95 |
+
"metadata": {
|
96 |
+
"colab": {
|
97 |
+
"base_uri": "https://localhost:8080/"
|
98 |
+
},
|
99 |
+
"id": "CjpPg4mGKc1v",
|
100 |
+
"outputId": "c0bb0d9a-2cd3-4bea-d38a-070b74a5a89b"
|
101 |
+
},
|
102 |
+
"outputs": [],
|
103 |
+
"source": [
|
104 |
+
"import os\n",
|
105 |
+
"HOME = os.getcwd()\n",
|
106 |
+
"print(HOME)"
|
107 |
+
]
|
108 |
+
},
|
109 |
+
{
|
110 |
+
"cell_type": "markdown",
|
111 |
+
"metadata": {
|
112 |
+
"id": "3C3EO_2zNChu"
|
113 |
+
},
|
114 |
+
"source": [
|
115 |
+
"### Yolo Instalation"
|
116 |
+
]
|
117 |
+
},
|
118 |
+
{
|
119 |
+
"cell_type": "code",
|
120 |
+
"execution_count": null,
|
121 |
+
"metadata": {
|
122 |
+
"colab": {
|
123 |
+
"base_uri": "https://localhost:8080/"
|
124 |
+
},
|
125 |
+
"id": "tdSMcABDNKW-",
|
126 |
+
"outputId": "6193e25a-2cfd-4d96-fe9f-769add6166f7"
|
127 |
+
},
|
128 |
+
"outputs": [],
|
129 |
+
"source": [
|
130 |
+
"%pip install ultralytics==8.0.20\n",
|
131 |
+
"\n",
|
132 |
+
"from IPython import display\n",
|
133 |
+
"display.clear_output()\n",
|
134 |
+
"\n",
|
135 |
+
"import ultralytics\n",
|
136 |
+
"ultralytics.checks()"
|
137 |
+
]
|
138 |
+
},
|
139 |
+
{
|
140 |
+
"cell_type": "code",
|
141 |
+
"execution_count": 4,
|
142 |
+
"metadata": {
|
143 |
+
"id": "VOEYrlBoP9-E"
|
144 |
+
},
|
145 |
+
"outputs": [],
|
146 |
+
"source": [
|
147 |
+
"from ultralytics import YOLO\n",
|
148 |
+
"\n",
|
149 |
+
"from IPython.display import display, Image"
|
150 |
+
]
|
151 |
+
},
|
152 |
+
{
|
153 |
+
"cell_type": "markdown",
|
154 |
+
"metadata": {
|
155 |
+
"id": "fT1qD4toTTw0"
|
156 |
+
},
|
157 |
+
"source": [
|
158 |
+
"### Import Dataset Form Roboflow"
|
159 |
+
]
|
160 |
+
},
|
161 |
+
{
|
162 |
+
"cell_type": "code",
|
163 |
+
"execution_count": null,
|
164 |
+
"metadata": {
|
165 |
+
"colab": {
|
166 |
+
"base_uri": "https://localhost:8080/"
|
167 |
+
},
|
168 |
+
"id": "BSd93ZJzZZKt",
|
169 |
+
"outputId": "eb8bcd99-cea8-48a1-bf11-7a37f2aa7018"
|
170 |
+
},
|
171 |
+
"outputs": [],
|
172 |
+
"source": [
|
173 |
+
"%mkdir {HOME}/datasets\n",
|
174 |
+
"%cd {HOME}/datasets\n",
|
175 |
+
"\n",
|
176 |
+
"%pip install roboflow --quiet\n",
|
177 |
+
"\n",
|
178 |
+
"from roboflow import Roboflow\n",
|
179 |
+
"\n",
|
180 |
+
"from roboflow import Roboflow\n",
|
181 |
+
"rf = Roboflow(api_key=\"moOAxzoPZOtIzhyyco0r\")\n",
|
182 |
+
"project = rf.workspace(\"bisindo-qndjb\").project(\"bisindov2\")\n",
|
183 |
+
"dataset = project.version(1).download(\"yolov8\")"
|
184 |
+
]
|
185 |
+
},
|
186 |
+
{
|
187 |
+
"cell_type": "markdown",
|
188 |
+
"metadata": {
|
189 |
+
"id": "YUjFBKKqXa-u"
|
190 |
+
},
|
191 |
+
"source": [
|
192 |
+
"### Training"
|
193 |
+
]
|
194 |
+
},
|
195 |
+
{
|
196 |
+
"cell_type": "code",
|
197 |
+
"execution_count": null,
|
198 |
+
"metadata": {
|
199 |
+
"colab": {
|
200 |
+
"base_uri": "https://localhost:8080/"
|
201 |
+
},
|
202 |
+
"id": "D2YkphuiaE7_",
|
203 |
+
"outputId": "7f5ea4f9-6e7d-4470-8209-9a253786cd13"
|
204 |
+
},
|
205 |
+
"outputs": [],
|
206 |
+
"source": [
|
207 |
+
"%cd {HOME}\n",
|
208 |
+
"\n",
|
209 |
+
"yolo task=detect mode=train model=yolov8s.pt data={dataset.location}/data.yaml epochs=25 imgsz=800 plots=True"
|
210 |
+
]
|
211 |
+
},
|
212 |
+
{
|
213 |
+
"cell_type": "code",
|
214 |
+
"execution_count": null,
|
215 |
+
"metadata": {
|
216 |
+
"colab": {
|
217 |
+
"base_uri": "https://localhost:8080/"
|
218 |
+
},
|
219 |
+
"id": "1MScstfHhArr",
|
220 |
+
"outputId": "7865d222-af3a-49bd-9aa7-3816872815c9"
|
221 |
+
},
|
222 |
+
"outputs": [],
|
223 |
+
"source": [
|
224 |
+
"%ls {HOME}/runs/detect/train/"
|
225 |
+
]
|
226 |
+
},
|
227 |
+
{
|
228 |
+
"cell_type": "code",
|
229 |
+
"execution_count": null,
|
230 |
+
"metadata": {
|
231 |
+
"colab": {
|
232 |
+
"base_uri": "https://localhost:8080/",
|
233 |
+
"height": 485
|
234 |
+
},
|
235 |
+
"id": "_J35i8Ofhjxa",
|
236 |
+
"outputId": "762ae444-f7c9-42f5-cd2c-8ea7facee223"
|
237 |
+
},
|
238 |
+
"outputs": [],
|
239 |
+
"source": [
|
240 |
+
"%cd {HOME}\n",
|
241 |
+
"Image(filename=f'{HOME}/runs/detect/train/confusion_matrix.png', width=600)"
|
242 |
+
]
|
243 |
+
},
|
244 |
+
{
|
245 |
+
"cell_type": "code",
|
246 |
+
"execution_count": null,
|
247 |
+
"metadata": {
|
248 |
+
"colab": {
|
249 |
+
"base_uri": "https://localhost:8080/",
|
250 |
+
"height": 335
|
251 |
+
},
|
252 |
+
"id": "A-urTWUkhRmn",
|
253 |
+
"outputId": "58b67f20-8844-43f4-ff41-c8c498036fc8"
|
254 |
+
},
|
255 |
+
"outputs": [],
|
256 |
+
"source": [
|
257 |
+
"%cd {HOME}\n",
|
258 |
+
"Image(filename=f'{HOME}/runs/detect/train/results.png', width=600)"
|
259 |
+
]
|
260 |
+
},
|
261 |
+
{
|
262 |
+
"cell_type": "markdown",
|
263 |
+
"metadata": {
|
264 |
+
"id": "6ODk1VTlevxn"
|
265 |
+
},
|
266 |
+
"source": [
|
267 |
+
"### Validate Model"
|
268 |
+
]
|
269 |
+
},
|
270 |
+
{
|
271 |
+
"cell_type": "code",
|
272 |
+
"execution_count": null,
|
273 |
+
"metadata": {
|
274 |
+
"colab": {
|
275 |
+
"base_uri": "https://localhost:8080/"
|
276 |
+
},
|
277 |
+
"id": "YpyuwrNlXc1P",
|
278 |
+
"outputId": "88f5e42d-e10d-45db-c578-7c85f8667c10"
|
279 |
+
},
|
280 |
+
"outputs": [],
|
281 |
+
"source": [
|
282 |
+
"%cd {HOME}\n",
|
283 |
+
"\n",
|
284 |
+
"!yolo task=detect mode=val model={HOME}/runs/detect/train/weights/best.pt data={dataset.location}/data.yaml"
|
285 |
+
]
|
286 |
+
},
|
287 |
+
{
|
288 |
+
"cell_type": "markdown",
|
289 |
+
"metadata": {
|
290 |
+
"id": "i4eASbcWkQBq"
|
291 |
+
},
|
292 |
+
"source": [
|
293 |
+
"### Inference Model"
|
294 |
+
]
|
295 |
+
},
|
296 |
+
{
|
297 |
+
"cell_type": "code",
|
298 |
+
"execution_count": null,
|
299 |
+
"metadata": {
|
300 |
+
"colab": {
|
301 |
+
"base_uri": "https://localhost:8080/"
|
302 |
+
},
|
303 |
+
"id": "Wjc1ctZykYuf",
|
304 |
+
"outputId": "f400774d-404b-4fef-ef58-796fc4fd522e"
|
305 |
+
},
|
306 |
+
"outputs": [],
|
307 |
+
"source": [
|
308 |
+
"%cd {HOME}\n",
|
309 |
+
"!yolo task=detect mode=predict model={HOME}/runs/detect/train/weights/best.pt conf=0.25 source={dataset.location}/test/images save=True"
|
310 |
+
]
|
311 |
+
},
|
312 |
+
{
|
313 |
+
"cell_type": "markdown",
|
314 |
+
"metadata": {
|
315 |
+
"id": "mEYIo95n-I0S"
|
316 |
+
},
|
317 |
+
"source": [
|
318 |
+
"### Run Model on CAMERA"
|
319 |
+
]
|
320 |
+
},
|
321 |
+
{
|
322 |
+
"cell_type": "code",
|
323 |
+
"execution_count": null,
|
324 |
+
"metadata": {
|
325 |
+
"colab": {
|
326 |
+
"base_uri": "https://localhost:8080/"
|
327 |
+
},
|
328 |
+
"id": "As_cl3OkQWQ1",
|
329 |
+
"outputId": "759e88f3-c3b8-474f-d217-35765bd81d06"
|
330 |
+
},
|
331 |
+
"outputs": [],
|
332 |
+
"source": [
|
333 |
+
"%cd {HOME}\n",
|
334 |
+
"!yolo task=detect mode=predict model=D:/Kuliah/\\(2023\\)S5-RSBP/FP/runs/detect/train/weights/best.pt source=0 show=true"
|
335 |
+
]
|
336 |
+
},
|
337 |
+
{
|
338 |
+
"cell_type": "markdown",
|
339 |
+
"metadata": {},
|
340 |
+
"source": [
|
341 |
+
"## Training Result\n",
|
342 |
+
"\n",
|
343 |
+
"### Confussion Matrix\n",
|
344 |
+
"</br>\n",
|
345 |
+
"\n",
|
346 |
+
"### Result Curve\n",
|
347 |
+
"</br>"
|
348 |
+
]
|
349 |
+
},
|
350 |
+
{
|
351 |
+
"cell_type": "markdown",
|
352 |
+
"metadata": {},
|
353 |
+
"source": [
|
354 |
+
"## Create Flask Web Application"
|
355 |
+
]
|
356 |
+
},
|
357 |
+
{
|
358 |
+
"cell_type": "markdown",
|
359 |
+
"metadata": {},
|
360 |
+
"source": [
|
361 |
+
"### Install Requirements Dependencies\n",
|
362 |
+
"To install the Python requirements from the `requirements.txt` file, run the following command in your terminal or command prompt:"
|
363 |
+
]
|
364 |
+
},
|
365 |
+
{
|
366 |
+
"cell_type": "code",
|
367 |
+
"execution_count": null,
|
368 |
+
"metadata": {},
|
369 |
+
"outputs": [],
|
370 |
+
"source": [
|
371 |
+
"pip install -r requirements.txt"
|
372 |
+
]
|
373 |
+
},
|
374 |
+
{
|
375 |
+
"cell_type": "markdown",
|
376 |
+
"metadata": {},
|
377 |
+
"source": [
|
378 |
+
"### Create new app.py file for main program\n",
|
379 |
+
"Import libray that needed for this project"
|
380 |
+
]
|
381 |
+
},
|
382 |
+
{
|
383 |
+
"cell_type": "code",
|
384 |
+
"execution_count": null,
|
385 |
+
"metadata": {},
|
386 |
+
"outputs": [],
|
387 |
+
"source": [
|
388 |
+
"from ultralytics import YOLO\n",
|
389 |
+
"import time\n",
|
390 |
+
"import numpy as np\n",
|
391 |
+
"import mediapipe as mp\n",
|
392 |
+
"\n",
|
393 |
+
"\n",
|
394 |
+
"import cv2\n",
|
395 |
+
"from flask import Flask, render_template, request, Response, session, redirect, url_for\n",
|
396 |
+
"\n",
|
397 |
+
"from flask_socketio import SocketIO\n",
|
398 |
+
"import yt_dlp as youtube_dl"
|
399 |
+
]
|
400 |
+
},
|
401 |
+
{
|
402 |
+
"cell_type": "markdown",
|
403 |
+
"metadata": {},
|
404 |
+
"source": [
|
405 |
+
"Explanation for each library:\n",
|
406 |
+
"- ultralytics.YOLO: Used for real-time object detection.\n",
|
407 |
+
"- time: Handles time-related functions.\n",
|
408 |
+
"- numpy as np: Supports numerical computations and arrays.\n",
|
409 |
+
"- mediapipe as mp: Facilitates various media processing tasks like object detection and hand tracking.\n",
|
410 |
+
"- cv2: Offers tools for computer vision, image, and video processing.\n",
|
411 |
+
"- Flask: A lightweight web framework for building web applications.\n",
|
412 |
+
"- Flask_socketio and SocketIO: Enables WebSocket support for real-time communication in Flask.\n",
|
413 |
+
"- yt_dlp as youtube_dl: Used to stream media content from various streaming sites, like YouTube."
|
414 |
+
]
|
415 |
+
},
|
416 |
+
{
|
417 |
+
"cell_type": "markdown",
|
418 |
+
"metadata": {},
|
419 |
+
"source": [
|
420 |
+
"### Initialize Model"
|
421 |
+
]
|
422 |
+
},
|
423 |
+
{
|
424 |
+
"cell_type": "code",
|
425 |
+
"execution_count": null,
|
426 |
+
"metadata": {},
|
427 |
+
"outputs": [],
|
428 |
+
"source": [
|
429 |
+
"model_object_detection = YOLO(\"bisindo.pt\")"
|
430 |
+
]
|
431 |
+
},
|
432 |
+
{
|
433 |
+
"cell_type": "markdown",
|
434 |
+
"metadata": {},
|
435 |
+
"source": [
|
436 |
+
"### Create Function for Detection"
|
437 |
+
]
|
438 |
+
},
|
439 |
+
{
|
440 |
+
"cell_type": "code",
|
441 |
+
"execution_count": null,
|
442 |
+
"metadata": {},
|
443 |
+
"outputs": [],
|
444 |
+
"source": [
|
445 |
+
"def show(self, url):\n",
|
446 |
+
" print(url)\n",
|
447 |
+
" self._preview = False\n",
|
448 |
+
" self._flipH = False\n",
|
449 |
+
" self._detect = False\n",
|
450 |
+
" self._mediaPipe = False\n",
|
451 |
+
"\n",
|
452 |
+
" self._confidence = 75.0\n",
|
453 |
+
" ydl_opts = {\n",
|
454 |
+
" \"quiet\": True,\n",
|
455 |
+
" \"no_warnings\": True,\n",
|
456 |
+
" \"format\": \"best\",\n",
|
457 |
+
" \"forceurl\": True,\n",
|
458 |
+
" }\n",
|
459 |
+
"\n",
|
460 |
+
" if url == '0':\n",
|
461 |
+
" cap = cv2.VideoCapture(0)\n",
|
462 |
+
" else:\n",
|
463 |
+
" \n",
|
464 |
+
" ydl = youtube_dl.YoutubeDL(ydl_opts)\n",
|
465 |
+
"\n",
|
466 |
+
" info = ydl.extract_info(url, download=False)\n",
|
467 |
+
" url = info[\"url\"]\n",
|
468 |
+
"\n",
|
469 |
+
" cap = cv2.VideoCapture(url)\n",
|
470 |
+
"\n",
|
471 |
+
" while True:\n",
|
472 |
+
" if self._preview:\n",
|
473 |
+
" if stop_flag:\n",
|
474 |
+
" print(\"Process Stopped\")\n",
|
475 |
+
" return\n",
|
476 |
+
"\n",
|
477 |
+
" grabbed, frame = cap.read()\n",
|
478 |
+
" if not grabbed:\n",
|
479 |
+
" break\n",
|
480 |
+
" if self.flipH:\n",
|
481 |
+
" frame = cv2.flip(frame, 1)\n",
|
482 |
+
"\n",
|
483 |
+
" if self.detect:\n",
|
484 |
+
" frame_yolo = frame.copy()\n",
|
485 |
+
" results_yolo = model_object_detection.predict(frame_yolo, conf=self._confidence / 100)\n",
|
486 |
+
"\n",
|
487 |
+
" frame_yolo, labels = results_yolo[0].plot()\n",
|
488 |
+
" list_labels = []\n",
|
489 |
+
" # labels_confidences\n",
|
490 |
+
" for label in labels:\n",
|
491 |
+
" confidence = label.split(\" \")[-1]\n",
|
492 |
+
" label = (label.split(\" \"))[:-1]\n",
|
493 |
+
" label = \" \".join(label)\n",
|
494 |
+
" list_labels.append(label)\n",
|
495 |
+
" list_labels.append(confidence)\n",
|
496 |
+
" socketio.emit('label', list_labels)\n",
|
497 |
+
"\n",
|
498 |
+
" if self.mediaPipe:\n",
|
499 |
+
" # Convert the image to RGB for processing with MediaPipe\n",
|
500 |
+
" image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)\n",
|
501 |
+
" results = self.hands.process(image)\n",
|
502 |
+
" \n",
|
503 |
+
" if results.multi_hand_landmarks:\n",
|
504 |
+
" for hand_landmarks in results.multi_hand_landmarks:\n",
|
505 |
+
" mp.solutions.drawing_utils.draw_landmarks(\n",
|
506 |
+
" frame,\n",
|
507 |
+
" hand_landmarks,\n",
|
508 |
+
" self.mp_hands.HAND_CONNECTIONS,\n",
|
509 |
+
" landmark_drawing_spec=mp.solutions.drawing_utils.DrawingSpec(color=(255, 0, 0), thickness=4, circle_radius=3),\n",
|
510 |
+
" connection_drawing_spec=mp.solutions.drawing_utils.DrawingSpec(color=(255, 255, 255), thickness=2, circle_radius=2), \n",
|
511 |
+
" )\n",
|
512 |
+
"\n",
|
513 |
+
" frame = cv2.imencode(\".jpg\", frame)[1].tobytes()\n",
|
514 |
+
" yield ( \n",
|
515 |
+
" b'--frame\\r\\n'\n",
|
516 |
+
" b'Content-Type: image/jpeg\\r\\n\\r\\n' + frame + b'\\r\\n'\n",
|
517 |
+
" )\n",
|
518 |
+
" else:\n",
|
519 |
+
" snap = np.zeros((\n",
|
520 |
+
" 1000,\n",
|
521 |
+
" 1000\n",
|
522 |
+
" ), np.uint8)\n",
|
523 |
+
" label = \"Streaming Off\"\n",
|
524 |
+
" H, W = snap.shape\n",
|
525 |
+
" font = cv2.FONT_HERSHEY_PLAIN\n",
|
526 |
+
" color = (255, 255, 255)\n",
|
527 |
+
" cv2.putText(snap, label, (W//2 - 100, H//2),\n",
|
528 |
+
" font, 2, color, 2)\n",
|
529 |
+
" frame = cv2.imencode(\".jpg\", snap)[1].tobytes()\n",
|
530 |
+
" yield (b'--frame\\r\\n'\n",
|
531 |
+
" b'Content-Type: image/jpeg\\r\\n\\r\\n' + frame + b'\\r\\n')"
|
532 |
+
]
|
533 |
+
},
|
534 |
+
{
|
535 |
+
"cell_type": "markdown",
|
536 |
+
"metadata": {},
|
537 |
+
"source": [
|
538 |
+
"### Explanation for each object:\n",
|
539 |
+
"- preview(): Displays the video stream on the web interface.\n",
|
540 |
+
"- flipH(): Flips the video horizontally.\n",
|
541 |
+
"- detect(): Detects using Yolo model the hand gesture from the video stream.\n",
|
542 |
+
"- mediaPipe(): Draws the hand gesture landmark on the video stream.\n",
|
543 |
+
"\n",
|
544 |
+
"### Explanation for flow of the program:\n",
|
545 |
+
"- If user input is \"camera\", the program will run the camera detection.\n",
|
546 |
+
"- If user input is \"url youtube video\", the program will run the youtube detection.\n",
|
547 |
+
"- If user activate the preview, the program will run the video stream/camera.\n",
|
548 |
+
"- If user activate the detection, the program will run the detection.\n",
|
549 |
+
"- If user activate the landmark, the program will run the landmark.\n",
|
550 |
+
"- If user activate the flip, video will be flipped.\n",
|
551 |
+
"- Threshold is used to set the minimum confidence threshold of the detection.\n",
|
552 |
+
"- If the preview is not activated, the program will show `streaming off` label.\n"
|
553 |
+
]
|
554 |
+
},
|
555 |
+
{
|
556 |
+
"cell_type": "markdown",
|
557 |
+
"metadata": {},
|
558 |
+
"source": [
|
559 |
+
"## Integration in HTML, CSS, and Javascript"
|
560 |
+
]
|
561 |
+
},
|
562 |
+
{
|
563 |
+
"cell_type": "markdown",
|
564 |
+
"metadata": {},
|
565 |
+
"source": [
|
566 |
+
"### In CSS file, create a style for the stream and output"
|
567 |
+
]
|
568 |
+
},
|
569 |
+
{
|
570 |
+
"cell_type": "code",
|
571 |
+
"execution_count": null,
|
572 |
+
"metadata": {},
|
573 |
+
"outputs": [],
|
574 |
+
"source": [
|
575 |
+
"/* * Local selectors */\n",
|
576 |
+
"#container {\n",
|
577 |
+
" width: 100%;\n",
|
578 |
+
" height: 586px;\n",
|
579 |
+
" border: 8px #2c374a solid;\n",
|
580 |
+
" background-color: #0F172A;\n",
|
581 |
+
" border-radius: 5px;\n",
|
582 |
+
"}\n",
|
583 |
+
"\n",
|
584 |
+
"#videoElement {\n",
|
585 |
+
" height: 570px;\n",
|
586 |
+
" width: 100%;\n",
|
587 |
+
" background-color: #0F172A;\n",
|
588 |
+
"\n",
|
589 |
+
" display: block;\n",
|
590 |
+
" margin-left: auto;\n",
|
591 |
+
" margin-right: auto;\n",
|
592 |
+
"}\n",
|
593 |
+
"\n",
|
594 |
+
"#terminal {\n",
|
595 |
+
" border-radius: 5px;\n",
|
596 |
+
" border: 5px #1C2637 solid;\n",
|
597 |
+
" font-family: monospace;\n",
|
598 |
+
" font-size: 12px;\n",
|
599 |
+
" background-color: #0F172A;\n",
|
600 |
+
" height: 490px;\n",
|
601 |
+
" overflow-y: scroll;\n",
|
602 |
+
"}"
|
603 |
+
]
|
604 |
+
},
|
605 |
+
{
|
606 |
+
"cell_type": "markdown",
|
607 |
+
"metadata": {},
|
608 |
+
"source": [
|
609 |
+
"### In Javascript, create a function needed for the web interface"
|
610 |
+
]
|
611 |
+
},
|
612 |
+
{
|
613 |
+
"cell_type": "markdown",
|
614 |
+
"metadata": {},
|
615 |
+
"source": [
|
616 |
+
"#### For Camera or Video Button"
|
617 |
+
]
|
618 |
+
},
|
619 |
+
{
|
620 |
+
"cell_type": "code",
|
621 |
+
"execution_count": null,
|
622 |
+
"metadata": {},
|
623 |
+
"outputs": [],
|
624 |
+
"source": [
|
625 |
+
"function startCamera() {\n",
|
626 |
+
" var url = '0';\n",
|
627 |
+
" $('#urlForm').attr('action', '/index'); \n",
|
628 |
+
" $('#urlForm').attr('method', 'POST'); \n",
|
629 |
+
" $('#urlForm').find('#url').val(url);\n",
|
630 |
+
" $('#urlForm').submit();\n",
|
631 |
+
"}\n",
|
632 |
+
"\n",
|
633 |
+
"function startVideo() {\n",
|
634 |
+
" var url = $('#url').val();\n",
|
635 |
+
" $('#urlForm').attr('action', '/index'); \n",
|
636 |
+
" $('#urlForm').attr('method', 'POST'); \n",
|
637 |
+
" $('#urlForm').find('#url').val(url);\n",
|
638 |
+
" $('#urlForm').submit();\n",
|
639 |
+
"}"
|
640 |
+
]
|
641 |
+
},
|
642 |
+
{
|
643 |
+
"cell_type": "markdown",
|
644 |
+
"metadata": {},
|
645 |
+
"source": [
|
646 |
+
"#### For terminal output, socket, and final output"
|
647 |
+
]
|
648 |
+
},
|
649 |
+
{
|
650 |
+
"cell_type": "code",
|
651 |
+
"execution_count": null,
|
652 |
+
"metadata": {},
|
653 |
+
"outputs": [],
|
654 |
+
"source": [
|
655 |
+
"var socket = io.connect('http://127.0.0.1:5000/');\n",
|
656 |
+
"\n",
|
657 |
+
"let consecutiveWords = [];\n",
|
658 |
+
"let finalSentence = \"\";\n",
|
659 |
+
"let wordCounter = 0;\n",
|
660 |
+
"\n",
|
661 |
+
"function appendToTerminal(message) {\n",
|
662 |
+
" var terminal = document.getElementById(\"terminal\");\n",
|
663 |
+
" var p = document.createElement(\"p\");\n",
|
664 |
+
" p.innerHTML = `<table class=\"table table-striped text-center\" style=\"border: none;\">\n",
|
665 |
+
" <tr class=\"row\">\n",
|
666 |
+
" <td class=\"col-md-6\" style=\"color: #01ECEC; border: none;\">${message[0]}</td>\n",
|
667 |
+
" <td class=\"col-md-6\" style=\"color: #01ECEC; border: none;\">${message[1]}</td>\n",
|
668 |
+
" </tr>\n",
|
669 |
+
" </table>`;\n",
|
670 |
+
" terminal.appendChild(p);\n",
|
671 |
+
" terminal.scrollTop = terminal.scrollHeight;\n",
|
672 |
+
"\n",
|
673 |
+
" if (consecutiveWords.length === 0 || consecutiveWords[consecutiveWords.length - 1] === message[0]) {\n",
|
674 |
+
" consecutiveWords.push(message[0]);\n",
|
675 |
+
" wordCounter++; \n",
|
676 |
+
" } else {\n",
|
677 |
+
" consecutiveWords = [message[0]];\n",
|
678 |
+
" wordCounter = 1;\n",
|
679 |
+
" }\n",
|
680 |
+
"\n",
|
681 |
+
" if (wordCounter >= 10) {\n",
|
682 |
+
" finalSentence += (finalSentence.length > 0 ? \" \" : \"\") + consecutiveWords[0];\n",
|
683 |
+
" document.getElementById(\"finalSentencePara\").innerText = finalSentence;\n",
|
684 |
+
" consecutiveWords = [];\n",
|
685 |
+
" wordCounter = 0;\n",
|
686 |
+
" }\n",
|
687 |
+
"}\n",
|
688 |
+
"\n",
|
689 |
+
"socket.on(\"label\", (data) => {\n",
|
690 |
+
" appendToTerminal(data);\n",
|
691 |
+
"});"
|
692 |
+
]
|
693 |
+
},
|
694 |
+
{
|
695 |
+
"cell_type": "markdown",
|
696 |
+
"metadata": {},
|
697 |
+
"source": [
|
698 |
+
"Integration with SocketIO:\n",
|
699 |
+
"\n",
|
700 |
+
"- Listens for data labeled as \"label\" from a SocketIO connection.\n",
|
701 |
+
"- Calls appendToTerminal() to display the received data in the terminal and potentially update an advertisement based on the data.\n",
|
702 |
+
"\n",
|
703 |
+
"Function appendToTerminal(message):\n",
|
704 |
+
"\n",
|
705 |
+
"- Takes a message as input.\n",
|
706 |
+
"- Adds a table with two columns to the terminal for displaying the message.\n",
|
707 |
+
"- Keeps track of consecutive words and their counts.\n",
|
708 |
+
"- Constructs a final sentence if a word appears more than ten times consecutively."
|
709 |
+
]
|
710 |
+
},
|
711 |
+
{
|
712 |
+
"cell_type": "markdown",
|
713 |
+
"metadata": {},
|
714 |
+
"source": [
|
715 |
+
"#### For Toggle Button"
|
716 |
+
]
|
717 |
+
},
|
718 |
+
{
|
719 |
+
"cell_type": "code",
|
720 |
+
"execution_count": null,
|
721 |
+
"metadata": {},
|
722 |
+
"outputs": [],
|
723 |
+
"source": [
|
724 |
+
"function toggleHSwitch() {\n",
|
725 |
+
" var switchElement = $(\"#flip-horizontal\");\n",
|
726 |
+
" var switchIsOn = switchElement.is(\":checked\");\n",
|
727 |
+
"\n",
|
728 |
+
" if (switchIsOn) {\n",
|
729 |
+
" console.log(\"SWITCH ON\")\n",
|
730 |
+
" $.getJSON(\"/request_flipH_switch\", function (data) {\n",
|
731 |
+
" console.log(\"Switch on request sent.\");\n",
|
732 |
+
" });\n",
|
733 |
+
" } else {\n",
|
734 |
+
" console.log(\"SWITCH OFF\")\n",
|
735 |
+
" $.getJSON(\"/request_flipH_switch\", function (data) {\n",
|
736 |
+
" console.log(\"Switch off request sent.\");\n",
|
737 |
+
" });\n",
|
738 |
+
" }\n",
|
739 |
+
"}\n",
|
740 |
+
"\n",
|
741 |
+
"function toggleMediaPipeSwitch() {\n",
|
742 |
+
" var switchElement = $(\"#mediapipe\");\n",
|
743 |
+
" var switchIsOn = switchElement.is(\":checked\");\n",
|
744 |
+
"\n",
|
745 |
+
" if (switchIsOn) {\n",
|
746 |
+
" console.log(\"SWITCH ON\")\n",
|
747 |
+
" $.getJSON(\"/request_mediapipe_switch\", function (data) {\n",
|
748 |
+
" console.log(\"Switch on request sent.\");\n",
|
749 |
+
" });\n",
|
750 |
+
" } else {\n",
|
751 |
+
" console.log(\"SWITCH OFF\")\n",
|
752 |
+
" $.getJSON(\"/request_mediapipe_switch\", function (data) {\n",
|
753 |
+
" console.log(\"Switch off request sent.\");\n",
|
754 |
+
" });\n",
|
755 |
+
" }\n",
|
756 |
+
"}\n",
|
757 |
+
"\n",
|
758 |
+
"function toggleDetSwitch() {\n",
|
759 |
+
"\n",
|
760 |
+
" var switchElement = $(\"#run_detection\");\n",
|
761 |
+
" var switchIsOn = switchElement.is(\":checked\");\n",
|
762 |
+
"\n",
|
763 |
+
" if (switchIsOn) {\n",
|
764 |
+
" console.log(\"SWITCH ON\")\n",
|
765 |
+
" $.getJSON(\"/request_run_model_switch\", function (data) {\n",
|
766 |
+
" console.log(\"Switch on request sent.\");\n",
|
767 |
+
" });\n",
|
768 |
+
" } else {\n",
|
769 |
+
" console.log(\"SWITCH OFF\")\n",
|
770 |
+
" $.getJSON(\"/request_run_model_switch\", function (data) {\n",
|
771 |
+
" console.log(\"Switch off request sent.\");\n",
|
772 |
+
" });\n",
|
773 |
+
" }\n",
|
774 |
+
"}\n",
|
775 |
+
"\n",
|
776 |
+
"function toggleOffSwitch() {\n",
|
777 |
+
" var switchElement = $(\"#turn_off\");\n",
|
778 |
+
" var switchIsOn = switchElement.is(\":checked\");\n",
|
779 |
+
"\n",
|
780 |
+
" if (switchIsOn) {\n",
|
781 |
+
" console.log(\"Camera ON\")\n",
|
782 |
+
" $.getJSON(\"/request_preview_switch\", function (data) {\n",
|
783 |
+
" console.log(\"Switch on request sent.\");\n",
|
784 |
+
" });\n",
|
785 |
+
" } else {\n",
|
786 |
+
" console.log(\"Camera OFF\")\n",
|
787 |
+
" $.getJSON(\"/request_preview_switch\", function (data) {\n",
|
788 |
+
" console.log(\"Switch off request sent.\");\n",
|
789 |
+
" });\n",
|
790 |
+
" }\n",
|
791 |
+
"}"
|
792 |
+
]
|
793 |
+
},
|
794 |
+
{
|
795 |
+
"cell_type": "markdown",
|
796 |
+
"metadata": {},
|
797 |
+
"source": [
|
798 |
+
"### For HTML, integrate the Javascript function"
|
799 |
+
]
|
800 |
+
},
|
801 |
+
{
|
802 |
+
"cell_type": "markdown",
|
803 |
+
"metadata": {},
|
804 |
+
"source": [
|
805 |
+
"#### For Camera and Terminal Output"
|
806 |
+
]
|
807 |
+
},
|
808 |
+
{
|
809 |
+
"cell_type": "code",
|
810 |
+
"execution_count": null,
|
811 |
+
"metadata": {},
|
812 |
+
"outputs": [],
|
813 |
+
"source": [
|
814 |
+
"<!-- Video -->\n",
|
815 |
+
"<div class=\"col-span-8 mx-4 mt-3\">\n",
|
816 |
+
" <div id=\"container\">\n",
|
817 |
+
" <img class=\"center\" src=\"/video_feed\" id=\"videoElement\">\n",
|
818 |
+
" </div>\n",
|
819 |
+
"</div>\n",
|
820 |
+
"\n",
|
821 |
+
"<!-- Terminal -->\n",
|
822 |
+
"<div class=\"col-span-2 mr-4\">\n",
|
823 |
+
" <h2 class=\"border-b border-slate-800 py-4 mb-4 text-3xl flex justify-end font-bold leading-none tracking-tight md:text-4xl lg:text-4xl text-cyan-100 \">Output</h1>\n",
|
824 |
+
" <div id=\"terminal\" class=\"w-full\"></div>\n",
|
825 |
+
"</div>"
|
826 |
+
]
|
827 |
+
},
|
828 |
+
{
|
829 |
+
"cell_type": "markdown",
|
830 |
+
"metadata": {},
|
831 |
+
"source": [
|
832 |
+
"#### For toggle switch"
|
833 |
+
]
|
834 |
+
},
|
835 |
+
{
|
836 |
+
"cell_type": "code",
|
837 |
+
"execution_count": null,
|
838 |
+
"metadata": {},
|
839 |
+
"outputs": [],
|
840 |
+
"source": [
|
841 |
+
"<div class=\"flex gap-3 mb-4\">\n",
|
842 |
+
" <label class=\"switch\">\n",
|
843 |
+
" <input id=\"turn_off\" value=\"1\" name=\"turn_off\" type=\"checkbox\" onclick=\"toggleOffSwitch()\"/>\n",
|
844 |
+
" <span class=\"slider round\"></span>\n",
|
845 |
+
" </label>\n",
|
846 |
+
" <label for=\"turn_off\" class=\"form-label text-cyan-500\">Show Video</label><br>\n",
|
847 |
+
"</div>\n",
|
848 |
+
"<div class=\"flex gap-3 mb-4\">\n",
|
849 |
+
" <label class=\"switch\">\n",
|
850 |
+
" <input id=\"run_detection\" value=\"0\" name=\"run_detection\" type=\"checkbox\"\n",
|
851 |
+
" onclick=\"toggleDetSwitch()\"/>\n",
|
852 |
+
" <span class=\"slider round\"></span>\n",
|
853 |
+
" </label>\n",
|
854 |
+
" <label for=\"run_detection\" class=\"form-label text-cyan-500\">Run Detection</label><br>\n",
|
855 |
+
"</div>\n",
|
856 |
+
"<div class=\"flex gap-3 mb-4\">\n",
|
857 |
+
" <label class=\"switch\">\n",
|
858 |
+
" <input id=\"mediapipe\" value=\"0\" name=\"mediapipe\" type=\"checkbox\"\n",
|
859 |
+
" onclick=\"toggleMediaPipeSwitch()\"/>\n",
|
860 |
+
" <span class=\"slider round\"></span>\n",
|
861 |
+
" </label>\n",
|
862 |
+
" <label for=\"mediapipe\" class=\"form-label text-cyan-500\">Show Landmark</label><br>\n",
|
863 |
+
"</div>\n",
|
864 |
+
"<div class=\"flex gap-3 mb-4\">\n",
|
865 |
+
" <label class=\"switch\">\n",
|
866 |
+
" <input id=\"flip-horizontal\" value=\"0\" name=\"flip-horizontal\" type=\"checkbox\"\n",
|
867 |
+
" onclick=\"toggleHSwitch()\"/>\n",
|
868 |
+
" <span class=\"slider round\"></span>\n",
|
869 |
+
" </label>\n",
|
870 |
+
" <label for=\"flip-horizontal\" class=\"form-label text-cyan-500\">Flip Video</label><br>\n",
|
871 |
+
"</div>\n",
|
872 |
+
"\n",
|
873 |
+
"<div class=\"gap-3 py-4 text-center border-b border-slate-800 mb-5\">\n",
|
874 |
+
" <form action=\"/\" method=\"POST\" style=\"text-align: center;\" class=\"mb-4\" >\n",
|
875 |
+
" <label for=\"slider\" class=\"form-label text-cyan-500\">Confidence Threshold</label>\n",
|
876 |
+
" <input type=\"range\" id=\"slider\" name=\"slider\" min=\"1\" max=\"100\">\n",
|
877 |
+
" </form>\n",
|
878 |
+
" <input type=\"hidden\" id=\"sliderValue\" name=\"sliderValue\" value=\"75\">\n",
|
879 |
+
" <span class=\"rounded-lg py-2 px-3 bg-slate-800 text-cyan-500\" id=\"conf_display\">75</span>\n",
|
880 |
+
"</div>"
|
881 |
+
]
|
882 |
+
},
|
883 |
+
{
|
884 |
+
"cell_type": "markdown",
|
885 |
+
"metadata": {},
|
886 |
+
"source": [
|
887 |
+
"#### For Final Output"
|
888 |
+
]
|
889 |
+
},
|
890 |
+
{
|
891 |
+
"cell_type": "code",
|
892 |
+
"execution_count": null,
|
893 |
+
"metadata": {},
|
894 |
+
"outputs": [],
|
895 |
+
"source": [
|
896 |
+
"<div>\n",
|
897 |
+
" <p id=\"finalSentencePara\" class=\"text-cyan-200 mt-4 text-center\">\n",
|
898 |
+
" </p>\n",
|
899 |
+
"</div>"
|
900 |
+
]
|
901 |
+
}
|
902 |
+
],
|
903 |
+
"metadata": {
|
904 |
+
"accelerator": "GPU",
|
905 |
+
"colab": {
|
906 |
+
"provenance": []
|
907 |
+
},
|
908 |
+
"gpuClass": "standard",
|
909 |
+
"kernelspec": {
|
910 |
+
"display_name": "Python 3",
|
911 |
+
"name": "python3"
|
912 |
+
},
|
913 |
+
"language_info": {
|
914 |
+
"codemirror_mode": {
|
915 |
+
"name": "ipython",
|
916 |
+
"version": 3
|
917 |
+
},
|
918 |
+
"file_extension": ".py",
|
919 |
+
"mimetype": "text/x-python",
|
920 |
+
"name": "python",
|
921 |
+
"nbconvert_exporter": "python",
|
922 |
+
"pygments_lexer": "ipython3",
|
923 |
+
"version": "3.11.5"
|
924 |
+
}
|
925 |
+
},
|
926 |
+
"nbformat": 4,
|
927 |
+
"nbformat_minor": 0
|
928 |
+
}
|
ultralytics/__init__.py
ADDED
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# Ultralytics YOLO 🚀, GPL-3.0 license
|
2 |
+
|
3 |
+
__version__ = '8.0.61'
|
4 |
+
|
5 |
+
from ultralytics.hub import start
|
6 |
+
from ultralytics.yolo.engine.model import YOLO
|
7 |
+
from ultralytics.yolo.utils.checks import check_yolo as checks
|
8 |
+
|
9 |
+
__all__ = '__version__', 'YOLO', 'checks', 'start' # allow simpler import
|
ultralytics/__pycache__/__init__.cpython-310.pyc
ADDED
Binary file (426 Bytes). View file
|
|
ultralytics/__pycache__/__init__.cpython-311.pyc
ADDED
Binary file (467 Bytes). View file
|
|
ultralytics/abc
ADDED
@@ -0,0 +1 @@
|
|
|
|
|
1 |
+
|
ultralytics/assets/bus.jpg
ADDED
![]() |
ultralytics/assets/zidane.jpg
ADDED
![]() |
ultralytics/datasets/Argoverse.yaml
ADDED
@@ -0,0 +1,73 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# Ultralytics YOLO 🚀, GPL-3.0 license
|
2 |
+
# Argoverse-HD dataset (ring-front-center camera) http://www.cs.cmu.edu/~mengtial/proj/streaming/ by Argo AI
|
3 |
+
# Example usage: yolo train data=Argoverse.yaml
|
4 |
+
# parent
|
5 |
+
# ├── ultralytics
|
6 |
+
# └── datasets
|
7 |
+
# └── Argoverse ← downloads here (31.3 GB)
|
8 |
+
|
9 |
+
|
10 |
+
# Train/val/test sets as 1) dir: path/to/imgs, 2) file: path/to/imgs.txt, or 3) list: [path/to/imgs1, path/to/imgs2, ..]
|
11 |
+
path: ../datasets/Argoverse # dataset root dir
|
12 |
+
train: Argoverse-1.1/images/train/ # train images (relative to 'path') 39384 images
|
13 |
+
val: Argoverse-1.1/images/val/ # val images (relative to 'path') 15062 images
|
14 |
+
test: Argoverse-1.1/images/test/ # test images (optional) https://eval.ai/web/challenges/challenge-page/800/overview
|
15 |
+
|
16 |
+
# Classes
|
17 |
+
names:
|
18 |
+
0: person
|
19 |
+
1: bicycle
|
20 |
+
2: car
|
21 |
+
3: motorcycle
|
22 |
+
4: bus
|
23 |
+
5: truck
|
24 |
+
6: traffic_light
|
25 |
+
7: stop_sign
|
26 |
+
|
27 |
+
|
28 |
+
# Download script/URL (optional) ---------------------------------------------------------------------------------------
|
29 |
+
download: |
|
30 |
+
import json
|
31 |
+
from tqdm import tqdm
|
32 |
+
from ultralytics.yolo.utils.downloads import download
|
33 |
+
from pathlib import Path
|
34 |
+
|
35 |
+
def argoverse2yolo(set):
|
36 |
+
labels = {}
|
37 |
+
a = json.load(open(set, "rb"))
|
38 |
+
for annot in tqdm(a['annotations'], desc=f"Converting {set} to YOLOv5 format..."):
|
39 |
+
img_id = annot['image_id']
|
40 |
+
img_name = a['images'][img_id]['name']
|
41 |
+
img_label_name = f'{img_name[:-3]}txt'
|
42 |
+
|
43 |
+
cls = annot['category_id'] # instance class id
|
44 |
+
x_center, y_center, width, height = annot['bbox']
|
45 |
+
x_center = (x_center + width / 2) / 1920.0 # offset and scale
|
46 |
+
y_center = (y_center + height / 2) / 1200.0 # offset and scale
|
47 |
+
width /= 1920.0 # scale
|
48 |
+
height /= 1200.0 # scale
|
49 |
+
|
50 |
+
img_dir = set.parents[2] / 'Argoverse-1.1' / 'labels' / a['seq_dirs'][a['images'][annot['image_id']]['sid']]
|
51 |
+
if not img_dir.exists():
|
52 |
+
img_dir.mkdir(parents=True, exist_ok=True)
|
53 |
+
|
54 |
+
k = str(img_dir / img_label_name)
|
55 |
+
if k not in labels:
|
56 |
+
labels[k] = []
|
57 |
+
labels[k].append(f"{cls} {x_center} {y_center} {width} {height}\n")
|
58 |
+
|
59 |
+
for k in labels:
|
60 |
+
with open(k, "w") as f:
|
61 |
+
f.writelines(labels[k])
|
62 |
+
|
63 |
+
|
64 |
+
# Download
|
65 |
+
dir = Path(yaml['path']) # dataset root dir
|
66 |
+
urls = ['https://argoverse-hd.s3.us-east-2.amazonaws.com/Argoverse-HD-Full.zip']
|
67 |
+
download(urls, dir=dir)
|
68 |
+
|
69 |
+
# Convert
|
70 |
+
annotations_dir = 'Argoverse-HD/annotations/'
|
71 |
+
(dir / 'Argoverse-1.1' / 'tracking').rename(dir / 'Argoverse-1.1' / 'images') # rename 'tracking' to 'images'
|
72 |
+
for d in "train.json", "val.json":
|
73 |
+
argoverse2yolo(dir / annotations_dir / d) # convert VisDrone annotations to YOLO labels
|