Files
observer/flutter_app/lib/detection/coordinate_mapper.dart
T
admin a0b115d954 训练体系整合与标注单阶段化
- 标注:AI 预标注直写 labels_json(去候选确认两阶段);重叠去重(minIoU);全量标注按钮
- 训练:脚本迁移入 server/training/(Go 化 prepare_yolo/analyze_rfdetr,保留 train_server.py);tflite 产物自检并入训练流程(check_tflite)
- 数据目录/权重不进 git;.gitignore 迁移至仓库根
2026-08-26 18:22:56 +08:00

70 lines
1.9 KiB
Dart

class ViewRect {
final double left;
final double top;
final double right;
final double bottom;
const ViewRect(this.left, this.top, this.right, this.bottom);
double get width => right - left;
double get height => bottom - top;
double get centerX => (left + right) / 2;
double get centerY => (top + bottom) / 2;
}
/// 模型归一化坐标 → 预览视图坐标(含传感器旋转与 FIT_COVER 全屏裁剪)。
class CoordinateMapper {
static ViewRect mapToView(
double normLeft,
double normTop,
double normRight,
double normBottom,
int rotation,
int imageW,
int imageH,
double viewW,
double viewH,
) {
// 1) 旋转校正:图像方向 → 竖屏视图方向(归一化坐标)
late final double x0, y0, x1, y1;
switch (rotation) {
case 90:
x0 = 1 - normBottom;
y0 = normLeft;
x1 = 1 - normTop;
y1 = normRight;
case 180:
x0 = 1 - normRight;
y0 = 1 - normBottom;
x1 = 1 - normLeft;
y1 = 1 - normTop;
case 270:
x0 = normTop;
y0 = 1 - normRight;
x1 = normBottom;
y1 = 1 - normLeft;
default:
x0 = normLeft;
y0 = normTop;
x1 = normRight;
y1 = normBottom;
}
// 2) 旋转后图像在竖屏方向上的尺寸
final portrait = rotation == 90 || rotation == 270;
final portW = portrait ? imageH : imageW;
final portH = portrait ? imageW : imageH;
// 3) FIT_COVER 缩放与居中裁剪:放大到铺满视图,溢出部分裁掉
final scale = viewW / portW < viewH / portH
? viewH / portH
: viewW / portW;
final offsetX = (viewW - portW * scale) / 2;
final offsetY = (viewH - portH * scale) / 2;
return ViewRect(
x0 * portW * scale + offsetX,
y0 * portH * scale + offsetY,
x1 * portW * scale + offsetX,
y1 * portH * scale + offsetY,
);
}
}