Skip to content

Commit 42aa5c8

Browse files
committed
Merge branch 'develop'
2 parents 4d085bc + f9a3c97 commit 42aa5c8

File tree

9 files changed

+162
-16
lines changed

9 files changed

+162
-16
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,5 @@ dist
1414

1515
test
1616
build
17-
yolov8*
17+
yolov8*
18+
pyrightconfig.json

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
## [1.2.3] - 2024-03-17
2+
### Added
3+
- Added Tutorial how to run YOLOv8 pretrained Object Detection model `Tutorials.11_Yolov8.README.md`
4+
5+
16
## [1.2.2] - 2024-03-15
27
### Changed
38
- Bug fixed with `loss_info` local variable in `mltu.torch.model.Model` object

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,6 @@ Each tutorial has its own requirements.txt file for a specific mltu version. As
2424
6. [Introduction to PyTorch in a practical way](https://pylessons.com/pytorch-introduction), code in ```Tutorials\06_pytorch_introduction``` folder;
2525
7. [Using custom wrapper to simplify PyTorch models training pipeline](https://pylessons.com/pytorch-introduction), code in ```Tutorials\07_pytorch_wrapper``` folder;
2626
8. [Handwriting words recognition with PyTorch](https://pylessons.com/handwriting-recognition-pytorch), code in ```Tutorials\08_handwriting_recognition_torch``` folder;
27-
9. [Transformer training with TensorFlow for Translation task](https://pylessons.com/transformers-training), code in ```Tutorials\09_translation_transformer``` folder;
27+
9. [Transformer training with TensorFlow for Translation task](https://pylessons.com/transformers-training), code in ```Tutorials\09_translation_transformer``` folder;
28+
10. [Speech Recognition in Python | finetune wav2vec2 model for a custom ASR model](https://youtu.be/h6ooEGzjkj0), code in ```Tutorials\10_wav2vec2_torch``` folder;
29+
11. [YOLOv8: Real-Time Object Detection Simplified](https://youtu.be/vegL__weCxY), code in ```Tutorials\11_Yolov8``` folder;

Tutorials/11_Yolov8/README.md

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
# Run Ultralytics YOLOv8 pretrained model
2+
3+
YouTube tutorial link: [YOLOv8: Real-Time Object Detection Simplified](https://youtu.be/vegL__weCxY)
4+
5+
First, I recommend you to install the required packages in a virtual environment:
6+
```bash
7+
mltu==1.2.3
8+
ultralytics==8.1.28
9+
torch==2.0.0
10+
torchvision==0.15.1
11+
onnxruntime==1.15.1
12+
onnx==1.12.0
13+
```
14+
15+
### Run the pretrained Ultralytics YOLOv8 within torch environment on webcam:
16+
```python
17+
import cv2
18+
from ultralytics.engine.model import Model as BaseModel
19+
from mltu.torch.yolo.detectors.torch_detector import Detector as TorchDetector
20+
21+
input_width, input_height = 640, 640
22+
confidence_threshold = 0.5
23+
iou_threshold = 0.5
24+
25+
base_model = BaseModel("yolov8m.pt")
26+
detector = TorchDetector(base_model.model, input_width, input_height, base_model.names, confidence_threshold, iou_threshold)
27+
28+
cap = cv2.VideoCapture(0)
29+
while True:
30+
ret, frame = cap.read()
31+
if not ret:
32+
break
33+
34+
# Perform Yolo object detection
35+
detections = detector(frame)
36+
37+
# Apply the detections to the frame
38+
frame = detections.applyToFrame(frame)
39+
40+
# Print the FPS
41+
print(detector.fps)
42+
43+
# Display the output image
44+
cv2.imshow("Object Detection", frame)
45+
if cv2.waitKey(1) & 0xFF == ord('q'):
46+
break
47+
48+
cap.release()
49+
cv2.destroyAllWindows()
50+
```
51+
52+
## Convert the pretrained model to ONNX:
53+
```python
54+
import torch
55+
from ultralytics.engine.model import Model as BaseModel
56+
57+
base_model = BaseModel("yolov8m.pt")
58+
59+
classes = base_model.names
60+
input_width, input_height = 640, 640
61+
input_shape = (1, 3, input_width, input_height)
62+
model = base_model.model
63+
64+
# place model on cpu
65+
model.to("cpu")
66+
67+
# set the model to inference mode
68+
model.eval()
69+
70+
# convert the model to ONNX format
71+
dummy_input = torch.randn(input_shape).to("cpu")
72+
73+
# Export the model
74+
torch.onnx.export(
75+
model,
76+
dummy_input,
77+
"yolov8m.onnx",
78+
export_params=True,
79+
input_names = ["input"],
80+
output_names = ["output"],
81+
dynamic_axes = {
82+
"input": {0: "batch_size", 2: "height", 3: "width"},
83+
"output": {0: "batch_size", 2: "anchors"}
84+
}
85+
)
86+
87+
# Add the class names to the model as metadata
88+
import onnx
89+
90+
metadata = {"classes": classes}
91+
92+
# Load the ONNX model
93+
onnx_model = onnx.load("yolov8m.onnx")
94+
95+
# Add the metadata dictionary to the onnx model's metadata_props attribute
96+
for key, value in metadata.items():
97+
meta = onnx_model.metadata_props.add()
98+
meta.key = key
99+
meta.value = str(value)
100+
101+
# Save the modified ONNX model
102+
onnx.save(onnx_model, "yolov8m.onnx")
103+
```
104+
105+
## Run the YOLOv8 ONNX model with ONNX Runtime:
106+
```python
107+
import cv2
108+
from ultralytics.engine.model import Model as BaseModel
109+
from mltu.torch.yolo.detectors.onnx_detector import Detector as OnnxDetector
110+
111+
input_width, input_height = 640, 640
112+
confidence_threshold = 0.5
113+
iou_threshold = 0.5
114+
115+
detector = OnnxDetector("yolov8m.onnx", input_width, input_height, confidence_threshold, iou_threshold)
116+
117+
cap = cv2.VideoCapture(0)
118+
while True:
119+
ret, frame = cap.read()
120+
if not ret:
121+
break
122+
123+
# Perform Yolo object detection
124+
detections = detector(frame)
125+
126+
# Apply the detections to the frame
127+
frame = detections.applyToFrame(frame)
128+
129+
# Print the FPS
130+
print(detector.fps)
131+
132+
# Display the output image
133+
cv2.imshow("Object Detection", frame)
134+
if cv2.waitKey(1) & 0xFF == ord('q'):
135+
break
136+
137+
cap.release()
138+
cv2.destroyAllWindows()
139+
```

Tutorials/11_Yolov8/requirements.txt

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
ultralytics==8.1.9
2-
torch==2.1.1
1+
mltu==1.2.3
2+
ultralytics==8.1.28
3+
torch==2.0.0
34
torchvision==0.15.1
4-
onnxruntime
5-
onnx
5+
onnxruntime==1.15.1
6+
onnx==1.12.0

Tutorials/11_Yolov8/run_pretrained.py

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,12 @@
33
from mltu.torch.yolo.detectors.torch_detector import Detector as TorchDetector
44
from mltu.torch.yolo.detectors.onnx_detector import Detector as OnnxDetector
55

6-
7-
classes = {v: v for v in range(80)}
8-
input_width, input_height = 320, 320
9-
6+
input_width, input_height = 640, 640
107
confidence_threshold = 0.5
118
iou_threshold = 0.5
129

1310
# base_model = BaseModel("yolov8m.pt")
14-
# detector = TorchDetector(base_model.model, input_width, input_height, classes, confidence_threshold, iou_threshold)
11+
# detector = TorchDetector(base_model.model, input_width, input_height, base_model.names, confidence_threshold, iou_threshold)
1512
detector = OnnxDetector("yolov8m.onnx", input_width, input_height, confidence_threshold, iou_threshold)
1613

1714
cap = cv2.VideoCapture(0)
@@ -31,7 +28,8 @@
3128

3229
# Display the output image
3330
cv2.imshow("Object Detection", frame)
34-
cv2.waitKey(1)
31+
if cv2.waitKey(1) & 0xFF == ord('q'):
32+
break
3533

3634
cap.release()
3735
cv2.destroyAllWindows()

mltu/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
__version__ = "1.2.2"
1+
__version__ = "1.2.3"
22

33
from .annotations.images import Image
44
from .annotations.images import CVImage

mltu/annotations/detections.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,8 +114,8 @@ def validate(self):
114114
if self.width is None or self.height is None:
115115
raise ValueError("width and height must be provided when relative is False")
116116

117-
if (np.array(self.bbox) > 1.0).any():
118-
raise ValueError("bbox coordinates must be in range [0, 1] when relative is False")
117+
if not (np.array(self.bbox) > 1.0).any():
118+
raise ValueError("bbox coordinates must be in range [0, np.inf] when relative is False")
119119

120120
bbox = np.array(self.bbox) / np.array([self.width, self.height, self.width, self.height])
121121

mltu/torch/yolo/detectors/onnx_detector.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ def predict(self, image: np.ndarray, **kwargs) -> Detections:
4949
# Perform inference on the preprocessed image
5050
preds = self.model.run(self.output_names, {self.input_names[0]: preprocessed_image})
5151

52-
# Convert torch tensor to numpy array
52+
# Extract the results from the predictions
5353
results = preds[0][0]
5454

5555
# Calculate the scaling factors for the bounding box coordinates

0 commit comments

Comments
 (0)