Sudabaka commited on
Commit
abf6b4e
·
verified ·
1 Parent(s): 5303c9b

docs: 补充完整的 ONNX 调用教程(预处理规范、批量推理、阈值调法与常见问题)

Browse files
Files changed (1) hide show
  1. example_infer.py +90 -24
example_infer.py CHANGED
@@ -1,24 +1,90 @@
1
- """Easy4K SFDP · Siamese NET AI 推理示例(DirectML / CPU 自动选择)。"""
2
- import sys
3
- import numpy as np
4
- import onnxruntime as ort
5
-
6
-
7
- def make_session(model_path="model.onnx"):
8
- return ort.InferenceSession(model_path, providers=["DmlExecutionProvider", "CPUExecutionProvider"])
9
-
10
-
11
- def score(sess, gray_a, gray_b):
12
- def prep(x):
13
- x = np.asarray(x, dtype=np.float32)
14
- if x.max() > 1.5:
15
- x = x / 255.0
16
- return x.reshape(1, 1, 128, 128)
17
- return float(sess.run(["score"], {"frame_a": prep(gray_a), "frame_b": prep(gray_b)})[0][0, 0])
18
-
19
-
20
- if __name__ == "__main__":
21
- s = make_session(sys.argv[1] if len(sys.argv) > 1 else "model.onnx")
22
- a = np.zeros((128, 128), np.uint8)
23
- print("same ->", score(s, a, a))
24
- print("noise ->", score(s, a, np.random.randint(0, 255, (128, 128), np.uint8)))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Easy4K SFDP · Siamese NET AI 推理示例。
2
+
3
+ 用法:
4
+ python example_infer.py [模型文件] [可选:视频文件]
5
+
6
+ 不传视频时用合成数据自检;传视频时对首两帧取同位置块做判重演示。
7
+ """
8
+ import sys
9
+
10
+ import numpy as np
11
+ import onnxruntime as ort
12
+
13
+ SIZE = 128
14
+ THRESHOLD = 0.5
15
+
16
+
17
+ def make_session(model_path="model.onnx"):
18
+ """DirectML 可用就用 GPU,否则自动回退 CPU。"""
19
+ avail = ort.get_available_providers()
20
+ providers = [p for p in ("DmlExecutionProvider", "CPUExecutionProvider") if p in avail]
21
+ sess = ort.InferenceSession(model_path, providers=providers)
22
+ print("providers:", sess.get_providers())
23
+ return sess
24
+
25
+
26
+ def prep(patch):
27
+ """灰度块 -> (1, 1, 128, 128) float32,值域 [0, 1]。"""
28
+ x = np.asarray(patch, dtype=np.float32)
29
+ if x.max() > 1.5: # 传入的是 0~255 时自动归一化
30
+ x = x / 255.0
31
+ if x.ndim == 3: # 兼容传入灰度单通道 (128,128,1)
32
+ x = x[..., 0]
33
+ return x.reshape(1, 1, SIZE, SIZE)
34
+
35
+
36
+ def score(sess, gray_a, gray_b):
37
+ a, b = prep(gray_a), prep(gray_b)
38
+ return float(sess.run(["score"], {"frame_a": a, "frame_b": b})[0][0, 0])
39
+
40
+
41
+ def score_batch(sess, pairs_a, pairs_b):
42
+ """批量推理:pairs 形状 (N, 128, 128),返回 (N,) 分数。"""
43
+ a = np.stack([prep(p).reshape(SIZE, SIZE) for p in pairs_a], axis=0).astype(np.float32)
44
+ b = np.stack([prep(p).reshape(SIZE, SIZE) for p in pairs_b], axis=0).astype(np.float32)
45
+ a = a[:, None, :, :]
46
+ b = b[:, None, :, :]
47
+ return sess.run(["score"], {"frame_a": a, "frame_b": b})[0].ravel()
48
+
49
+
50
+ def crop(gray, x, y):
51
+ p = gray[y:y + SIZE, x:x + SIZE]
52
+ return p if p.shape[:2] == (SIZE, SIZE) else None
53
+
54
+
55
+ def main():
56
+ model = sys.argv[1] if len(sys.argv) > 1 else "model.onnx"
57
+ video = sys.argv[2] if len(sys.argv) > 2 else None
58
+ sess = make_session(model)
59
+
60
+ if not video:
61
+ base = np.random.randint(0, 255, (SIZE, SIZE), np.uint8)
62
+ print("same ->", round(score(sess, base, base), 4))
63
+ print("noise ->", round(score(sess, base, np.random.randint(0, 255, (SIZE, SIZE), np.uint8)), 4))
64
+ pairs = [base] * 4
65
+ print("batch ->", np.round(score_batch(sess, pairs, pairs), 4))
66
+ return
67
+
68
+ import cv2
69
+
70
+ cap = cv2.VideoCapture(video)
71
+ ok1, f1 = cap.read()
72
+ ok2, f2 = cap.read()
73
+ cap.release()
74
+ if not (ok1 and ok2):
75
+ raise SystemExit("视频读取失败")
76
+
77
+ g1 = cv2.cvtColor(f1, cv2.COLOR_BGR2GRAY)
78
+ g2 = cv2.cvtColor(f2, cv2.COLOR_BGR2GRAY)
79
+
80
+ h, w = g1.shape
81
+ a, b = crop(g1, (w - SIZE) // 2, (h - SIZE) // 2), crop(g2, (w - SIZE) // 2, (h - SIZE) // 2)
82
+ if a is None:
83
+ raise SystemExit("视频分辨率小于 128x128")
84
+
85
+ s = score(sess, a, b)
86
+ print("score =", round(s, 4), "| duplicate" if s >= THRESHOLD else "| different")
87
+
88
+
89
+ if __name__ == "__main__":
90
+ main()