This commit is contained in:
2026-09-03 10:01:42 +08:00
parent 71d042906c
commit 7bfafc7be3
18 changed files with 671 additions and 228 deletions
+8 -7
View File
@@ -3,14 +3,15 @@ import 'dart:typed_data';
import 'detection_result.dart';
/// 运行时视觉先验:对低置信度环颈雉鸡框做多线索过滤,降低户外误报。
/// 运行时视觉先验:对低置信度目标物种框(class 0做多线索过滤,降低户外误报。
/// 识别哪些类为目标物种由模型训练决定,本先验不依赖任何具体物种名。
///
/// 仅对 score < [maxScore]0.35)的 pheasant 框生效;高分框与
/// 仅对 score < [maxScore]0.35)的目标框生效;高分框与
/// suspect(生境预警)不参与过滤,避免误杀。
///
/// 线索:
/// - 颜色:绿色主导(草/叶)、蓝色主导(天空/水)、平坦低饱和(键盘/石头/文字)
/// - 位置:中心在画面上部 15%(天空区)——环颈雉鸡是地栖动物,不会出现在天空
/// - 位置:中心在画面上部 15%(天空区)——目标物种为地面活动,不会出现在天空
///
/// 采样在原始 planes 上进行(后台 isolate 内,不依赖 UI 线程)。
class VisualPrior {
@@ -39,9 +40,9 @@ class VisualPrior {
if (results.isEmpty || width <= 0 || height <= 0) return results;
final kept = <DetectionResult>[];
for (final r in results) {
final lowConfPheasant =
(r.classId == 0 || r.label == 'pheasant') && r.score < maxScore;
if (lowConfPheasant &&
// class 0 即目标物种(各数据集标签统一:0 目标 / 其余 suspect
final lowConfTarget = r.classId == 0 && r.score < maxScore;
if (lowConfTarget &&
_reject(r, planes, strides, width, height, isBgra, rgbaOrder)) {
continue;
}
@@ -86,7 +87,7 @@ class VisualPrior {
/// 读取单像素 RGB0~255)。
/// 8888 单平面按实际字节序取通道:BGRA=[b,g,r,a]iOS 插件)、
/// RGBA=[r,g,b,a]Android 自写原生通道)——字节序写死会让 Android
/// 低分框采样到 R/B 互换的颜色(橙色环颈雉鸡身被误判成"蓝色")整批误杀;
/// 低分框采样到 R/B 互换的颜色(橙色目标躯体被误判成"蓝色")整批误杀;
/// YUVy 平面 + 4:2:0 半分辨率 U/VNV12 交错或 I420 分离)。
static (double, double, double) _pixel(List<Uint8List> planes,
List<int> strides, int x, int y, int width, int height, bool isBgra,