Calibrate systematic roof box offsets
This commit is contained in:
@@ -52,12 +52,19 @@ def metrics(tp: int, fp: int, fn: int) -> dict[str, float | int]:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def scale_box(box: tuple[float, float, float, float], factor: float) -> tuple[float, float, float, float]:
|
def scale_box(
|
||||||
|
box: tuple[float, float, float, float], factor: float, offset_x: float = 0.0, offset_y: float = 0.0
|
||||||
|
) -> tuple[float, float, float, float]:
|
||||||
"""Scale a detector box around its center for calibration-only geometry correction."""
|
"""Scale a detector box around its center for calibration-only geometry correction."""
|
||||||
x1, y1, x2, y2 = box
|
x1, y1, x2, y2 = box
|
||||||
cx, cy = (x1 + x2) / 2, (y1 + y2) / 2
|
cx, cy = (x1 + x2) / 2, (y1 + y2) / 2
|
||||||
half_width, half_height = (x2 - x1) * factor / 2, (y2 - y1) * factor / 2
|
half_width, half_height = (x2 - x1) * factor / 2, (y2 - y1) * factor / 2
|
||||||
return cx - half_width, cy - half_height, cx + half_width, cy + half_height
|
return (
|
||||||
|
cx - half_width + offset_x,
|
||||||
|
cy - half_height + offset_y,
|
||||||
|
cx + half_width + offset_x,
|
||||||
|
cy + half_height + offset_y,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def read_references(path: Path, width: int, height: int) -> list[tuple[float, float, float, float]]:
|
def read_references(path: Path, width: int, height: int) -> list[tuple[float, float, float, float]]:
|
||||||
@@ -97,6 +104,8 @@ def main() -> int:
|
|||||||
help="Maximum detections retained per tile; dense Belgian urban tiles exceed YOLO's default 300.",
|
help="Maximum detections retained per tile; dense Belgian urban tiles exceed YOLO's default 300.",
|
||||||
)
|
)
|
||||||
parser.add_argument("--box-scale", type=float, default=1.0)
|
parser.add_argument("--box-scale", type=float, default=1.0)
|
||||||
|
parser.add_argument("--box-offset-x", type=float, default=0.0)
|
||||||
|
parser.add_argument("--box-offset-y", type=float, default=0.0)
|
||||||
parser.add_argument("--proposal-classifier", type=Path)
|
parser.add_argument("--proposal-classifier", type=Path)
|
||||||
parser.add_argument("--proposal-classifier-threshold", type=float, default=0.5)
|
parser.add_argument("--proposal-classifier-threshold", type=float, default=0.5)
|
||||||
parser.add_argument("--proposal-crop-scale", type=float, default=1.4)
|
parser.add_argument("--proposal-crop-scale", type=float, default=1.4)
|
||||||
@@ -142,7 +151,12 @@ def main() -> int:
|
|||||||
for tile, result in zip(tiles, results, strict=True):
|
for tile, result in zip(tiles, results, strict=True):
|
||||||
height, width = result.orig_shape
|
height, width = result.orig_shape
|
||||||
predictions = [
|
predictions = [
|
||||||
(scale_box(tuple(map(float, box)), args.box_scale), float(score))
|
(
|
||||||
|
scale_box(
|
||||||
|
tuple(map(float, box)), args.box_scale, args.box_offset_x, args.box_offset_y
|
||||||
|
),
|
||||||
|
float(score),
|
||||||
|
)
|
||||||
for box, score in zip(result.boxes.xyxy.cpu().tolist(), result.boxes.conf.cpu().tolist(), strict=True)
|
for box, score in zip(result.boxes.xyxy.cpu().tolist(), result.boxes.conf.cpu().tolist(), strict=True)
|
||||||
]
|
]
|
||||||
if proposal_classifier is not None:
|
if proposal_classifier is not None:
|
||||||
@@ -213,6 +227,8 @@ def main() -> int:
|
|||||||
"inference_imgsz": args.imgsz,
|
"inference_imgsz": args.imgsz,
|
||||||
"max_detections_per_tile": args.max_det,
|
"max_detections_per_tile": args.max_det,
|
||||||
"box_scale": args.box_scale,
|
"box_scale": args.box_scale,
|
||||||
|
"box_offset_x": args.box_offset_x,
|
||||||
|
"box_offset_y": args.box_offset_y,
|
||||||
"proposal_classifier": str(args.proposal_classifier) if args.proposal_classifier else None,
|
"proposal_classifier": str(args.proposal_classifier) if args.proposal_classifier else None,
|
||||||
"proposal_classifier_threshold": args.proposal_classifier_threshold if args.proposal_classifier else None,
|
"proposal_classifier_threshold": args.proposal_classifier_threshold if args.proposal_classifier else None,
|
||||||
"proposal_crop_scale": args.proposal_crop_scale if args.proposal_classifier else None,
|
"proposal_crop_scale": args.proposal_crop_scale if args.proposal_classifier else None,
|
||||||
|
|||||||
Reference in New Issue
Block a user