perf: reuse sample dimensions and catalog digest
This commit is contained in:
parent
7142f10cfe
commit
1064e356de
2 changed files with 78 additions and 17 deletions
|
|
@ -21,6 +21,7 @@ import argparse
|
|||
import asyncio
|
||||
import base64
|
||||
from contextlib import asynccontextmanager
|
||||
from dataclasses import dataclass
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
|
|
@ -29,8 +30,7 @@ import sys
|
|||
import threading
|
||||
import time
|
||||
import uuid
|
||||
from dataclasses import dataclass
|
||||
from typing import Any, Dict, List, Optional
|
||||
from typing import Any, Dict, List, Optional, Tuple
|
||||
|
||||
# Keep the demo off the network before anything imports ultralytics.
|
||||
os.environ.setdefault("YOLO_OFFLINE", "1")
|
||||
|
|
@ -296,6 +296,9 @@ def create_app(
|
|||
recorder = FrameRecorder(settings.record_frames, every=settings.record_every) \
|
||||
if settings.record_frames else None
|
||||
samples = {item["id"]: item for item in get_available_shelf_images("add")}
|
||||
# path -> (mtime_ns, size, width, height). Dropped when the file changes.
|
||||
sample_dimensions: Dict[str, Tuple[int, int, int, int]] = {}
|
||||
sample_dimensions_lock = threading.Lock()
|
||||
sessions: Dict[str, LiveSession] = {}
|
||||
sessions_lock = asyncio.Lock()
|
||||
app.state.engine = engine
|
||||
|
|
@ -371,15 +374,37 @@ def create_app(
|
|||
raise _error("NOT_FOUND", f"unknown sku '{sku_id}'", 404)
|
||||
return {"status": "success", "product": product}
|
||||
|
||||
def _sample_listing() -> List[Dict[str, Any]]:
|
||||
listing = []
|
||||
def _sample_dimensions(path: str) -> Optional[Tuple[int, int]]:
|
||||
try:
|
||||
stat = os.stat(path)
|
||||
except OSError:
|
||||
with sample_dimensions_lock:
|
||||
sample_dimensions.pop(path, None)
|
||||
return None
|
||||
key = (stat.st_mtime_ns, stat.st_size)
|
||||
with sample_dimensions_lock:
|
||||
cached = sample_dimensions.get(path)
|
||||
if cached is not None and cached[:2] == key:
|
||||
return cached[2], cached[3]
|
||||
import cv2
|
||||
|
||||
image = cv2.imread(path)
|
||||
if image is None:
|
||||
with sample_dimensions_lock:
|
||||
sample_dimensions.pop(path, None)
|
||||
return None
|
||||
width, height = int(image.shape[1]), int(image.shape[0])
|
||||
with sample_dimensions_lock:
|
||||
sample_dimensions[path] = (key[0], key[1], width, height)
|
||||
return width, height
|
||||
|
||||
def _sample_listing() -> List[Dict[str, Any]]:
|
||||
listing = []
|
||||
for item in samples.values():
|
||||
entry = {"id": item["id"], "label": item["label"], "url": f"/v1/samples/{item['id']}"}
|
||||
image = cv2.imread(item["path"])
|
||||
if image is not None:
|
||||
entry["width"], entry["height"] = int(image.shape[1]), int(image.shape[0])
|
||||
dimensions = _sample_dimensions(item["path"])
|
||||
if dimensions is not None:
|
||||
entry["width"], entry["height"] = dimensions
|
||||
listing.append(entry)
|
||||
return listing
|
||||
|
||||
|
|
@ -693,7 +718,6 @@ def create_app(
|
|||
async def send(payload: Dict[str, Any]) -> None:
|
||||
async with send_lock:
|
||||
await websocket.send_text(json.dumps(payload))
|
||||
|
||||
await send(
|
||||
{
|
||||
"type": "hello",
|
||||
|
|
@ -717,7 +741,7 @@ def create_app(
|
|||
|
||||
async def processing_loop() -> None:
|
||||
while not session.closed:
|
||||
pending = await loop.run_in_executor(None, session.take_pending, 0.25)
|
||||
pending = await session.take_pending_async()
|
||||
if pending is None:
|
||||
continue
|
||||
frame_id, payload = pending
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue