Files
observer/flutter_app/lib/detection/nms.dart
T
2026-09-01 17:47:03 +08:00

38 lines
1.5 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import 'detection_result.dart';
double iou(DetectionResult a, DetectionResult b) {
final x0 = a.left > b.left ? a.left : b.left;
final y0 = a.top > b.top ? a.top : b.top;
final x1 = a.right < b.right ? a.right : b.right;
final y1 = a.bottom < b.bottom ? a.bottom : b.bottom;
if (x1 <= x0 || y1 <= y0) return 0;
final inter = (x1 - x0) * (y1 - y0);
final union = a.width * a.height + b.width * b.height - inter;
return union <= 0 ? 0 : inter / union;
}
/// 交叠/较小框面积(minIoU):同一目标的一大一小两框时比 IoU 更能命中
/// IoU = 小/大 会漏判;YOLO 同目标常输出大小两框,与 server 标注端
/// localAi.overlapThreshold 同思路,2026-09-01 用户实测修订)。
double boxOverlap(DetectionResult a, DetectionResult b) {
final x0 = a.left > b.left ? a.left : b.left;
final y0 = a.top > b.top ? a.top : b.top;
final x1 = a.right < b.right ? a.right : b.right;
final y1 = a.bottom < b.bottom ? a.bottom : b.bottom;
if (x1 <= x0 || y1 <= y0) return 0;
final inter = (x1 - x0) * (y1 - y0);
final minArea = a.width * a.height < b.width * b.height
? a.width * a.height
: b.width * b.height;
return minArea <= 0 ? 0 : inter / minArea;
}
List<DetectionResult> nms(List<DetectionResult> boxes, double iouThreshold) {
final sorted = [...boxes]..sort((a, b) => b.score.compareTo(a.score));
final kept = <DetectionResult>[];
for (final b in sorted) {
if (!kept.any((k) => boxOverlap(b, k) > iouThreshold)) kept.add(b);
}
return kept;
}