Files
mediaproc/detect/profiles/base.py
2026-03-28 10:05:59 -03:00

97 lines
2.8 KiB
Python

"""
ContentTypeProfile protocol and config dataclasses.
Each profile defines the pipeline topology (as a JSONB blob), stage configs,
brand dictionary, VLM prompt templates, and aggregation strategy.
When profiles are persisted, the pipeline field is a JSONB column.
For now, profiles are code-only and pipeline_config() returns a hardcoded value.
"""
from __future__ import annotations
from dataclasses import dataclass, field
from typing import Any, Dict, Protocol
from detect.models import BrandDetection, DetectionReport
from core.schema.models.pipeline_config import PipelineConfig, StageRef, Edge
@dataclass
class FrameExtractionConfig:
fps: float = 2.0
max_frames: int = 500
@dataclass
class SceneFilterConfig:
hamming_threshold: int = 8
enabled: bool = True
@dataclass
class DetectionConfig:
model_name: str = "yolov8n.pt"
confidence_threshold: float = 0.3
target_classes: list[str] = field(default_factory=lambda: ["logo", "text"])
@dataclass
class OCRConfig:
languages: list[str] = field(default_factory=lambda: ["en"])
min_confidence: float = 0.5
@dataclass
class ResolverConfig:
fuzzy_threshold: int = 75
@dataclass
class RegionAnalysisConfig:
enabled: bool = True
# Edge detection (Canny + HoughLinesP)
edge_canny_low: int = 50
edge_canny_high: int = 150
edge_hough_threshold: int = 80
edge_hough_min_length: int = 100
edge_hough_max_gap: int = 10
edge_pair_max_distance: int = 200
edge_pair_min_distance: int = 15
@dataclass
class CropContext:
image: bytes
surrounding_text: str = ""
position_hint: str = ""
def pipeline_config_from_dict(data: Dict[str, Any]) -> PipelineConfig:
"""Deserialize a PipelineConfig from a JSONB dict."""
stages = [StageRef(**s) for s in data.get("stages", [])]
edges = [Edge(**e) for e in data.get("edges", [])]
return PipelineConfig(
name=data.get("name", ""),
profile_name=data.get("profile_name", ""),
stages=stages,
edges=edges,
routing_rules=data.get("routing_rules", {}),
)
class ContentTypeProfile(Protocol):
name: str
pipeline: Dict[str, Any] # JSONB blob — PipelineConfig shape
def pipeline_config(self) -> PipelineConfig: ...
def frame_extraction_config(self) -> FrameExtractionConfig: ...
def scene_filter_config(self) -> SceneFilterConfig: ...
def region_analysis_config(self) -> RegionAnalysisConfig: ...
def detection_config(self) -> DetectionConfig: ...
def ocr_config(self) -> OCRConfig: ...
def resolver_config(self) -> ResolverConfig: ...
def vlm_prompt(self, crop_context: CropContext) -> str: ...
def aggregate(self, detections: list[BrandDetection]) -> DetectionReport: ...
def auxiliary_detections(self, source: str) -> list[BrandDetection]: ...