| """ |
| Image quality analysis provider. |
| |
| Delegates all metric computation to cores.vision.quality — no duplicated |
| brightness/contrast/sharpness/noise logic. |
| """ |
|
|
| from __future__ import annotations |
|
|
| import numpy as np |
|
|
| from config.settings import Settings, settings as _default_settings |
| from cores.vision import brightness, contrast, sharpness, noise_level, quality_score |
| from pipeline.feature_extraction import PipelineOutput |
| from providers.base import BaseProvider, ProviderCapability |
|
|
|
|
| class ImageQualityProvider(BaseProvider): |
| name = "image_quality" |
| capability = ProviderCapability.IMAGE_ANALYSIS |
|
|
| def __init__(self, settings: Settings | None = None) -> None: |
| super().__init__(settings=settings or _default_settings) |
|
|
| def is_available(self) -> bool: |
| return True |
|
|
| def _run(self, pipeline_output: PipelineOutput) -> tuple[dict, dict]: |
| img: np.ndarray = pipeline_output.image |
| b = brightness(img) |
| c = contrast(img) |
| s = sharpness(img) |
| n = noise_level(img) |
| q = quality_score(img) |
|
|
| raw = { |
| "brightness": b, |
| "contrast": c, |
| "sharpness": s, |
| "noise_level": n, |
| "quality_score": q, |
| "image_size": {"width": img.shape[1], "height": img.shape[0]}, |
| } |
| normalized = { |
| "quality_score": round(q, 4), |
| "brightness": round(b, 4), |
| "contrast": round(c, 4), |
| "sharpness": round(s, 4), |
| "noise_level": round(n, 4), |
| "width": int(img.shape[1]), |
| "height": int(img.shape[0]), |
| "channels": int(img.shape[2]) if img.ndim == 3 else 1, |
| "color_profile": None, |
| "dominant_colors": [], |
| "aspects": { |
| "method": "variance_of_laplacian", |
| "noise_method": "median_absolute_deviation", |
| }, |
| } |
| return raw, normalized |
|
|