@camstack/addon-pipeline 1.1.4 → 1.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/audio-analyzer/index.js +16 -15
- package/dist/audio-analyzer/index.mjs +16 -15
- package/dist/audio-codec-nodeav/index.js +1 -1
- package/dist/audio-codec-nodeav/index.mjs +1 -1
- package/dist/decoder-nodeav/index.js +1 -1
- package/dist/decoder-nodeav/index.mjs +1 -1
- package/dist/detection-pipeline/index.js +195 -38
- package/dist/detection-pipeline/index.mjs +195 -38
- package/dist/{dist-OlOI9pHn.js → dist-BhpOMzzH.js} +28 -4
- package/dist/{dist-CAgJixja.mjs → dist-GFzs5acw.mjs} +28 -4
- package/dist/motion-wasm/index.js +1 -1
- package/dist/motion-wasm/index.mjs +1 -1
- package/dist/pipeline-runner/index.js +1 -1
- package/dist/pipeline-runner/index.mjs +1 -1
- package/dist/recorder/index.js +1 -1
- package/dist/recorder/index.mjs +1 -1
- package/dist/stream-broker/_stub.js +2 -2
- package/dist/stream-broker/{_virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-D08yXBHc.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-DQYrh0ie.mjs} +3 -3
- package/dist/stream-broker/{_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-FRD2eBuz.mjs → _virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-S6ETjGtN.mjs} +1 -1
- package/dist/stream-broker/{_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-CHcXI1Wf.mjs → _virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-5vetl3CL.mjs} +1 -1
- package/dist/stream-broker/{hostInit-DPGCWkwA.mjs → hostInit-DvWdWFSe.mjs} +3 -3
- package/dist/stream-broker/index.js +1 -1
- package/dist/stream-broker/index.mjs +1 -1
- package/dist/stream-broker/remoteEntry.js +1 -1
- package/embed-dist/assets/{MaskShapeCanvas-DI4BY7W2-Ds2bhSfK.js → MaskShapeCanvas-DI4BY7W2-Bulflbu5.js} +1 -1
- package/embed-dist/assets/{MotionZonesSettings-NcxxQN8r-W7yVVry1.js → MotionZonesSettings-NcxxQN8r-DJ9keq4q.js} +1 -1
- package/embed-dist/assets/{PrivacyMaskSettings-APgPLF7p-30DllvBT.js → PrivacyMaskSettings-APgPLF7p-CRsjkTB1.js} +1 -1
- package/embed-dist/assets/{index-D8CZDqZG.js → index-DBB2e2P1.js} +9 -9
- package/embed-dist/index.html +1 -1
- package/package.json +1 -1
- package/python/postprocessors/__init__.py +2 -0
- package/python/postprocessors/clip.py +35 -0
- package/python/postprocessors/test_clip.py +33 -0
package/embed-dist/index.html
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
<meta charset="utf-8" />
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
6
6
|
<title>CamStack Embed</title>
|
|
7
|
-
<script type="module" crossorigin src="./assets/index-
|
|
7
|
+
<script type="module" crossorigin src="./assets/index-DBB2e2P1.js"></script>
|
|
8
8
|
<link rel="stylesheet" crossorigin href="./assets/index-ZhDdp1Nd.css">
|
|
9
9
|
</head>
|
|
10
10
|
<body>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@camstack/addon-pipeline",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.5",
|
|
4
4
|
"description": "CamStack Pipeline bundle — runner, detection, motion, decoders, audio + stream broker. Multi-entry npm package shipping 7 addons under a single bundle.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"camstack",
|
|
@@ -7,6 +7,7 @@ from .yolo import postprocess_yolo
|
|
|
7
7
|
from .yolo_seg import postprocess_yolo_seg
|
|
8
8
|
from .scrfd import postprocess_scrfd
|
|
9
9
|
from .arcface import postprocess_arcface
|
|
10
|
+
from .clip import postprocess_clip
|
|
10
11
|
from .softmax import postprocess_softmax
|
|
11
12
|
from .ctc import postprocess_ctc
|
|
12
13
|
from .saliency import postprocess_saliency
|
|
@@ -17,6 +18,7 @@ POSTPROCESSORS = {
|
|
|
17
18
|
"yolo-seg": postprocess_yolo_seg,
|
|
18
19
|
"scrfd": postprocess_scrfd,
|
|
19
20
|
"arcface": postprocess_arcface,
|
|
21
|
+
"clip": postprocess_clip,
|
|
20
22
|
"softmax": postprocess_softmax,
|
|
21
23
|
"ctc": postprocess_ctc,
|
|
22
24
|
"saliency": postprocess_saliency,
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"""CLIP image embedding postprocessor.
|
|
2
|
+
|
|
3
|
+
Input: raw embedding tensor from a CLIP vision encoder (e.g. MobileCLIP S0/S1/S2)
|
|
4
|
+
Output: {"kind": "embedding", "embedding": [...], "embeddingNorm": [...]}
|
|
5
|
+
|
|
6
|
+
MobileCLIP uses resize 256×256 + rescale /255 only (no ImageNet mean/std).
|
|
7
|
+
The existing inference_pool resize_image path already produces this layout —
|
|
8
|
+
preprocessMode:'resize' + inputNormalization:'none' is the correct config.
|
|
9
|
+
"""
|
|
10
|
+
import numpy as np
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def postprocess_clip(
|
|
14
|
+
predictions: dict,
|
|
15
|
+
config: dict,
|
|
16
|
+
orig_w: int,
|
|
17
|
+
orig_h: int,
|
|
18
|
+
scale: float,
|
|
19
|
+
pad: tuple[int, int],
|
|
20
|
+
) -> dict:
|
|
21
|
+
"""L2-normalize the CLIP embedding vector."""
|
|
22
|
+
# Get the first output tensor (vision encoder emits a single embedding)
|
|
23
|
+
raw = np.array(list(predictions.values())[0]).flatten().astype(np.float32)
|
|
24
|
+
|
|
25
|
+
norm = np.linalg.norm(raw)
|
|
26
|
+
if norm == 0:
|
|
27
|
+
normalized = np.zeros_like(raw)
|
|
28
|
+
else:
|
|
29
|
+
normalized = raw / norm
|
|
30
|
+
|
|
31
|
+
return {
|
|
32
|
+
"kind": "embedding",
|
|
33
|
+
"embedding": raw.tolist(),
|
|
34
|
+
"embeddingNorm": normalized.tolist(),
|
|
35
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"""Tests for the CLIP embedding postprocessor."""
|
|
2
|
+
import numpy as np
|
|
3
|
+
import pytest
|
|
4
|
+
from postprocessors.clip import postprocess_clip
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def test_clip_output_kind() -> None:
|
|
8
|
+
vec = np.ones(512, dtype=np.float32)
|
|
9
|
+
predictions = {"output": vec.reshape(1, 512)}
|
|
10
|
+
result = postprocess_clip(predictions, {}, 640, 480, 1.0, (0, 0))
|
|
11
|
+
assert result["kind"] == "embedding"
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def test_clip_embedding_length() -> None:
|
|
15
|
+
vec = np.ones(512, dtype=np.float32)
|
|
16
|
+
predictions = {"output": vec.reshape(1, 512)}
|
|
17
|
+
result = postprocess_clip(predictions, {}, 640, 480, 1.0, (0, 0))
|
|
18
|
+
assert len(result["embedding"]) == 512
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def test_clip_embedding_norm_is_unit() -> None:
|
|
22
|
+
vec = np.array([3.0, 4.0] + [0.0] * 510, dtype=np.float32)
|
|
23
|
+
predictions = {"output": vec.reshape(1, 512)}
|
|
24
|
+
result = postprocess_clip(predictions, {}, 640, 480, 1.0, (0, 0))
|
|
25
|
+
norm = float(np.linalg.norm(result["embeddingNorm"]))
|
|
26
|
+
assert abs(norm - 1.0) < 1e-5
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def test_clip_zero_vector_does_not_divide_by_zero() -> None:
|
|
30
|
+
vec = np.zeros(512, dtype=np.float32)
|
|
31
|
+
predictions = {"output": vec.reshape(1, 512)}
|
|
32
|
+
result = postprocess_clip(predictions, {}, 640, 480, 1.0, (0, 0))
|
|
33
|
+
assert all(v == 0.0 for v in result["embeddingNorm"])
|