This commit is contained in:
2026-09-01 15:18:05 +08:00
parent dcde05d67c
commit abccda0bd6
19 changed files with 381 additions and 160 deletions
+1 -1
View File
@@ -91,7 +91,7 @@ class _CameraScreenState extends State<CameraScreen> {
const SizedBox(height: 8),
const Text(
'阈值越低识别越灵敏(低分框越多,误报也可能增加);'
'环颈雉鸡模型置信度普遍在 10%~20%,场景识别不到时可适当调低。',
'不同模型置信度分布不同,识别不到目标时可适当调低阈值',
style: TextStyle(color: Colors.white54, fontSize: 12),
),
const SizedBox(height: 16),
@@ -105,9 +105,10 @@ class CameraViewModel extends ChangeNotifier {
visible.add(r.copyWith(confirmed: t.confirmed));
}
// 提醒:仅新确认的环颈雉鸡轨迹(确认瞬间触发一次,10s 同类冷却在 Reminder 内)
// 提醒:仅新确认的目标物种轨迹(class 0,如环颈雉鸡确认瞬间触发一次,10s 同类冷却在 Reminder 内)
for (final t in _tracks.values) {
if (t.label != 'pheasant' || !t.confirmed || t.reminded) continue;
final isSuspect = t.result.classId > 0 || t.label == 'suspect';
if (isSuspect || !t.confirmed || t.reminded) continue;
final age = now - t.firstSeenMs;
if (age >= displayAgeMs && age <= displayAgeMs + 1600 &&
now - t.lastSeenMs <= 300) {
@@ -184,7 +185,7 @@ class CameraViewModel extends ChangeNotifier {
/// - 环颈雉鸡:确认轨迹直接显示;未确认的只有在高分或活动证据时才显示
bool _shouldDisplay(_Track t, List<MotionRegion> motionRegions,
List<MotionRegion> noveltyRegions) {
if (t.label == 'suspect') return true;
if (t.result.classId > 0 || t.label == 'suspect') return true;
if (t.confirmed) return true;
return t.result.score >= highConf ||
_hasActivity(t.result, motionRegions, noveltyRegions);
@@ -203,7 +204,7 @@ class CameraViewModel extends ChangeNotifier {
if (w <= 0 || h <= 0) return false;
final aspect = w / h;
if (aspect < 0.3 || aspect > 3.0) return false;
if (r.label == 'suspect') return h >= 0.01 && h <= 0.5;
if (r.classId > 0 || r.label == 'suspect') return h >= 0.01 && h <= 0.5;
return h >= 0.01 && h <= 0.3;
}
+10 -10
View File
@@ -44,14 +44,11 @@ class _OverlayPainter extends CustomPainter {
_OverlayPainter(this.results, this.rotation, this.imageWidthPx,
this.imageHeightPx);
static const _colors = {
'pheasant': Color(0xFFE53935),
'suspect': Color(0xFFFDD835),
};
static const _labels = {'pheasant': '环颈雉鸡', 'suspect': '疑似'};
/// 参考体型(米):环颈雉鸡身高 / 植被高度(参照旧 DistanceEstimator
static const _refSizeM = {'pheasant': 0.45, 'suspect': 0.50};
/// 参考体型(米):目标物种(class 0,如环颈雉鸡身高 / suspect 植被高度
static const double _refSizeSpeciesM = 0.45;
static const double _refSizeSuspectM = 0.50;
/// iPhone 13 主摄在 1280 高预览下的估算焦距 px5.1mm / 5.30mm 传感器),
/// 单目误差 ±30%,仅作参考
@@ -72,8 +69,10 @@ class _OverlayPainter extends CustomPainter {
size.width,
size.height,
);
final color = _colors[r.label] ?? Colors.white;
final isSuspect = r.label == 'suspect';
// 颜色按类别索引而非 label 文本:模型类别名可能为中文(环颈雉)或
// 随数据集变化,class 0 恒为目标物种(红),其余类恒为 suspect(黄)
final isSuspect = r.classId > 0 || r.label == 'suspect';
final color = isSuspect ? Color(0xFFFDD835) : Color(0xFFE53935);
final confirmed = r.confirmed && !isSuspect;
final paint = Paint()
..color = color.withValues(alpha: confirmed ? 1.0 : 0.55)
@@ -113,8 +112,9 @@ class _OverlayPainter extends CustomPainter {
}
String _distanceLabel(DetectionResult r) {
final refH = _refSizeM[r.label];
if (refH == null) return '';
final refH = (r.classId > 0 || r.label == 'suspect')
? _refSizeSuspectM
: _refSizeSpeciesM;
final hPx = r.height * imageHeightPx;
if (hPx < 8) return '';
final m = focalPx * refH / hPx;