Fangming Guo commited on
Commit
6d30d77
·
verified ·
1 Parent(s): 56a5459

Upload 43 files

Browse files
Files changed (44) hide show
  1. .gitattributes +2 -0
  2. AX615/yolov8m_640x640_npu1.axmodel +3 -0
  3. AX615/yolov8m_640x640_npu2.axmodel +3 -0
  4. AX615/yolov8n_640x640_npu1.axmodel +3 -0
  5. AX615/yolov8n_640x640_npu2.axmodel +3 -0
  6. AX615/yolov8s_640x640_npu1.axmodel +3 -0
  7. AX615/yolov8s_640x640_npu2.axmodel +3 -0
  8. AX620E/yolov8l_640x640_npu1.axmodel +3 -0
  9. AX620E/yolov8l_640x640_npu2.axmodel +3 -0
  10. AX620E/yolov8m_640x640_npu1.axmodel +3 -0
  11. AX620E/yolov8m_640x640_npu2.axmodel +3 -0
  12. AX620E/yolov8n_640x640_npu1.axmodel +3 -0
  13. AX620E/yolov8n_640x640_npu2.axmodel +3 -0
  14. AX620E/yolov8s_640x640_npu1.axmodel +3 -0
  15. AX620E/yolov8s_640x640_npu2.axmodel +3 -0
  16. AX620E/yolov8x_640x640_npu1.axmodel +3 -0
  17. AX620E/yolov8x_640x640_npu2.axmodel +3 -0
  18. AX637/yolov8l_640x640_npu1.axmodel +3 -0
  19. AX637/yolov8m_640x640_npu1.axmodel +3 -0
  20. AX637/yolov8n_640x640_npu1.axmodel +3 -0
  21. AX637/yolov8s_640x640_npu1.axmodel +3 -0
  22. AX637/yolov8x_640x640_npu1.axmodel +3 -0
  23. AX650/yolov8l_640x640_npu1.axmodel +3 -0
  24. AX650/yolov8l_640x640_npu3.axmodel +3 -0
  25. AX650/yolov8m_640x640_npu1.axmodel +3 -0
  26. AX650/yolov8m_640x640_npu3.axmodel +3 -0
  27. AX650/yolov8n_640x640_npu1.axmodel +3 -0
  28. AX650/yolov8n_640x640_npu3.axmodel +3 -0
  29. AX650/yolov8s_640x640_npu1.axmodel +3 -0
  30. AX650/yolov8s_640x640_npu3.axmodel +3 -0
  31. AX650/yolov8x_640x640_npu1.axmodel +3 -0
  32. AX650/yolov8x_640x640_npu3.axmodel +3 -0
  33. ax_infer.py +230 -0
  34. bus.jpg +3 -0
  35. coco_1000.tar +3 -0
  36. config.json +32 -0
  37. export_onnx.py +91 -0
  38. onnx_infer.py +269 -0
  39. result_yolov8_det.jpg +3 -0
  40. yolov8l_640x640.onnx +3 -0
  41. yolov8m_640x640.onnx +3 -0
  42. yolov8n_640x640.onnx +3 -0
  43. yolov8s_640x640.onnx +3 -0
  44. yolov8x_640x640.onnx +3 -0
.gitattributes CHANGED
@@ -44,3 +44,5 @@ axcl_aarch64/axcl_yolov8 filter=lfs diff=lfs merge=lfs -text
44
  axcl_x86_64/axcl_yolov8 filter=lfs diff=lfs merge=lfs -text
45
  yolov8_axcl_out.jpg filter=lfs diff=lfs merge=lfs -text
46
  *.axmodel filter=lfs diff=lfs merge=lfs -text
 
 
 
44
  axcl_x86_64/axcl_yolov8 filter=lfs diff=lfs merge=lfs -text
45
  yolov8_axcl_out.jpg filter=lfs diff=lfs merge=lfs -text
46
  *.axmodel filter=lfs diff=lfs merge=lfs -text
47
+ bus.jpg filter=lfs diff=lfs merge=lfs -text
48
+ result_yolov8_det.jpg filter=lfs diff=lfs merge=lfs -text
AX615/yolov8m_640x640_npu1.axmodel ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:318f485b377273c2d9107ff5869f58b0c01fe6343afee56afd9ae792d856c335
3
+ size 28682377
AX615/yolov8m_640x640_npu2.axmodel ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:7b70f750bd5d9dcda95c7ad28f5176d8f7752ce2384c1c7d0b0ba0200b02f2eb
3
+ size 26630729
AX615/yolov8n_640x640_npu1.axmodel ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:34f90d2d742214630ee1034a487cd4d4fdd61be31cda3fbddf818b86d4113be7
3
+ size 3670985
AX615/yolov8n_640x640_npu2.axmodel ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:d71eae7f16a7358c6b2f182f0d1c695c5a2cf1f48eae9b1a8dee3c322621299d
3
+ size 3397645
AX615/yolov8s_640x640_npu1.axmodel ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:f8158f466b2cb8e8aebdc35cf27ceb55792b2d32c4d2f25a72568c7805a760ab
3
+ size 12468873
AX615/yolov8s_640x640_npu2.axmodel ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:794c436981a263431461f5b4c969ed613fea06c584f2977c7f5d4d984abd3640
3
+ size 11503501
AX620E/yolov8l_640x640_npu1.axmodel ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:31a202c34e0f9feb6e9c5395d10115271a59944507465d42a46fdd4abbb30b59
3
+ size 50315789
AX620E/yolov8l_640x640_npu2.axmodel ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:985cd993878a0786b9b9625972f109273e0557bbd4d02e14eac4903d54c13678
3
+ size 44955325
AX620E/yolov8m_640x640_npu1.axmodel ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:87ef023288128267d9de1ab0f685d475a54e801e213ef2400d2b3f315f7f3120
3
+ size 29841021
AX620E/yolov8m_640x640_npu2.axmodel ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:d55dcf21bdcfbfc5571afb10894484cfbd2b1142fe97432b1ea23d9966468a89
3
+ size 26738901
AX620E/yolov8n_640x640_npu1.axmodel ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:87d1d0029203056c9372bca4da68a396e2bf71914263ae8a3712668e1ef03d60
3
+ size 3810681
AX620E/yolov8n_640x640_npu2.axmodel ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:fb40333377b7f3444ce53fd9382d7d1d3a3e36bd87536614378bd2101a5218c5
3
+ size 3424381
AX620E/yolov8s_640x640_npu1.axmodel ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:cf2c4a73878be48aafb01316029b32043844b71408afc36329cf6d36e67c63c6
3
+ size 12639153
AX620E/yolov8s_640x640_npu2.axmodel ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:56ff92fb5c14d73c58e9d2f0573c04bf1c5e47cfe5b11ac316c3412aae19dfe8
3
+ size 11529925
AX620E/yolov8x_640x640_npu1.axmodel ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:664668e09033507a78d4185ef7a1de670959bca9e17dbfd6aa21aa730d33ffb4
3
+ size 80537453
AX620E/yolov8x_640x640_npu2.axmodel ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:c7a9ef5096de6fa6a8acc3fcb7fe10c7872ae58aadcafb73da7f9c2f03f2a45e
3
+ size 70628301
AX637/yolov8l_640x640_npu1.axmodel ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:c1bdff37d0c432d3b73215a7da9777742bfb25e24eeb7cffc0ea1a6eeb7b8883
3
+ size 44417625
AX637/yolov8m_640x640_npu1.axmodel ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:cf9e5ce79d61fbf4586f77794132be4dff296d2410348f337b0569ba2dd9fa9d
3
+ size 26311565
AX637/yolov8n_640x640_npu1.axmodel ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:3829468bd86c4f5bcf1595df7e1ebdf827ff5a824962745dccbd64a41237329e
3
+ size 3629097
AX637/yolov8s_640x640_npu1.axmodel ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:c818a96de1f8f921fe98388949dd4b5cdac559fd0e588aa43c87fa960bd78ed0
3
+ size 11394521
AX637/yolov8x_640x640_npu1.axmodel ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:120d6e1ba59ab9b7eb835ada8e2f6c658cd3b133a591098f1201d653d8da0dff
3
+ size 69938665
AX650/yolov8l_640x640_npu1.axmodel ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:077fd62f40e710c680e5dfaf3865ee32196818695a5b1d39d764b2f79b2df366
3
+ size 45101257
AX650/yolov8l_640x640_npu3.axmodel ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:fd19e855fffc6237d1e99e06cabd98b64448131ae0b6fa502ffee9f424d31e2c
3
+ size 45526493
AX650/yolov8m_640x640_npu1.axmodel ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:23583617c0c630a248feb7f27fd0b219c41ae373e2bb2d3b5ba06b022492c128
3
+ size 26735549
AX650/yolov8m_640x640_npu3.axmodel ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:da0ba156916b0ac626ab588f5de845f7c13692cbd5c6f5df8bf2d45bdfac2101
3
+ size 27064817
AX650/yolov8n_640x640_npu1.axmodel ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:5d1be0d0b0fcdbf6b0c6b097b124b51653c2c8347129beab519c59586cf42a87
3
+ size 3443549
AX650/yolov8n_640x640_npu3.axmodel ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:e5563cc868a98e9ee051cb9941844be934c55cd5a37264d10bff534dd613e86b
3
+ size 3700265
AX650/yolov8s_640x640_npu1.axmodel ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:aab82f706f0dec0a6e4244813ab1883d2b1291e348800437a488f1de23c2a905
3
+ size 11616925
AX650/yolov8s_640x640_npu3.axmodel ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:f112959508faa56c2d7b9a17e7ba48b9a0967bc95fb499cfc47993ce099fb0ce
3
+ size 11860681
AX650/yolov8x_640x640_npu1.axmodel ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:c13a043ea5ab6cd939841ce4aba4c071120df0b703ab5b185da34cfc398a7beb
3
+ size 70652329
AX650/yolov8x_640x640_npu3.axmodel ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:5c951cd2f7406c8f175010f64dbecdfafe3cc07d97065d026414622458a9fe7c
3
+ size 71141277
ax_infer.py ADDED
@@ -0,0 +1,230 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ # Usage: python ax_infer.py --model-path yolov8n_640x640.axmodel --test-img bus.jpg --img-save-path result_yolov8_det.jpg --score-thres 0.25 --nms-thres 0.7 --providers AxEngineExecutionProvider
3
+ import os
4
+ import cv2
5
+ import numpy as np
6
+ from time import time
7
+ import argparse
8
+ import logging
9
+ import axengine as ort
10
+
11
+ logging.basicConfig(
12
+ level=logging.DEBUG,
13
+ format='[%(name)s] [%(asctime)s.%(msecs)03d] [%(levelname)s] %(message)s',
14
+ datefmt='%H:%M:%S'
15
+ )
16
+ logger = logging.getLogger("YOLOv8-Det")
17
+
18
+
19
+ def infer_hw_layout(shape):
20
+ """Infer input height, width and layout from model input shape."""
21
+ shape = list(shape)
22
+ if len(shape) == 4 and shape[-1] == 3:
23
+ h = int(shape[1] or 640)
24
+ w = int(shape[2] or 640)
25
+ return h, w, "NHWC"
26
+ if len(shape) == 4 and shape[1] == 3:
27
+ h = int(shape[2] or 640)
28
+ w = int(shape[3] or 640)
29
+ return h, w, "NCHW"
30
+ return 640, 640, "NCHW"
31
+
32
+
33
+ def softmax(x, axis=-1):
34
+ """Compute softmax along axis."""
35
+ e_x = np.exp(x - np.max(x, axis=axis, keepdims=True))
36
+ return e_x / np.sum(e_x, axis=axis, keepdims=True)
37
+
38
+
39
+ def dfl_decode(box_pred, reg_max=16):
40
+ """Decode DFL (Distribution Focal Loss) box predictions to ltrb distances."""
41
+ N = box_pred.shape[0]
42
+ box_pred = box_pred.reshape(N, 4, reg_max)
43
+ box_pred = softmax(box_pred, axis=-1)
44
+ proj = np.arange(reg_max, dtype=np.float32)
45
+ return np.sum(box_pred * proj, axis=-1) # (N, 4)
46
+
47
+
48
+ def main():
49
+ ap = argparse.ArgumentParser(description='YOLOv8-Det Inference (AXERARuntime)')
50
+ ap.add_argument('--model-path', type=str, default='yolov8n_640x640.axmodel')
51
+ ap.add_argument('--test-img', type=str, default='bus.jpg')
52
+ ap.add_argument('--img-save-path', type=str, default='result_yolov8_det.jpg')
53
+ ap.add_argument('--score-thres', type=float, default=0.25)
54
+ ap.add_argument('--nms-thres', type=float, default=0.7)
55
+ ap.add_argument('--providers', type=str, default='AxEngineExecutionProvider')
56
+ opt = ap.parse_args()
57
+
58
+ if not os.path.exists(opt.model_path):
59
+ logger.error(f"Model not found: {opt.model_path}")
60
+ return
61
+
62
+ t0 = time()
63
+ providers = [p.strip() for p in opt.providers.split(",") if p.strip()] or None
64
+ sess = ort.InferenceSession(opt.model_path, providers=providers)
65
+ logger.debug(f"\033[1;31mLoad model time = {(time() - t0) * 1000:.2f} ms\033[0m")
66
+
67
+ inp = sess.get_inputs()[0]
68
+ input_name = inp.name
69
+ m_h, m_w, layout = infer_hw_layout(inp.shape)
70
+
71
+ img = cv2.imread(opt.test_img)
72
+ if img is None:
73
+ logger.error(f"Image not found or unreadable: {opt.test_img}")
74
+ return
75
+
76
+ # Preprocess
77
+ t0 = time()
78
+ orig_h, orig_w = img.shape[:2]
79
+ scale = min(m_h / orig_h, m_w / orig_w)
80
+ new_w, new_h = int(orig_w * scale), int(orig_h * scale)
81
+
82
+ resized = cv2.resize(img, (new_w, new_h), interpolation=cv2.INTER_LINEAR)
83
+ padded = cv2.copyMakeBorder(
84
+ resized, 0, m_h - new_h, 0, m_w - new_w,
85
+ cv2.BORDER_CONSTANT, value=(127, 127, 127)
86
+ )
87
+ rgb = cv2.cvtColor(padded, cv2.COLOR_BGR2RGB)
88
+ input_tensor = rgb[None, ...].astype(np.uint8) if layout == "NHWC" else np.transpose(rgb, (2, 0, 1))[None, ...].astype(np.uint8)
89
+ logger.debug(f"\033[1;31mPre-process time = {(time() - t0) * 1000:.2f} ms\033[0m")
90
+
91
+ # Inference
92
+ t0 = time()
93
+ ort_outputs = sess.run(None, {input_name: input_tensor})
94
+ out_metas = sess.get_outputs()
95
+ logger.debug(f"\033[1;31mForward time = {(time() - t0) * 1000:.2f} ms\033[0m")
96
+
97
+ # Post-process
98
+ t0 = time()
99
+ strides = (8, 16, 32)
100
+ conf_raw = -np.log(1 / opt.score_thres - 1)
101
+ detections = []
102
+
103
+ output_items = []
104
+ for meta, data in zip(out_metas, ort_outputs):
105
+ shape = list(meta.shape)
106
+ if any(s is None or isinstance(s, str) for s in shape):
107
+ shape = list(data.shape)
108
+ output_items.append((data, shape))
109
+
110
+ # Process each scale (6 outputs: 2 outputs per scale [box, cls])
111
+ for scale_idx, stride in enumerate(strides):
112
+ box_idx = scale_idx * 2
113
+ cls_idx = scale_idx * 2 + 1
114
+
115
+ if box_idx >= len(output_items) or cls_idx >= len(output_items):
116
+ continue
117
+
118
+ box_data, box_shape = output_items[box_idx]
119
+ cls_data, cls_shape = output_items[cls_idx]
120
+
121
+ H, W = box_shape[1], box_shape[2]
122
+ box_channels = box_shape[-1]
123
+
124
+ # Determine if DFL is used (YOLOv8: 4*reg_max = 64)
125
+ reg_max = None
126
+ if box_channels > 4 and box_channels % 4 == 0:
127
+ reg_max = box_channels // 4
128
+
129
+ box_data = box_data[0].reshape(-1, box_channels)
130
+ cls_data = cls_data[0].reshape(-1, cls_shape[-1])
131
+
132
+ # Get max class scores
133
+ cls_scores = np.max(cls_data, axis=1)
134
+ cls_ids = np.argmax(cls_data, axis=1)
135
+
136
+ valid_mask = cls_scores >= conf_raw
137
+ if not np.any(valid_mask):
138
+ continue
139
+
140
+ v_box = box_data[valid_mask]
141
+ v_score = 1 / (1 + np.exp(-cls_scores[valid_mask]))
142
+ v_id = cls_ids[valid_mask]
143
+
144
+ gy, gx = np.indices((H, W))
145
+ anchors = np.stack((gx.ravel(), gy.ravel()), axis=-1).astype(np.float32) + 0.5
146
+ anchors = anchors[valid_mask]
147
+
148
+ # Decode boxes (DFL -> ltrb -> xyxy)
149
+ if reg_max is not None:
150
+ v_box = dfl_decode(v_box, reg_max)
151
+ lt = v_box[:, :2]
152
+ rb = v_box[:, 2:]
153
+ x1y1 = anchors - lt
154
+ x2y2 = anchors + rb
155
+ boxes = np.hstack([x1y1, x2y2]) * stride
156
+
157
+ for i in range(len(boxes)):
158
+ detections.append([*boxes[i], v_score[i], v_id[i]])
159
+
160
+ logger.debug(f"\033[1;31mPost-process time = {(time() - t0) * 1000:.2f} ms\033[0m")
161
+
162
+ if len(detections) == 0:
163
+ logger.info("No detections found.")
164
+ cv2.imwrite(opt.img_save_path, img)
165
+ return
166
+
167
+ detections = np.array(detections)
168
+
169
+ # NMS
170
+ xywh = detections[:, :4].copy()
171
+ xywh[:, 2] = xywh[:, 2] - xywh[:, 0] # w
172
+ xywh[:, 3] = xywh[:, 3] - xywh[:, 1] # h
173
+
174
+ indices = cv2.dnn.NMSBoxes(xywh.tolist(), detections[:, 4].tolist(), opt.score_thres, opt.nms_thres)
175
+
176
+ if len(indices) == 0:
177
+ logger.info("No detections after NMS.")
178
+ cv2.imwrite(opt.img_save_path, img)
179
+ return
180
+
181
+ indices = indices.flatten()
182
+ final_dets = detections[indices]
183
+
184
+ # Scale to original image coordinates
185
+ final_dets[:, :4] = final_dets[:, :4] / scale
186
+ final_dets[:, [0, 2]] = np.clip(final_dets[:, [0, 2]], 0, orig_w)
187
+ final_dets[:, [1, 3]] = np.clip(final_dets[:, [1, 3]], 0, orig_h)
188
+
189
+ # COCO class names
190
+ coco_names = [
191
+ "person", "bicycle", "car", "motorcycle", "airplane", "bus", "train", "truck", "boat", "traffic light",
192
+ "fire hydrant", "stop sign", "parking meter", "bench", "bird", "cat", "dog", "horse", "sheep", "cow",
193
+ "elephant", "bear", "zebra", "giraffe", "backpack", "umbrella", "handbag", "tie", "suitcase", "frisbee",
194
+ "skis", "snowboard", "sports ball", "kite", "baseball bat", "baseball glove", "skateboard", "surfboard",
195
+ "tennis racket", "bottle", "wine glass", "cup", "fork", "knife", "spoon", "bowl", "banana", "apple",
196
+ "sandwich", "orange", "broccoli", "carrot", "hot dog", "pizza", "donut", "cake", "chair", "couch",
197
+ "potted plant", "bed", "dining table", "toilet", "tv", "laptop", "mouse", "remote", "keyboard",
198
+ "cell phone", "microwave", "oven", "toaster", "sink", "refrigerator", "book", "clock", "vase",
199
+ "scissors", "teddy bear", "hair drier", "toothbrush"
200
+ ]
201
+
202
+ base_colors = [
203
+ (255, 42, 4), (235, 219, 11), (243, 243, 243), (183, 223, 0), (104, 31, 17),
204
+ (221, 111, 255), (79, 68, 255), (0, 237, 204), (68, 243, 0), (255, 0, 189),
205
+ (255, 180, 0), (186, 0, 221), (255, 255, 0), (0, 192, 38), (179, 255, 1),
206
+ (255, 36, 125), (104, 0, 123), (108, 27, 255), (47, 109, 252), (11, 255, 162),
207
+ ]
208
+
209
+ logger.info(f"\033[1;32mDraw Results ({len(final_dets)} objects): \033[0m")
210
+
211
+ for det in final_dets:
212
+ box = det[:4].astype(int)
213
+ conf = det[4]
214
+ cls_id = int(det[5])
215
+ color = [int(c) for c in base_colors[cls_id % len(base_colors)]]
216
+ cls_name = coco_names[cls_id] if cls_id < len(coco_names) else str(cls_id)
217
+
218
+ logger.info(f"({box[0]}, {box[1]}, {box[2]}, {box[3]}) -> {cls_name}: {conf:.2f}")
219
+
220
+ cv2.rectangle(img, (box[0], box[1]), (box[2], box[3]), color, 2)
221
+ label = f"{cls_name} {conf:.2f}"
222
+ cv2.putText(img, label, (box[0], box[1] - 10),
223
+ cv2.FONT_HERSHEY_SIMPLEX, 0.5, color, 2)
224
+
225
+ cv2.imwrite(opt.img_save_path, img)
226
+ logger.info(f"Saved to {opt.img_save_path}")
227
+
228
+
229
+ if __name__ == "__main__":
230
+ main()
bus.jpg ADDED

Git LFS Details

  • SHA256: 33b198a1d2839bb9ac4c65d61f9e852196793cae9a0781360859425f6022b69c
  • Pointer size: 131 Bytes
  • Size of remote file: 487 kB
coco_1000.tar ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:f3e18a198658270e19ced079de7a404e3478e69c2ef94fb47c87ddf056e6a541
3
+ size 163112960
config.json ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "model_type": "ONNX",
3
+ "npu_mode": "NPU3",
4
+ "quant": {
5
+ "input_configs": [
6
+ {
7
+ "tensor_name": "images",
8
+ "calibration_dataset": "./coco_1000.tar",
9
+ "calibration_size": 32,
10
+ "calibration_mean": [0, 0, 0],
11
+ "calibration_std": [255.0, 255.0, 255.0]
12
+ }
13
+ ],
14
+ "calibration_method": "MinMax",
15
+ "precision_analysis": true,
16
+ "precision_analysis_method":"EndToEnd"
17
+ },
18
+ "input_processors": [
19
+ {
20
+ "tensor_name": "images",
21
+ "tensor_format": "BGR",
22
+ "src_format": "BGR",
23
+ "src_dtype": "U8",
24
+ "src_layout": "NHWC"
25
+ }
26
+ ],
27
+ "output_processors": [
28
+ ],
29
+ "compiler": {
30
+ "check": 0
31
+ }
32
+ }
export_onnx.py ADDED
@@ -0,0 +1,91 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ import torch
3
+ from ultralytics import YOLO
4
+ from ultralytics.nn.modules.head import Detect
5
+ import os
6
+ import shutil
7
+
8
+
9
+ def npu_detect_forward(self, x):
10
+ """
11
+ YOLOv8 Detect Head Modified for NPU.
12
+
13
+ YOLOv8 Detect structure (NOT end2end):
14
+ - cv2: box regression layers (DFL, out channels = 4 * reg_max = 64)
15
+ - cv3: classification layers (out channels = nc, nc=80 for COCO)
16
+
17
+ Output:
18
+ List of Tensors (6 items for 3 scales), Layout: NHWC.
19
+ For each scale:
20
+ - Box_Raw (B, H, W, 4*reg_max), <-- raw DFL box logits (decode in post-process)
21
+ - Cls_Raw (B, H, W, nc), <-- class scores (raw logits), nc=80
22
+ """
23
+ if not isinstance(x, (list, tuple)):
24
+ x = [x]
25
+
26
+ res = []
27
+
28
+ box_layers = self.cv2
29
+ cls_layers = self.cv3
30
+
31
+ for i in range(self.nl):
32
+ # 1. Box branch (raw DFL logits) - NHWC
33
+ bboxes = box_layers[i](x[i]).permute(0, 2, 3, 1)
34
+
35
+ # 2. Cls branch (raw logits) - NHWC
36
+ scores = cls_layers[i](x[i]).permute(0, 2, 3, 1)
37
+
38
+ res.append(bboxes)
39
+ res.append(scores)
40
+
41
+ return res
42
+
43
+
44
+ def batch_export_yolov8_det():
45
+ variants = ['n', 's', 'm', 'l', 'x']
46
+ imgsz = 640
47
+
48
+ # Execute Monkey Patch
49
+ Detect.forward = npu_detect_forward
50
+ print("Monkey patch applied for Detect: Output Layout forced to NHWC (Box, Cls for each scale).")
51
+
52
+ for v in variants:
53
+ model_name = f"yolov8{v}"
54
+ pt_path = f"{model_name}.pt"
55
+ onnx_final_name = f"{model_name}_640x640.onnx"
56
+ print(f"\n--- Processing {model_name} ---")
57
+ try:
58
+ # Load model
59
+ model = YOLO(pt_path)
60
+
61
+ # Reapply monkey patch
62
+ Detect.forward = npu_detect_forward
63
+
64
+ # Ensure the model's head also uses the new forward
65
+ if hasattr(model.model, 'model') and len(model.model.model) > 0:
66
+ head = model.model.model[-1]
67
+ if isinstance(head, Detect):
68
+ head.forward = lambda x: npu_detect_forward(head, x)
69
+
70
+ # Execute export
71
+ exported_path = model.export(
72
+ format="onnx",
73
+ imgsz=imgsz,
74
+ dynamic=False,
75
+ opset=11,
76
+ simplify=True,
77
+ nms=False
78
+ )
79
+
80
+ # Move and rename
81
+ if exported_path:
82
+ shutil.move(exported_path, onnx_final_name)
83
+ print(f"Success: {onnx_final_name}")
84
+ except Exception as e:
85
+ print(f"Failed to export {model_name}: {e}")
86
+ import traceback
87
+ traceback.print_exc()
88
+
89
+
90
+ if __name__ == "__main__":
91
+ batch_export_yolov8_det()
onnx_infer.py ADDED
@@ -0,0 +1,269 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ import onnxruntime as ort
3
+ import cv2
4
+ import numpy as np
5
+ import argparse
6
+ import os
7
+
8
+
9
+ def preprocess_image(image, input_size=(640, 640)):
10
+ """
11
+ Preprocess image with left-top aligned letterbox (same as official YOLO).
12
+
13
+ Args:
14
+ image: BGR image (H, W, C)
15
+ input_size: (height, width) target size
16
+
17
+ Returns:
18
+ input_tensor: (1, 3, H, W) float32 tensor normalized to [0, 1]
19
+ scale: scale ratio used for resizing
20
+ original_shape: (orig_h, orig_w) original image shape
21
+ """
22
+ orig_h, orig_w = image.shape[:2]
23
+ m_h, m_w = input_size
24
+
25
+ # Calculate scale (keep aspect ratio)
26
+ scale = min(m_h / orig_h, m_w / orig_w)
27
+
28
+ # Resize
29
+ new_w, new_h = int(orig_w * scale), int(orig_h * scale)
30
+ img_resized = cv2.resize(image, (new_w, new_h), interpolation=cv2.INTER_LINEAR)
31
+
32
+ # Pad to target size (left-top aligned)
33
+ input_bgr = cv2.copyMakeBorder(
34
+ img_resized, 0, m_h - new_h, 0, m_w - new_w,
35
+ cv2.BORDER_CONSTANT, value=(114, 114, 114)
36
+ )
37
+
38
+ # BGR -> RGB, normalize to [0, 1]
39
+ input_rgb = cv2.cvtColor(input_bgr, cv2.COLOR_BGR2RGB).astype(np.float32) / 255.0
40
+
41
+ # HWC -> CHW, add batch dimension
42
+ input_tensor = np.transpose(input_rgb, (2, 0, 1))[None, ...]
43
+
44
+ return input_tensor, scale, (orig_h, orig_w)
45
+
46
+
47
+ def softmax(x, axis=-1):
48
+ """Compute softmax along axis."""
49
+ e_x = np.exp(x - np.max(x, axis=axis, keepdims=True))
50
+ return e_x / np.sum(e_x, axis=axis, keepdims=True)
51
+
52
+
53
+ def dfl_decode(box_pred, reg_max=16):
54
+ """
55
+ Decode DFL (Distribution Focal Loss) box predictions.
56
+
57
+ Args:
58
+ box_pred: (N, 4 * reg_max) raw box predictions
59
+ reg_max: number of DFL bins
60
+
61
+ Returns:
62
+ (N, 4) decoded ltrb distances
63
+ """
64
+ N = box_pred.shape[0]
65
+ box_pred = box_pred.reshape(N, 4, reg_max)
66
+ box_pred = softmax(box_pred, axis=-1)
67
+ proj = np.arange(reg_max, dtype=np.float32)
68
+ return np.sum(box_pred * proj, axis=-1) # (N, 4)
69
+
70
+
71
+ def decode_bboxes(bbox_preds, anchors, stride, reg_max=None):
72
+ """
73
+ Decode bounding boxes from predictions.
74
+
75
+ Args:
76
+ bbox_preds: (N, 4) or (N, 4*reg_max) - distance predictions in ltrb format
77
+ anchors: (N, 2) - anchor points (x, y) with offset 0.5
78
+ stride: scalar - stride value
79
+ reg_max: if not None, apply DFL decoding first
80
+
81
+ Returns:
82
+ boxes: (N, 4) in xyxy format
83
+ """
84
+ if reg_max is not None and bbox_preds.shape[-1] == 4 * reg_max:
85
+ bbox_preds = dfl_decode(bbox_preds, reg_max)
86
+
87
+ # dist2bbox: ltrb to xyxy
88
+ lt = bbox_preds[:, :2] # left, top
89
+ rb = bbox_preds[:, 2:] # right, bottom
90
+
91
+ x1y1 = anchors - lt
92
+ x2y2 = anchors + rb
93
+
94
+ boxes = np.hstack([x1y1, x2y2]) * stride
95
+ return boxes
96
+
97
+
98
+ def scale_boxes_lefttop(boxes, scale, orig_shape):
99
+ """Scale boxes from model output to original image coordinates."""
100
+ boxes = boxes.copy()
101
+ boxes[..., :4] /= scale
102
+ boxes[..., [0, 2]] = np.clip(boxes[..., [0, 2]], 0, orig_shape[1])
103
+ boxes[..., [1, 3]] = np.clip(boxes[..., [1, 3]], 0, orig_shape[0])
104
+ return boxes
105
+
106
+
107
+ def main():
108
+ parser = argparse.ArgumentParser(description='YOLOv8-Det ONNX Inference')
109
+ parser.add_argument('-m', '--model', type=str, default='yolov8n_640x640.onnx',
110
+ dest='model_path', help='Path to YOLOv8 Detection *.onnx Model.')
111
+ parser.add_argument('-i', '--img', type=str, default='bus.jpg',
112
+ dest='test_img', help='Path to Test Image.')
113
+ parser.add_argument('-o', '--output', type=str, default='result_yolov8_det.jpg',
114
+ dest='img_save_path', help='Path to Save Result Image.')
115
+ parser.add_argument('--score-thres', type=float, default=0.25,
116
+ help='Confidence threshold.')
117
+ parser.add_argument('--nms-thres', type=float, default=0.7,
118
+ help='IoU threshold for NMS.')
119
+ opt = parser.parse_args()
120
+
121
+ if not os.path.exists(opt.model_path):
122
+ print(f"Error: Model not found: {opt.model_path}")
123
+ return
124
+
125
+ if not os.path.exists(opt.test_img):
126
+ print(f"Error: Image not found: {opt.test_img}")
127
+ return
128
+
129
+ # Load ONNX model
130
+ providers = ['CUDAExecutionProvider', 'CPUExecutionProvider']
131
+ try:
132
+ session = ort.InferenceSession(opt.model_path, providers=providers)
133
+ except:
134
+ session = ort.InferenceSession(opt.model_path, providers=['CPUExecutionProvider'])
135
+
136
+ input_name = session.get_inputs()[0].name
137
+ output_names = [o.name for o in session.get_outputs()]
138
+ input_shape = session.get_inputs()[0].shape
139
+ imgsz = (input_shape[2], input_shape[3])
140
+
141
+ # Load image
142
+ img0 = cv2.imread(opt.test_img)
143
+ if img0 is None:
144
+ print(f"Error: Cannot read image: {opt.test_img}")
145
+ return
146
+
147
+ # Preprocess
148
+ img, scale, orig_shape = preprocess_image(img0.copy(), imgsz)
149
+
150
+ # Inference
151
+ outputs = session.run(output_names, {input_name: img})
152
+
153
+ # Post-process
154
+ strides = [8, 16, 32]
155
+ conf_raw = -np.log(1 / opt.score_thres - 1)
156
+ detections = []
157
+
158
+ # Process each scale (6 outputs: 2 outputs per scale [box, cls])
159
+ for scale_idx, stride in enumerate(strides):
160
+ box_idx = scale_idx * 2
161
+ cls_idx = scale_idx * 2 + 1
162
+
163
+ if box_idx >= len(outputs) or cls_idx >= len(outputs):
164
+ continue
165
+
166
+ box_data = outputs[box_idx] # (1, H, W, C) where C = 4 or 4*reg_max
167
+ cls_data = outputs[cls_idx] # (1, H, W, nc)
168
+
169
+ H, W = box_data.shape[1:3]
170
+ box_channels = box_data.shape[-1]
171
+
172
+ # Determine if DFL is used (YOLOv8: 4*reg_max = 64)
173
+ reg_max = None
174
+ if box_channels > 4 and box_channels % 4 == 0:
175
+ reg_max = box_channels // 4
176
+
177
+ # Reshape to (H*W, ...)
178
+ box_data = box_data[0].reshape(-1, box_channels)
179
+ cls_data = cls_data[0].reshape(-1, cls_data.shape[-1])
180
+
181
+ # Get max class scores
182
+ cls_scores = np.max(cls_data, axis=1)
183
+ cls_ids = np.argmax(cls_data, axis=1)
184
+
185
+ # Filter by confidence (on raw logits)
186
+ valid_mask = cls_scores >= conf_raw
187
+ if not np.any(valid_mask):
188
+ continue
189
+
190
+ v_box = box_data[valid_mask]
191
+ v_score = 1 / (1 + np.exp(-cls_scores[valid_mask]))
192
+ v_id = cls_ids[valid_mask]
193
+
194
+ # Generate anchors for this scale (grid indices + 0.5)
195
+ gy, gx = np.indices((H, W))
196
+ anchors = np.stack((gx.ravel(), gy.ravel()), axis=-1).astype(np.float32) + 0.5
197
+ anchors = anchors[valid_mask]
198
+
199
+ # Decode boxes
200
+ boxes = decode_bboxes(v_box, anchors, stride, reg_max)
201
+
202
+ # Store detections
203
+ for i in range(len(boxes)):
204
+ detections.append([*boxes[i], v_score[i], v_id[i]])
205
+
206
+ if len(detections) == 0:
207
+ print("No detections found.")
208
+ cv2.imwrite(opt.img_save_path, img0)
209
+ return
210
+
211
+ detections = np.array(detections)
212
+
213
+ # NMS
214
+ xywh = detections[:, :4].copy()
215
+ xywh[:, 2] = xywh[:, 2] - xywh[:, 0] # w
216
+ xywh[:, 3] = xywh[:, 3] - xywh[:, 1] # h
217
+
218
+ indices = cv2.dnn.NMSBoxes(xywh.tolist(), detections[:, 4].tolist(), opt.score_thres, opt.nms_thres)
219
+
220
+ if len(indices) == 0:
221
+ print("No detections after NMS.")
222
+ cv2.imwrite(opt.img_save_path, img0)
223
+ return
224
+
225
+ indices = indices.flatten()
226
+ detections = detections[indices]
227
+
228
+ # Scale to original image
229
+ detections[:, :4] = scale_boxes_lefttop(detections[:, :4], scale, orig_shape)
230
+
231
+ # COCO class names
232
+ coco_names = [
233
+ "person", "bicycle", "car", "motorcycle", "airplane", "bus", "train", "truck", "boat", "traffic light",
234
+ "fire hydrant", "stop sign", "parking meter", "bench", "bird", "cat", "dog", "horse", "sheep", "cow",
235
+ "elephant", "bear", "zebra", "giraffe", "backpack", "umbrella", "handbag", "tie", "suitcase", "frisbee",
236
+ "skis", "snowboard", "sports ball", "kite", "baseball bat", "baseball glove", "skateboard", "surfboard",
237
+ "tennis racket", "bottle", "wine glass", "cup", "fork", "knife", "spoon", "bowl", "banana", "apple",
238
+ "sandwich", "orange", "broccoli", "carrot", "hot dog", "pizza", "donut", "cake", "chair", "couch",
239
+ "potted plant", "bed", "dining table", "toilet", "tv", "laptop", "mouse", "remote", "keyboard",
240
+ "cell phone", "microwave", "oven", "toaster", "sink", "refrigerator", "book", "clock", "vase",
241
+ "scissors", "teddy bear", "hair drier", "toothbrush"
242
+ ]
243
+
244
+ # Official Ultralytics colors (BGR format)
245
+ base_colors = [
246
+ (255, 42, 4), (235, 219, 11), (243, 243, 243), (183, 223, 0), (104, 31, 17),
247
+ (221, 111, 255), (79, 68, 255), (0, 237, 204), (68, 243, 0), (255, 0, 189),
248
+ (255, 180, 0), (186, 0, 221), (255, 255, 0), (0, 192, 38), (179, 255, 1),
249
+ (255, 36, 125), (104, 0, 123), (108, 27, 255), (47, 109, 252), (11, 255, 162),
250
+ ]
251
+
252
+ for det in detections:
253
+ box = det[:4].astype(int)
254
+ conf = det[4]
255
+ cls_id = int(det[5])
256
+ color = [int(c) for c in base_colors[cls_id % len(base_colors)]]
257
+ cls_name = coco_names[cls_id] if cls_id < len(coco_names) else str(cls_id)
258
+
259
+ cv2.rectangle(img0, (box[0], box[1]), (box[2], box[3]), color, 2)
260
+ label = f"{cls_name} {conf:.2f}"
261
+ cv2.putText(img0, label, (box[0], box[1] - 10),
262
+ cv2.FONT_HERSHEY_SIMPLEX, 0.5, color, 2)
263
+
264
+ cv2.imwrite(opt.img_save_path, img0)
265
+ print(f"Done! Found {len(detections)} objects. Result saved to {opt.img_save_path}")
266
+
267
+
268
+ if __name__ == "__main__":
269
+ main()
result_yolov8_det.jpg ADDED

Git LFS Details

  • SHA256: 8e4a57010ca18c66555d217dc797d03c5a43e34703c6da5b8c3a8be941e90e51
  • Pointer size: 131 Bytes
  • Size of remote file: 491 kB
yolov8l_640x640.onnx ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:848ed042b6aae973feef19605808fb964a60ef13e032e1010a54a772c4364332
3
+ size 174782655
yolov8m_640x640.onnx ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:61fae246d49e5a395d8ddd694a7212cdbcf2be76a2f97d1d80fc011a333e6207
3
+ size 103631997
yolov8n_640x640.onnx ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:3e006d4f9b2b77b0b1846cf8104f9de620419dfa3ab63d651426ab25e50444aa
3
+ size 12673498
yolov8s_640x640.onnx ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:7dcda830f3390e95453076524f56b074cd201ec0044e797a84ed2304a4fe3ec7
3
+ size 44692292
yolov8x_640x640.onnx ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:1a5ef92546eabe7794d0d9f10f6cdea7f84e27a993f667b1d8e47f19810650bd
3
+ size 272911938