neurofocus-backend / scoring.py
akhilc19's picture
Deploy NeuroFocus backend (FastAPI + DETR)
b86ffcf verified
Raw
History Blame Contribute Delete
2.04 kB
"""Neuro-inspired scoring for a detected scene.
These scores are a SIMULATION for visualization, not a neuroscience measurement
and not a medical diagnosis. They are simple, transparent heuristics derived from
the object detections.
"""
from statistics import fmean, pvariance
def _box_center(box: dict) -> tuple:
return (
(box["xmin"] + box["xmax"]) / 2.0,
(box["ymin"] + box["ymax"]) / 2.0,
)
def compute_scores(detection: dict) -> dict:
"""Build 0-100 scores from a detection result (see detection.detect)."""
objects = detection["objects"]
size = detection["image_size"]
width = max(size["width"], 1)
height = max(size["height"], 1)
object_count = len(objects)
# More objects -> more clutter.
visual_clutter = min(object_count * 12, 100)
# Spatial spread: how scattered the object centers are across the frame.
# Normalized variance of centers (0 = all stacked, ~100 = spread to corners).
if object_count >= 2:
cx = [_box_center(o["box"])[0] / width for o in objects]
cy = [_box_center(o["box"])[1] / height for o in objects]
spread = (pvariance(cx) + pvariance(cy)) # each variance in [0, 0.25]
spread_score = min(spread / 0.5 * 100, 100)
else:
spread_score = 0.0
# Harder to focus when there are many objects AND they are spread out.
focus_difficulty = round(0.6 * visual_clutter + 0.4 * spread_score)
# Confidence of the single most prominent object.
if objects:
top = objects[0]
primary_object = {
"label": top["label"],
"score": round(top["score"] * 100),
}
else:
primary_object = {"label": None, "score": 0}
scene_complexity = round(fmean([visual_clutter, focus_difficulty]))
return {
"object_count": object_count,
"visual_clutter": int(visual_clutter),
"focus_difficulty": int(focus_difficulty),
"primary_object": primary_object,
"scene_complexity": int(scene_complexity),
}