You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter ML Kit姿势检测坐标与屏幕位置不匹配,如何正确放置自定义Widget

Flutter ML Kit 姿势关键点坐标匹配解决方案

问题核心

ML Kit 返回来的人体关键点坐标是相对于输入推理的原始图像帧的尺寸,并非你页面中实际渲染的相机预览Widget的尺寸,再加上相机预览的宽高比适配、横竖屏旋转、前后摄像头镜像三个变量的影响,直接使用原始坐标必然会出现位置错位、偏移的问题。

修复步骤

1. 采集基础参数

你需要提前拿到3组核心参数:

  • 原始输入帧的尺寸:即传入ML Kit做推理的InputImage对应的宽高
  • 实际渲染的相机预览尺寸:通过绑定GlobalKey到相机预览组件的父容器获取:
final GlobalKey previewKey = GlobalKey();
// 绑定到你包裹CameraPreview的Container上
// 组件渲染完成后获取实际尺寸
Size previewSize = previewKey.currentContext!.size!;
  • 设备当前方向、相机朝向(前置/后置)

2. 计算缩放与偏移参数

相机预览一般默认按BoxFit.cover适配屏幕,需要先计算缩放比和适配偏移:

// 适配横竖屏,调整原始输入帧的宽高
bool isLandscape = MediaQuery.of(context).orientation == Orientation.landscape;
double adjustedInputWidth = isLandscape ? inputImageSize.width : inputImageSize.height;
double adjustedInputHeight = isLandscape ? inputImageSize.height : inputImageSize.width;

// 计算缩放比,cover模式取宽高缩放的最大值
double scaleX = previewSize.width / adjustedInputWidth;
double scaleY = previewSize.height / adjustedInputHeight;
double finalScale = max(scaleX, scaleY);

// 计算宽高比不一致产生的留白偏移
double offsetX = (previewSize.width - adjustedInputWidth * finalScale) / 2;
double offsetY = (previewSize.height - adjustedInputHeight * finalScale) / 2;

3. 转换原始关键点坐标到屏幕坐标

// 取原始关键点坐标
double rawX = pose.landmarks[PoseLandmarkType.rightShoulder]!.x;
double rawY = pose.landmarks[PoseLandmarkType.rightShoulder]!.y;

// 适配横竖屏转换坐标
double adjustedX, adjustedY;
if (isLandscape) {
  adjustedX = rawX;
  adjustedY = rawY;
} else {
  adjustedX = rawY;
  adjustedY = inputImageSize.width - rawX;
}

// 应用缩放和偏移得到屏幕坐标
double screenX = adjustedX * finalScale + offsetX;
double screenY = adjustedY * finalScale + offsetY;

// 前置摄像头需要做x轴镜像翻转
bool isFrontCamera = /*你的相机朝向判断逻辑*/;
if (isFrontCamera) {
  screenX = previewSize.width - screenX;
}

// 最终更新坐标
setState(() {
  x = screenX;
  y = screenY;
});

4. 自定义Widget位置微调

如果你希望自定义Widget的中心点对准关键点,需要在Positioned参数里减去Widget自身宽高的一半:

Positioned(
  // 假设你的自定义Widget宽高都是20
  left: x - 10,
  top: y - 10,
  child: YourCustomMarker(),
)

内容的提问来源于stack exchange,提问作者Débora

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 00:09:00