"""Pixel-to-inch calibration using the conveyor belt as a known reference. The 30" belt width is mapped to the image HEIGHT (in pixels), not image width. This matches the camera setup where the 30" cross-belt dimension corresponds to the shorter side of the cropped region of interest. """ from __future__ import annotations import pandas as pd BELT_WIDTH_IN_DEFAULT = 30.0 def apply_real_scale(df: pd.DataFrame, belt_width_in: float = BELT_WIDTH_IN_DEFAULT) -> pd.DataFrame: """Add real-scale columns derived from belt-width calibration. Adds: width_in, height_in, inMinDim, area_poly_in2. Expects columns: img_height_px, width_px, height_px, area_poly_px. """ df = df.copy() inch_per_px = belt_width_in / df["img_height_px"] scale_area_in2 = inch_per_px**2 df["width_in"] = df["width_px"] * inch_per_px df["height_in"] = df["height_px"] * inch_per_px df["inMinDim"] = df[["width_in", "height_in"]].min(axis=1) df["area_poly_in2"] = df["area_poly_px"] * scale_area_in2 return df