mirror of
https://github.com/azaion/detections.git
synced 2026-06-23 17:01:08 +00:00
Skip GSD and size filtering without altitude
This commit is contained in:
@@ -8,12 +8,9 @@
|
|||||||
| classes-json | `classes.json` (repo root) | 19 detection classes with Id, Name, Color, MaxSizeM | All tests | Volume mount to detections `/app/classes.json` | Container restart |
|
| classes-json | `classes.json` (repo root) | 19 detection classes with Id, Name, Color, MaxSizeM | All tests | Volume mount to detections `/app/classes.json` | Container restart |
|
||||||
| image-small | `input_data/image_small.jpg` | JPEG 1280×720 — below tiling threshold (1920×1920) | FT-P-01..03, 05, 07, 13..15, FT-N-03, 06, NFT-PERF-01..02, NFT-RES-01, 03, NFT-SEC-01, NFT-RES-LIM-01 | Volume mount to consumer `/media/` | N/A (read-only) |
|
| image-small | `input_data/image_small.jpg` | JPEG 1280×720 — below tiling threshold (1920×1920) | FT-P-01..03, 05, 07, 13..15, FT-N-03, 06, NFT-PERF-01..02, NFT-RES-01, 03, NFT-SEC-01, NFT-RES-LIM-01 | Volume mount to consumer `/media/` | N/A (read-only) |
|
||||||
| image-large | `input_data/image_large.JPG` | JPEG 6252×4168 — above tiling threshold, triggers GSD tiling | FT-P-04, 16, NFT-PERF-03 | Volume mount to consumer `/media/` | N/A (read-only) |
|
| image-large | `input_data/image_large.JPG` | JPEG 6252×4168 — above tiling threshold, triggers GSD tiling | FT-P-04, 16, NFT-PERF-03 | Volume mount to consumer `/media/` | N/A (read-only) |
|
||||||
| image-dense-01 | `input_data/image_dense01.jpg` | JPEG 1280×720 — dense scene with many clustered objects | FT-P-06, NFT-RES-LIM-03 | Volume mount to consumer `/media/` | N/A (read-only) |
|
|
||||||
| image-dense-02 | `input_data/image_dense02.jpg` | JPEG 1920×1080 — dense scene variant, borderline tiling | FT-P-06 (variant) | Volume mount to consumer `/media/` | N/A (read-only) |
|
|
||||||
| image-different-types | `input_data/image_different_types.jpg` | JPEG 900×1600 — varied object classes for class variant tests | FT-P-13 | Volume mount to consumer `/media/` | N/A (read-only) |
|
| image-different-types | `input_data/image_different_types.jpg` | JPEG 900×1600 — varied object classes for class variant tests | FT-P-13 | Volume mount to consumer `/media/` | N/A (read-only) |
|
||||||
| image-empty-scene | `input_data/image_empty_scene.jpg` | JPEG 1920×1080 — clean scene with no detectable objects | Edge case (zero detections) | Volume mount to consumer `/media/` | N/A (read-only) |
|
| image-empty-scene | `input_data/image_empty_scene.jpg` | JPEG 1920×1080 — clean scene with no detectable objects | Edge case (zero detections) | Volume mount to consumer `/media/` | N/A (read-only) |
|
||||||
| video-test-01 | `input_data/video_test01.mp4` | MP4 video — standard async/SSE/video detection tests | FT-P-08..12, FT-N-04, 07, NFT-PERF-04, NFT-RES-02, NFT-SEC-03 | Volume mount to consumer `/media/` | N/A (read-only) |
|
| video-test-01 | `input_data/video_test01.mp4` | MP4 video — standard async/SSE/video detection tests | FT-P-08..12, FT-N-04, 07, NFT-PERF-04, NFT-RES-02, NFT-SEC-03 | Volume mount to consumer `/media/` | N/A (read-only) |
|
||||||
| video-1 | `input_data/video_1.mp4` | MP4 video — local variant for concurrent and resilience-style tests | NFT-RES-02 (variant), NFT-RES-04 | Volume mount to consumer `/media/` | N/A (read-only) |
|
|
||||||
| video-1-faststart | `input_data/video_1_faststart.mp4` | MP4 video — faststart/local streaming variant | Streaming compatibility checks | Volume mount to consumer `/media/` | N/A (read-only) |
|
| video-1-faststart | `input_data/video_1_faststart.mp4` | MP4 video — faststart/local streaming variant | Streaming compatibility checks | Volume mount to consumer `/media/` | N/A (read-only) |
|
||||||
| empty-image | Generated at build time | Zero-byte file | FT-N-01 | Generated in e2e/fixtures/ | N/A |
|
| empty-image | Generated at build time | Zero-byte file | FT-N-01 | Generated in e2e/fixtures/ | N/A |
|
||||||
| corrupt-image | Generated at build time | Random binary garbage (not valid image format) | FT-N-02 | Generated in e2e/fixtures/ | N/A |
|
| corrupt-image | Generated at build time | Random binary garbage (not valid image format) | FT-N-02 | Generated in e2e/fixtures/ | N/A |
|
||||||
@@ -31,12 +28,9 @@ Each test run starts with fresh containers (`docker compose down -v && docker co
|
|||||||
| azaion.onnx | `_docs/00_problem/input_data/azaion.onnx` | YOLO ONNX detection model | All detection tests |
|
| azaion.onnx | `_docs/00_problem/input_data/azaion.onnx` | YOLO ONNX detection model | All detection tests |
|
||||||
| image_small.jpg | `_docs/00_problem/input_data/image_small.jpg` | 1280×720 aerial image | Single-frame detection, health, negative, perf tests |
|
| image_small.jpg | `_docs/00_problem/input_data/image_small.jpg` | 1280×720 aerial image | Single-frame detection, health, negative, perf tests |
|
||||||
| image_large.JPG | `_docs/00_problem/input_data/image_large.JPG` | 6252×4168 aerial image | Tiling tests |
|
| image_large.JPG | `_docs/00_problem/input_data/image_large.JPG` | 6252×4168 aerial image | Tiling tests |
|
||||||
| image_dense01.jpg | `_docs/00_problem/input_data/image_dense01.jpg` | Dense scene 1280×720 | Dedup, detection cap tests |
|
|
||||||
| image_dense02.jpg | `_docs/00_problem/input_data/image_dense02.jpg` | Dense scene 1920×1080 | Dedup variant |
|
|
||||||
| image_different_types.jpg | `_docs/00_problem/input_data/image_different_types.jpg` | Varied classes 900×1600 | Class variant tests |
|
| image_different_types.jpg | `_docs/00_problem/input_data/image_different_types.jpg` | Varied classes 900×1600 | Class variant tests |
|
||||||
| image_empty_scene.jpg | `_docs/00_problem/input_data/image_empty_scene.jpg` | Empty scene 1920×1080 | Zero-detection edge case |
|
| image_empty_scene.jpg | `_docs/00_problem/input_data/image_empty_scene.jpg` | Empty scene 1920×1080 | Zero-detection edge case |
|
||||||
| video_test01.mp4 | `_docs/00_problem/input_data/video_test01.mp4` | Standard video | Async, SSE, video, perf tests |
|
| video_test01.mp4 | `_docs/00_problem/input_data/video_test01.mp4` | Standard video | Async, SSE, video, perf tests |
|
||||||
| video_1.mp4 | `_docs/00_problem/input_data/video_1.mp4` | Video variant | Resilience, concurrent tests |
|
|
||||||
| video_1_faststart.mp4 | `_docs/00_problem/input_data/video_1_faststart.mp4` | Faststart video variant | Streaming compatibility checks |
|
| video_1_faststart.mp4 | `_docs/00_problem/input_data/video_1_faststart.mp4` | Faststart video variant | Streaming compatibility checks |
|
||||||
| classes.json | repo root `classes.json` | 19 detection classes | All tests |
|
| classes.json | repo root `classes.json` | 19 detection classes | All tests |
|
||||||
|
|
||||||
|
|||||||
@@ -27,8 +27,6 @@ e2e/
|
|||||||
├── fixtures/
|
├── fixtures/
|
||||||
│ ├── image_small.jpg (1280×720 JPEG, aerial, detectable objects)
|
│ ├── image_small.jpg (1280×720 JPEG, aerial, detectable objects)
|
||||||
│ ├── image_large.JPG (6252×4168 JPEG, triggers tiling)
|
│ ├── image_large.JPG (6252×4168 JPEG, triggers tiling)
|
||||||
│ ├── image_dense01.jpg (1280×720 JPEG, dense scene, clustered objects)
|
|
||||||
│ ├── image_dense02.jpg (1920×1080 JPEG, dense scene variant)
|
|
||||||
│ ├── image_different_types.jpg (900×1600 JPEG, varied object classes)
|
│ ├── image_different_types.jpg (900×1600 JPEG, varied object classes)
|
||||||
│ ├── image_empty_scene.jpg (1920×1080 JPEG, no detectable objects)
|
│ ├── image_empty_scene.jpg (1920×1080 JPEG, no detectable objects)
|
||||||
│ ├── video_short01.mp4 (short MP4 with moving objects)
|
│ ├── video_short01.mp4 (short MP4 with moving objects)
|
||||||
@@ -130,8 +128,6 @@ Two Docker Compose profiles:
|
|||||||
| `reset_mocks` | function (autouse) | Calls `POST /mock/reset` on both mocks before each test |
|
| `reset_mocks` | function (autouse) | Calls `POST /mock/reset` on both mocks before each test |
|
||||||
| `image_small` | session | Reads `image_small.jpg` from `/media/` volume |
|
| `image_small` | session | Reads `image_small.jpg` from `/media/` volume |
|
||||||
| `image_large` | session | Reads `image_large.JPG` from `/media/` volume |
|
| `image_large` | session | Reads `image_large.JPG` from `/media/` volume |
|
||||||
| `image_dense` | session | Reads `image_dense01.jpg` from `/media/` volume |
|
|
||||||
| `image_dense_02` | session | Reads `image_dense02.jpg` from `/media/` volume |
|
|
||||||
| `image_different_types` | session | Reads `image_different_types.jpg` from `/media/` volume |
|
| `image_different_types` | session | Reads `image_different_types.jpg` from `/media/` volume |
|
||||||
| `image_empty_scene` | session | Reads `image_empty_scene.jpg` from `/media/` volume |
|
| `image_empty_scene` | session | Reads `image_empty_scene.jpg` from `/media/` volume |
|
||||||
| `video_short_path` | session | Path to `video_short01.mp4` on `/media/` volume |
|
| `video_short_path` | session | Path to `video_short01.mp4` on `/media/` volume |
|
||||||
@@ -150,8 +146,6 @@ Two Docker Compose profiles:
|
|||||||
| classes.json | repo root `classes.json` | JSON (19 objects with Id, Name, Color, MaxSizeM) | All tests (volume mount to detections) |
|
| classes.json | repo root `classes.json` | JSON (19 objects with Id, Name, Color, MaxSizeM) | All tests (volume mount to detections) |
|
||||||
| image_small.jpg | `input_data/image_small.jpg` | JPEG 1280×720 | Health, single image, filtering, negative, performance tests |
|
| image_small.jpg | `input_data/image_small.jpg` | JPEG 1280×720 | Health, single image, filtering, negative, performance tests |
|
||||||
| image_large.JPG | `input_data/image_large.JPG` | JPEG 6252×4168 | Tiling tests, performance tests |
|
| image_large.JPG | `input_data/image_large.JPG` | JPEG 6252×4168 | Tiling tests, performance tests |
|
||||||
| image_dense01.jpg | `input_data/image_dense01.jpg` | JPEG 1280×720 dense scene | Dedup tests, detection cap tests |
|
|
||||||
| image_dense02.jpg | `input_data/image_dense02.jpg` | JPEG 1920×1080 dense scene | Dedup variant |
|
|
||||||
| image_different_types.jpg | `input_data/image_different_types.jpg` | JPEG 900×1600 varied classes | Weather mode class variant tests |
|
| image_different_types.jpg | `input_data/image_different_types.jpg` | JPEG 900×1600 varied classes | Weather mode class variant tests |
|
||||||
| image_empty_scene.jpg | `input_data/image_empty_scene.jpg` | JPEG 1920×1080 empty | Zero-detection edge case |
|
| image_empty_scene.jpg | `input_data/image_empty_scene.jpg` | JPEG 1920×1080 empty | Zero-detection edge case |
|
||||||
| video_short01.mp4 | `input_data/video_short01.mp4` | MP4 short video | Async, SSE, video processing tests |
|
| video_short01.mp4 | `input_data/video_short01.mp4` | MP4 short video | Async, SSE, video processing tests |
|
||||||
|
|||||||
@@ -228,17 +228,6 @@ def image_small():
|
|||||||
def image_large():
|
def image_large():
|
||||||
return _read_media("image_large.JPG")
|
return _read_media("image_large.JPG")
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope="session")
|
|
||||||
def image_dense():
|
|
||||||
return _read_media("image_dense01.jpg")
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope="session")
|
|
||||||
def image_dense_02():
|
|
||||||
return _read_media("image_dense02.jpg")
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope="session")
|
@pytest.fixture(scope="session")
|
||||||
def image_different_types():
|
def image_different_types():
|
||||||
return _read_media("image_different_types.jpg")
|
return _read_media("image_different_types.jpg")
|
||||||
|
|||||||
+1
-1
@@ -7,6 +7,6 @@ cdef class Detection:
|
|||||||
cdef class Annotation:
|
cdef class Annotation:
|
||||||
cdef public str name
|
cdef public str name
|
||||||
cdef public str original_media_name
|
cdef public str original_media_name
|
||||||
cdef long time
|
cdef public long time
|
||||||
cdef public list[Detection] detections
|
cdef public list[Detection] detections
|
||||||
cdef public bytes image
|
cdef public bytes image
|
||||||
|
|||||||
+13
-5
@@ -15,6 +15,7 @@ import cv2
|
|||||||
import jwt as pyjwt
|
import jwt as pyjwt
|
||||||
import numpy as np
|
import numpy as np
|
||||||
import requests as http_requests
|
import requests as http_requests
|
||||||
|
from loguru import logger
|
||||||
from fastapi import Body, Depends, FastAPI, File, Form, HTTPException, Request, UploadFile
|
from fastapi import Body, Depends, FastAPI, File, Form, HTTPException, Request, UploadFile
|
||||||
from fastapi.responses import Response, StreamingResponse
|
from fastapi.responses import Response, StreamingResponse
|
||||||
from fastapi.security import HTTPAuthorizationCredentials, HTTPBearer
|
from fastapi.security import HTTPAuthorizationCredentials, HTTPBearer
|
||||||
@@ -270,7 +271,8 @@ def _post_media_record(payload: dict, bearer: str) -> bool:
|
|||||||
timeout=30,
|
timeout=30,
|
||||||
)
|
)
|
||||||
return r.status_code in (200, 201)
|
return r.status_code in (200, 201)
|
||||||
except Exception:
|
except Exception as exc:
|
||||||
|
logger.warning(f"Failed to create media record in annotations service: {exc}")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
@@ -284,7 +286,8 @@ def _put_media_status(media_id: str, media_status: int, bearer: str) -> bool:
|
|||||||
timeout=30,
|
timeout=30,
|
||||||
)
|
)
|
||||||
return r.status_code in (200, 204)
|
return r.status_code in (200, 204)
|
||||||
except Exception:
|
except Exception as exc:
|
||||||
|
logger.warning(f"Failed to update media status in annotations service for {media_id}: {exc}")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
@@ -332,10 +335,13 @@ def _post_annotation_to_service(token_mgr: TokenManager, media_id: str,
|
|||||||
try:
|
try:
|
||||||
token = token_mgr.get_valid_token()
|
token = token_mgr.get_valid_token()
|
||||||
image_b64 = base64.b64encode(annotation.image).decode() if annotation.image else None
|
image_b64 = base64.b64encode(annotation.image).decode() if annotation.image else None
|
||||||
|
total_seconds = int(annotation.time // 1000) if annotation.time else 0
|
||||||
|
hours, remainder = divmod(total_seconds, 3600)
|
||||||
|
minutes, seconds = divmod(remainder, 60)
|
||||||
payload = {
|
payload = {
|
||||||
"mediaId": media_id,
|
"mediaId": media_id,
|
||||||
"source": 0,
|
"source": 0,
|
||||||
"videoTime": f"00:00:{annotation.time // 1000:02d}" if annotation.time else "00:00:00",
|
"videoTime": f"{hours:02d}:{minutes:02d}:{seconds:02d}",
|
||||||
"detections": [d.model_dump() for d in dtos],
|
"detections": [d.model_dump() for d in dtos],
|
||||||
}
|
}
|
||||||
if image_b64:
|
if image_b64:
|
||||||
@@ -346,8 +352,10 @@ def _post_annotation_to_service(token_mgr: TokenManager, media_id: str,
|
|||||||
headers={"Authorization": f"Bearer {token}"},
|
headers={"Authorization": f"Bearer {token}"},
|
||||||
timeout=30,
|
timeout=30,
|
||||||
)
|
)
|
||||||
except Exception:
|
except Exception as exc:
|
||||||
pass
|
logger.warning(
|
||||||
|
f"Failed to post annotation to annotations service for media {media_id}: {exc}"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def _cleanup_channel(channel_id: str):
|
def _cleanup_channel(channel_id: str):
|
||||||
|
|||||||
Reference in New Issue
Block a user