迁移 Flutter 端与训练脚本,模型/训练产物移出 git(遵循纯代码约定)
This commit is contained in:
@@ -0,0 +1,53 @@
|
||||
import 'dart:typed_data';
|
||||
|
||||
import '../detection/detection_result.dart';
|
||||
import '../detection/motion_aggregator.dart';
|
||||
|
||||
/// 轻量运动检测:相邻帧 Y 通道差分 + 分块聚合。
|
||||
/// 小尺寸工作(约 128x128 内),在分析流中串行调用。
|
||||
/// 相机大幅移动时(全屏帧差)自动忽略本帧,避免误报。
|
||||
class MotionDetector {
|
||||
final int maxWidth;
|
||||
final int maxHeight;
|
||||
|
||||
List<int>? _prevGray;
|
||||
|
||||
MotionDetector({this.maxWidth = 128, this.maxHeight = 128});
|
||||
|
||||
/// 后台 isolate 用原始数据接口(不依赖 CameraImage)。
|
||||
List<MotionRegion> detectMotionRaw(
|
||||
Uint8List yPlane, int yStride, int width, int height) {
|
||||
final w = width, h = height;
|
||||
final scale = maxWidth / w < maxHeight / h ? maxWidth / w : maxHeight / h;
|
||||
final tw = (w * scale).toInt().clamp(1, maxWidth);
|
||||
final th = (h * scale).toInt().clamp(1, maxHeight);
|
||||
if (tw == 0 || th == 0) return const [];
|
||||
|
||||
// 取 Y 平面缩放灰度(最近邻下采样到 128x128 内)
|
||||
final y = yPlane;
|
||||
final gray = List<int>.filled(tw * th, 0);
|
||||
for (var oy = 0; oy < th; oy++) {
|
||||
final sy = (oy / scale).toInt().clamp(0, h - 1);
|
||||
for (var ox = 0; ox < tw; ox++) {
|
||||
final sx = (ox / scale).toInt().clamp(0, w - 1);
|
||||
gray[oy * tw + ox] = y[sy * yStride + sx];
|
||||
}
|
||||
}
|
||||
|
||||
final prev = _prevGray;
|
||||
_prevGray = List.of(gray);
|
||||
if (prev == null || prev.length != gray.length) return const [];
|
||||
|
||||
final diff = MotionAggregator.diffMask(gray, prev);
|
||||
final motionTotal = diff.fold(0, (a, b) => a + b);
|
||||
// 全屏大差异 → 相机移动/大范围变化,忽略本帧
|
||||
if (motionTotal > tw * th / 2) return const [];
|
||||
if (motionTotal < 12) return const [];
|
||||
return MotionAggregator.aggregate(diff, tw, th);
|
||||
}
|
||||
|
||||
/// 相机切换后重置参考帧,避免旧帧误差
|
||||
void reset() {
|
||||
_prevGray = null;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user