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
Files changed (50) hide show
  1. .gitignore +1 -0
  2. MANIFEST.in +8 -0
  3. app.py +337 -0
  4. bisindo.pt +3 -0
  5. bisindov2.pt +3 -0
  6. camera_settings.py +53 -0
  7. img/confusion_matrix.png +0 -0
  8. img/results.png +0 -0
  9. requirements.txt +0 -0
  10. setup.cfg +56 -0
  11. setup.py +65 -0
  12. static/script.js +194 -0
  13. static/style.css +217 -0
  14. templates/hompage copy.html +65 -0
  15. templates/hompage.html +80 -0
  16. templates/index copy.html +72 -0
  17. templates/index.html +120 -0
  18. templates/indexv1.html +112 -0
  19. tests/test_cli.py +81 -0
  20. tests/test_engine.py +93 -0
  21. tests/test_python.py +222 -0
  22. train/result/F1_curve.png +0 -0
  23. train/result/PR_curve.png +0 -0
  24. train/result/P_curve.png +0 -0
  25. train/result/R_curve.png +0 -0
  26. train/result/best.pt +3 -0
  27. train/result/confusion_matrix.png +0 -0
  28. train/result/events.out.tfevents.1703117386.69c6eee73c8d.3549.0 +3 -0
  29. train/result/results.csv +51 -0
  30. train/result/results.png +0 -0
  31. train/result/train_batch0.jpg +0 -0
  32. train/result/train_batch1.jpg +0 -0
  33. train/result/train_batch2.jpg +0 -0
  34. train/result/train_batch6680.jpg +0 -0
  35. train/result/train_batch6681.jpg +0 -0
  36. train/result/train_batch6682.jpg +0 -0
  37. train/result/val_batch0_labels.jpg +0 -0
  38. train/result/val_batch0_pred.jpg +0 -0
  39. train/result/val_batch1_labels.jpg +0 -0
  40. train/result/val_batch1_pred.jpg +0 -0
  41. train/result/val_batch2_labels.jpg +0 -0
  42. train/result/val_batch2_pred.jpg +0 -0
  43. train/train_model.ipynb +928 -0
  44. ultralytics/__init__.py +9 -0
  45. ultralytics/__pycache__/__init__.cpython-310.pyc +0 -0
  46. ultralytics/__pycache__/__init__.cpython-311.pyc +0 -0
  47. ultralytics/abc +1 -0
  48. ultralytics/assets/bus.jpg +0 -0
  49. ultralytics/assets/zidane.jpg +0 -0
  50. 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
+ "![dashboard](../img/image.png)</br>\n",
32
+ "\n",
33
+ "### Stream Youtube Detection\n",
34
+ "![yt](../img/image-2.png)</br>\n",
35
+ "\n",
36
+ "### Camera Detection\n",
37
+ "![run](../img/image-1.png)</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
+ "![dashboard](../img/confussion_matrix.png)</br>\n",
345
+ "\n",
346
+ "### Result Curve\n",
347
+ "![dashboard](../img/result.png)</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