pyzm 2.3.3__tar.gz → 2.3.4__tar.gz
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.
- {pyzm-2.3.3/pyzm.egg-info → pyzm-2.3.4}/PKG-INFO +3 -3
- {pyzm-2.3.3 → pyzm-2.3.4}/README.md +2 -2
- {pyzm-2.3.3 → pyzm-2.3.4}/pyzm/__init__.py +1 -1
- {pyzm-2.3.3 → pyzm-2.3.4}/pyzm/ml/detector.py +22 -2
- {pyzm-2.3.3 → pyzm-2.3.4/pyzm.egg-info}/PKG-INFO +3 -3
- {pyzm-2.3.3 → pyzm-2.3.4}/tests/test_ml/test_detector.py +58 -0
- {pyzm-2.3.3 → pyzm-2.3.4}/LICENSE +0 -0
- {pyzm-2.3.3 → pyzm-2.3.4}/MANIFEST.in +0 -0
- {pyzm-2.3.3 → pyzm-2.3.4}/pyproject.toml +0 -0
- {pyzm-2.3.3 → pyzm-2.3.4}/pyzm/client.py +0 -0
- {pyzm-2.3.3 → pyzm-2.3.4}/pyzm/log.py +0 -0
- {pyzm-2.3.3 → pyzm-2.3.4}/pyzm/ml/__init__.py +0 -0
- {pyzm-2.3.3 → pyzm-2.3.4}/pyzm/ml/backends/__init__.py +0 -0
- {pyzm-2.3.3 → pyzm-2.3.4}/pyzm/ml/backends/alpr.py +0 -0
- {pyzm-2.3.3 → pyzm-2.3.4}/pyzm/ml/backends/base.py +0 -0
- {pyzm-2.3.3 → pyzm-2.3.4}/pyzm/ml/backends/birdnet.py +0 -0
- {pyzm-2.3.3 → pyzm-2.3.4}/pyzm/ml/backends/coral.py +0 -0
- {pyzm-2.3.3 → pyzm-2.3.4}/pyzm/ml/backends/face_dlib.py +0 -0
- {pyzm-2.3.3 → pyzm-2.3.4}/pyzm/ml/backends/face_tpu.py +0 -0
- {pyzm-2.3.3 → pyzm-2.3.4}/pyzm/ml/backends/rekognition.py +0 -0
- {pyzm-2.3.3 → pyzm-2.3.4}/pyzm/ml/backends/yolo.py +0 -0
- {pyzm-2.3.3 → pyzm-2.3.4}/pyzm/ml/backends/yolo_darknet.py +0 -0
- {pyzm-2.3.3 → pyzm-2.3.4}/pyzm/ml/backends/yolo_onnx.py +0 -0
- {pyzm-2.3.3 → pyzm-2.3.4}/pyzm/ml/face_train_dlib.py +0 -0
- {pyzm-2.3.3 → pyzm-2.3.4}/pyzm/ml/filters.py +0 -0
- {pyzm-2.3.3 → pyzm-2.3.4}/pyzm/ml/pipeline.py +0 -0
- {pyzm-2.3.3 → pyzm-2.3.4}/pyzm/models/__init__.py +0 -0
- {pyzm-2.3.3 → pyzm-2.3.4}/pyzm/models/config.py +0 -0
- {pyzm-2.3.3 → pyzm-2.3.4}/pyzm/models/detection.py +0 -0
- {pyzm-2.3.3 → pyzm-2.3.4}/pyzm/models/zm.py +0 -0
- {pyzm-2.3.3 → pyzm-2.3.4}/pyzm/serve/__init__.py +0 -0
- {pyzm-2.3.3 → pyzm-2.3.4}/pyzm/serve/__main__.py +0 -0
- {pyzm-2.3.3 → pyzm-2.3.4}/pyzm/serve/app.py +0 -0
- {pyzm-2.3.3 → pyzm-2.3.4}/pyzm/serve/auth.py +0 -0
- {pyzm-2.3.3 → pyzm-2.3.4}/pyzm/train/__init__.py +0 -0
- {pyzm-2.3.3 → pyzm-2.3.4}/pyzm/train/__main__.py +0 -0
- {pyzm-2.3.3 → pyzm-2.3.4}/pyzm/train/_import_panel.py +0 -0
- {pyzm-2.3.3 → pyzm-2.3.4}/pyzm/train/_review_panel.py +0 -0
- {pyzm-2.3.3 → pyzm-2.3.4}/pyzm/train/_train_panel.py +0 -0
- {pyzm-2.3.3 → pyzm-2.3.4}/pyzm/train/app.py +0 -0
- {pyzm-2.3.3 → pyzm-2.3.4}/pyzm/train/assets/pyzm.png +0 -0
- {pyzm-2.3.3 → pyzm-2.3.4}/pyzm/train/auto_label.py +0 -0
- {pyzm-2.3.3 → pyzm-2.3.4}/pyzm/train/dataset.py +0 -0
- {pyzm-2.3.3 → pyzm-2.3.4}/pyzm/train/local_import.py +0 -0
- {pyzm-2.3.3 → pyzm-2.3.4}/pyzm/train/pipeline.py +0 -0
- {pyzm-2.3.3 → pyzm-2.3.4}/pyzm/train/trainer.py +0 -0
- {pyzm-2.3.3 → pyzm-2.3.4}/pyzm/train/verification.py +0 -0
- {pyzm-2.3.3 → pyzm-2.3.4}/pyzm/zm/__init__.py +0 -0
- {pyzm-2.3.3 → pyzm-2.3.4}/pyzm/zm/api.py +0 -0
- {pyzm-2.3.3 → pyzm-2.3.4}/pyzm/zm/auth.py +0 -0
- {pyzm-2.3.3 → pyzm-2.3.4}/pyzm/zm/db.py +0 -0
- {pyzm-2.3.3 → pyzm-2.3.4}/pyzm/zm/media.py +0 -0
- {pyzm-2.3.3 → pyzm-2.3.4}/pyzm/zm/shm.py +0 -0
- {pyzm-2.3.3 → pyzm-2.3.4}/pyzm.egg-info/SOURCES.txt +0 -0
- {pyzm-2.3.3 → pyzm-2.3.4}/pyzm.egg-info/dependency_links.txt +0 -0
- {pyzm-2.3.3 → pyzm-2.3.4}/pyzm.egg-info/requires.txt +0 -0
- {pyzm-2.3.3 → pyzm-2.3.4}/pyzm.egg-info/top_level.txt +0 -0
- {pyzm-2.3.3 → pyzm-2.3.4}/setup.cfg +0 -0
- {pyzm-2.3.3 → pyzm-2.3.4}/setup.py +0 -0
- {pyzm-2.3.3 → pyzm-2.3.4}/tests/__init__.py +0 -0
- {pyzm-2.3.3 → pyzm-2.3.4}/tests/conftest.py +0 -0
- {pyzm-2.3.3 → pyzm-2.3.4}/tests/test_config.py +0 -0
- {pyzm-2.3.3 → pyzm-2.3.4}/tests/test_config_variants.py +0 -0
- {pyzm-2.3.3 → pyzm-2.3.4}/tests/test_face_dlib_lock.py +0 -0
- {pyzm-2.3.3 → pyzm-2.3.4}/tests/test_filters.py +0 -0
- {pyzm-2.3.3 → pyzm-2.3.4}/tests/test_log.py +0 -0
- {pyzm-2.3.3 → pyzm-2.3.4}/tests/test_ml/__init__.py +0 -0
- {pyzm-2.3.3 → pyzm-2.3.4}/tests/test_ml/test_birdnet.py +0 -0
- {pyzm-2.3.3 → pyzm-2.3.4}/tests/test_ml/test_filters.py +0 -0
- {pyzm-2.3.3 → pyzm-2.3.4}/tests/test_ml/test_pipeline.py +0 -0
- {pyzm-2.3.3 → pyzm-2.3.4}/tests/test_ml/test_pipeline_lazy.py +0 -0
- {pyzm-2.3.3 → pyzm-2.3.4}/tests/test_ml/test_yolo_onnx.py +0 -0
- {pyzm-2.3.3 → pyzm-2.3.4}/tests/test_ml_e2e/__init__.py +0 -0
- {pyzm-2.3.3 → pyzm-2.3.4}/tests/test_ml_e2e/conftest.py +0 -0
- {pyzm-2.3.3 → pyzm-2.3.4}/tests/test_ml_e2e/test_basic_detection.py +0 -0
- {pyzm-2.3.3 → pyzm-2.3.4}/tests/test_ml_e2e/test_disabled_models.py +0 -0
- {pyzm-2.3.3 → pyzm-2.3.4}/tests/test_ml_e2e/test_edge_cases.py +0 -0
- {pyzm-2.3.3 → pyzm-2.3.4}/tests/test_ml_e2e/test_filter_combinations.py +0 -0
- {pyzm-2.3.3 → pyzm-2.3.4}/tests/test_ml_e2e/test_frame_strategies.py +0 -0
- {pyzm-2.3.3 → pyzm-2.3.4}/tests/test_ml_e2e/test_from_dict.py +0 -0
- {pyzm-2.3.3 → pyzm-2.3.4}/tests/test_ml_e2e/test_match_strategies.py +0 -0
- {pyzm-2.3.3 → pyzm-2.3.4}/tests/test_ml_e2e/test_min_confidence.py +0 -0
- {pyzm-2.3.3 → pyzm-2.3.4}/tests/test_ml_e2e/test_model_dimensions.py +0 -0
- {pyzm-2.3.3 → pyzm-2.3.4}/tests/test_ml_e2e/test_model_discovery.py +0 -0
- {pyzm-2.3.3 → pyzm-2.3.4}/tests/test_ml_e2e/test_multi_model.py +0 -0
- {pyzm-2.3.3 → pyzm-2.3.4}/tests/test_ml_e2e/test_past_detections.py +0 -0
- {pyzm-2.3.3 → pyzm-2.3.4}/tests/test_ml_e2e/test_pattern_filtering.py +0 -0
- {pyzm-2.3.3 → pyzm-2.3.4}/tests/test_ml_e2e/test_pipeline_loading.py +0 -0
- {pyzm-2.3.3 → pyzm-2.3.4}/tests/test_ml_e2e/test_pre_existing_labels.py +0 -0
- {pyzm-2.3.3 → pyzm-2.3.4}/tests/test_ml_e2e/test_remote_serve.py +0 -0
- {pyzm-2.3.3 → pyzm-2.3.4}/tests/test_ml_e2e/test_server_config.py +0 -0
- {pyzm-2.3.3 → pyzm-2.3.4}/tests/test_ml_e2e/test_size_filtering.py +0 -0
- {pyzm-2.3.3 → pyzm-2.3.4}/tests/test_ml_e2e/test_stream_config.py +0 -0
- {pyzm-2.3.3 → pyzm-2.3.4}/tests/test_ml_e2e/test_zone_filtering.py +0 -0
- {pyzm-2.3.3 → pyzm-2.3.4}/tests/test_models/__init__.py +0 -0
- {pyzm-2.3.3 → pyzm-2.3.4}/tests/test_models/test_config.py +0 -0
- {pyzm-2.3.3 → pyzm-2.3.4}/tests/test_models/test_detection.py +0 -0
- {pyzm-2.3.3 → pyzm-2.3.4}/tests/test_models/test_zm.py +0 -0
- {pyzm-2.3.3 → pyzm-2.3.4}/tests/test_serve/__init__.py +0 -0
- {pyzm-2.3.3 → pyzm-2.3.4}/tests/test_serve/test_app.py +0 -0
- {pyzm-2.3.3 → pyzm-2.3.4}/tests/test_serve/test_auth.py +0 -0
- {pyzm-2.3.3 → pyzm-2.3.4}/tests/test_serve/test_models_all.py +0 -0
- {pyzm-2.3.3 → pyzm-2.3.4}/tests/test_train/__init__.py +0 -0
- {pyzm-2.3.3 → pyzm-2.3.4}/tests/test_train/test_app_review.py +0 -0
- {pyzm-2.3.3 → pyzm-2.3.4}/tests/test_train/test_auto_label.py +0 -0
- {pyzm-2.3.3 → pyzm-2.3.4}/tests/test_train/test_dataset.py +0 -0
- {pyzm-2.3.3 → pyzm-2.3.4}/tests/test_train/test_local_import.py +0 -0
- {pyzm-2.3.3 → pyzm-2.3.4}/tests/test_train/test_trainer.py +0 -0
- {pyzm-2.3.3 → pyzm-2.3.4}/tests/test_train/test_verification.py +0 -0
- {pyzm-2.3.3 → pyzm-2.3.4}/tests/test_train_pipeline.py +0 -0
- {pyzm-2.3.3 → pyzm-2.3.4}/tests/test_zm/__init__.py +0 -0
- {pyzm-2.3.3 → pyzm-2.3.4}/tests/test_zm/test_api.py +0 -0
- {pyzm-2.3.3 → pyzm-2.3.4}/tests/test_zm/test_auth.py +0 -0
- {pyzm-2.3.3 → pyzm-2.3.4}/tests/test_zm/test_client.py +0 -0
- {pyzm-2.3.3 → pyzm-2.3.4}/tests/test_zm_e2e/__init__.py +0 -0
- {pyzm-2.3.3 → pyzm-2.3.4}/tests/test_zm_e2e/conftest.py +0 -0
- {pyzm-2.3.3 → pyzm-2.3.4}/tests/test_zm_e2e/test_auth.py +0 -0
- {pyzm-2.3.3 → pyzm-2.3.4}/tests/test_zm_e2e/test_configs.py +0 -0
- {pyzm-2.3.3 → pyzm-2.3.4}/tests/test_zm_e2e/test_db.py +0 -0
- {pyzm-2.3.3 → pyzm-2.3.4}/tests/test_zm_e2e/test_detection.py +0 -0
- {pyzm-2.3.3 → pyzm-2.3.4}/tests/test_zm_e2e/test_events.py +0 -0
- {pyzm-2.3.3 → pyzm-2.3.4}/tests/test_zm_e2e/test_frames.py +0 -0
- {pyzm-2.3.3 → pyzm-2.3.4}/tests/test_zm_e2e/test_monitors.py +0 -0
- {pyzm-2.3.3 → pyzm-2.3.4}/tests/test_zm_e2e/test_states.py +0 -0
- {pyzm-2.3.3 → pyzm-2.3.4}/tests/test_zm_e2e/test_system.py +0 -0
- {pyzm-2.3.3 → pyzm-2.3.4}/tests/test_zm_e2e/test_write_events.py +0 -0
- {pyzm-2.3.3 → pyzm-2.3.4}/tests/test_zm_e2e/test_write_monitors.py +0 -0
- {pyzm-2.3.3 → pyzm-2.3.4}/tests/test_zm_e2e/test_write_notes.py +0 -0
- {pyzm-2.3.3 → pyzm-2.3.4}/tests/test_zm_e2e/test_write_state.py +0 -0
- {pyzm-2.3.3 → pyzm-2.3.4}/tests/test_zm_e2e/test_zones.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: pyzm
|
|
3
|
-
Version: 2.3.
|
|
3
|
+
Version: 2.3.4
|
|
4
4
|
Summary: ZoneMinder API, Logger and other base utilities for python programmers
|
|
5
5
|
Home-page: https://github.com/pliablepixels/pyzm
|
|
6
6
|
Author: Pliable Pixels
|
|
@@ -65,11 +65,11 @@ Requires-Dist: st-clickable-images>=0.0.3; extra == "full"
|
|
|
65
65
|
|
|
66
66
|
What
|
|
67
67
|
=====
|
|
68
|
-
|
|
68
|
+
pyzmNg is a rewrite of pyzm.
|
|
69
69
|
|
|
70
70
|
It's a pythonic wrapper that integrates with ZM and also operates as a standalone ML library. Key features:
|
|
71
71
|
- ZM API
|
|
72
|
-
- ZM
|
|
72
|
+
- ZM EventServerNg
|
|
73
73
|
- ZM Logger
|
|
74
74
|
- ZM Memory
|
|
75
75
|
- Machine Learning Modules (with our without ZM)
|
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
What
|
|
4
4
|
=====
|
|
5
|
-
|
|
5
|
+
pyzmNg is a rewrite of pyzm.
|
|
6
6
|
|
|
7
7
|
It's a pythonic wrapper that integrates with ZM and also operates as a standalone ML library. Key features:
|
|
8
8
|
- ZM API
|
|
9
|
-
- ZM
|
|
9
|
+
- ZM EventServerNg
|
|
10
10
|
- ZM Logger
|
|
11
11
|
- ZM Memory
|
|
12
12
|
- Machine Learning Modules (with our without ZM)
|
|
@@ -291,14 +291,31 @@ class Detector:
|
|
|
291
291
|
detections: list,
|
|
292
292
|
zones: list["Zone"] | None,
|
|
293
293
|
image_shape: tuple[int, int],
|
|
294
|
+
original_shape: tuple[int, int] | None = None,
|
|
294
295
|
) -> tuple[list, list]:
|
|
295
296
|
"""Apply client-side filters: pattern, size, zones, past detections.
|
|
296
297
|
|
|
298
|
+
Parameters
|
|
299
|
+
----------
|
|
300
|
+
original_shape:
|
|
301
|
+
``(height, width)`` of the image before resizing. When provided
|
|
302
|
+
and different from *image_shape*, zone polygons are rescaled from
|
|
303
|
+
original coordinates to match the (resized) detection space.
|
|
304
|
+
|
|
297
305
|
Returns (kept_detections, error_boxes).
|
|
298
306
|
"""
|
|
299
307
|
h, w = image_shape
|
|
300
308
|
zone_dicts = [z.as_dict() for z in zones] if zones else []
|
|
301
309
|
|
|
310
|
+
# Rescale zone polygons when the image was resized
|
|
311
|
+
if original_shape and zone_dicts and (original_shape[0] != h or original_shape[1] != w):
|
|
312
|
+
orig_h, orig_w = original_shape
|
|
313
|
+
xfactor = w / orig_w
|
|
314
|
+
yfactor = h / orig_h
|
|
315
|
+
for zd in zone_dicts:
|
|
316
|
+
pts = zd.get("value") or zd.get("points", [])
|
|
317
|
+
zd["value"] = [(int(x * xfactor), int(y * yfactor)) for x, y in pts]
|
|
318
|
+
|
|
302
319
|
detections = filter_by_pattern(detections, self._config.pattern)
|
|
303
320
|
detections = filter_by_size(detections, self._config.max_detection_size, (h, w))
|
|
304
321
|
detections, error_boxes = filter_by_zone(detections, zone_dicts, (h, w))
|
|
@@ -332,6 +349,7 @@ class Detector:
|
|
|
332
349
|
self,
|
|
333
350
|
image: "np.ndarray",
|
|
334
351
|
zones: list["Zone"] | None = None,
|
|
352
|
+
original_shape: tuple[int, int] | None = None,
|
|
335
353
|
) -> DetectionResult:
|
|
336
354
|
"""Send an image to the remote gateway for detection, then filter locally."""
|
|
337
355
|
import cv2
|
|
@@ -355,7 +373,9 @@ class Detector:
|
|
|
355
373
|
|
|
356
374
|
# Apply client-side filters
|
|
357
375
|
h, w = image.shape[:2]
|
|
358
|
-
filtered, error_boxes = self._apply_filters(
|
|
376
|
+
filtered, error_boxes = self._apply_filters(
|
|
377
|
+
result.detections, zones, (h, w), original_shape=original_shape,
|
|
378
|
+
)
|
|
359
379
|
|
|
360
380
|
return DetectionResult(
|
|
361
381
|
detections=filtered,
|
|
@@ -845,7 +865,7 @@ class Detector:
|
|
|
845
865
|
|
|
846
866
|
for frame_id, image in frames:
|
|
847
867
|
try:
|
|
848
|
-
result = self._remote_detect(image, zones)
|
|
868
|
+
result = self._remote_detect(image, zones, original_shape=original_shape)
|
|
849
869
|
result.frame_id = frame_id
|
|
850
870
|
if original_shape:
|
|
851
871
|
result.image_dimensions["original"] = original_shape
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: pyzm
|
|
3
|
-
Version: 2.3.
|
|
3
|
+
Version: 2.3.4
|
|
4
4
|
Summary: ZoneMinder API, Logger and other base utilities for python programmers
|
|
5
5
|
Home-page: https://github.com/pliablepixels/pyzm
|
|
6
6
|
Author: Pliable Pixels
|
|
@@ -65,11 +65,11 @@ Requires-Dist: st-clickable-images>=0.0.3; extra == "full"
|
|
|
65
65
|
|
|
66
66
|
What
|
|
67
67
|
=====
|
|
68
|
-
|
|
68
|
+
pyzmNg is a rewrite of pyzm.
|
|
69
69
|
|
|
70
70
|
It's a pythonic wrapper that integrates with ZM and also operates as a standalone ML library. Key features:
|
|
71
71
|
- ZM API
|
|
72
|
-
- ZM
|
|
72
|
+
- ZM EventServerNg
|
|
73
73
|
- ZM Logger
|
|
74
74
|
- ZM Memory
|
|
75
75
|
- Machine Learning Modules (with our without ZM)
|
|
@@ -1557,6 +1557,64 @@ class TestApplyFilters:
|
|
|
1557
1557
|
filtered, errors = det._apply_filters(dets, zones=None, image_shape=(480, 640))
|
|
1558
1558
|
assert len(filtered) == 2
|
|
1559
1559
|
|
|
1560
|
+
def test_zone_rescaled_with_original_shape(self):
|
|
1561
|
+
"""Zone polygons should be rescaled when original_shape differs from image_shape."""
|
|
1562
|
+
from pyzm.ml.detector import Detector
|
|
1563
|
+
from pyzm.models.zm import Zone
|
|
1564
|
+
det = Detector.__new__(Detector)
|
|
1565
|
+
det._config = DetectorConfig(pattern=".*")
|
|
1566
|
+
det._pipeline = None
|
|
1567
|
+
# Zone covers a small region in 800x480 (original) coordinates
|
|
1568
|
+
# After 0.5x resize to 400x240, detection bbox at (10,10)-(90,90) in resized space
|
|
1569
|
+
# Zone must be rescaled to (50,100)-(200,200) in resized space to contain bbox
|
|
1570
|
+
zones = [Zone(name="z", points=[(0, 0), (200, 0), (200, 200), (0, 200)])]
|
|
1571
|
+
dets = [
|
|
1572
|
+
Detection(label="person", confidence=0.9, bbox=BBox(10, 10, 90, 90), model_name="test"),
|
|
1573
|
+
]
|
|
1574
|
+
# With original_shape: zones get rescaled from 800x480 to 400x240
|
|
1575
|
+
filtered, errors = det._apply_filters(
|
|
1576
|
+
dets, zones=zones, image_shape=(240, 400), original_shape=(480, 800),
|
|
1577
|
+
)
|
|
1578
|
+
assert len(filtered) == 1
|
|
1579
|
+
assert filtered[0].label == "person"
|
|
1580
|
+
|
|
1581
|
+
def test_zone_not_rescaled_without_original_shape(self):
|
|
1582
|
+
"""Without original_shape, zone polygons pass through unchanged."""
|
|
1583
|
+
from pyzm.ml.detector import Detector
|
|
1584
|
+
from pyzm.models.zm import Zone
|
|
1585
|
+
det = Detector.__new__(Detector)
|
|
1586
|
+
det._config = DetectorConfig(pattern=".*")
|
|
1587
|
+
det._pipeline = None
|
|
1588
|
+
zones = [Zone(name="z", points=[(0, 0), (50, 0), (50, 50), (0, 50)])]
|
|
1589
|
+
dets = [
|
|
1590
|
+
Detection(label="person", confidence=0.9, bbox=BBox(10, 10, 40, 40), model_name="test"),
|
|
1591
|
+
]
|
|
1592
|
+
filtered, errors = det._apply_filters(dets, zones=zones, image_shape=(480, 640))
|
|
1593
|
+
assert len(filtered) == 1
|
|
1594
|
+
|
|
1595
|
+
def test_zone_mismatch_without_rescaling(self):
|
|
1596
|
+
"""Without original_shape, large original-coord zones won't match small-image detections."""
|
|
1597
|
+
from pyzm.ml.detector import Detector
|
|
1598
|
+
from pyzm.models.zm import Zone
|
|
1599
|
+
det = Detector.__new__(Detector)
|
|
1600
|
+
det._config = DetectorConfig(pattern=".*")
|
|
1601
|
+
det._pipeline = None
|
|
1602
|
+
# Zone is in original coords (600-800 range), but image is only 400 wide
|
|
1603
|
+
# Detection at (10,10)-(90,90) in resized space won't intersect
|
|
1604
|
+
zones = [Zone(name="z", points=[(600, 300), (800, 300), (800, 480), (600, 480)])]
|
|
1605
|
+
dets = [
|
|
1606
|
+
Detection(label="person", confidence=0.9, bbox=BBox(10, 10, 90, 90), model_name="test"),
|
|
1607
|
+
]
|
|
1608
|
+
# Without original_shape: zone coords stay in 800x480 space, won't intersect detection
|
|
1609
|
+
filtered, errors = det._apply_filters(dets, zones=zones, image_shape=(240, 400))
|
|
1610
|
+
assert len(filtered) == 0
|
|
1611
|
+
|
|
1612
|
+
# With original_shape: zone rescaled to (300,150)-(400,240), still won't intersect (10,10)-(90,90)
|
|
1613
|
+
filtered2, _ = det._apply_filters(
|
|
1614
|
+
dets, zones=zones, image_shape=(240, 400), original_shape=(480, 800),
|
|
1615
|
+
)
|
|
1616
|
+
assert len(filtered2) == 0
|
|
1617
|
+
|
|
1560
1618
|
|
|
1561
1619
|
class TestRemoteDetectFiltering:
|
|
1562
1620
|
"""Verify that _remote_detect applies client-side filters."""
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|