鸿蒙开发-实战:用AR Engine做虚拟试衣
实战:用 AR Engine 做虚拟试衣
虚拟试衣是 AR 技术最热门的应用之一——用户打开摄像头,选择一件衣服,衣服就"穿"在身上了。今天我们来看看用 AR Engine 怎么实现这个功能。
虚拟试衣整体流程
下面是虚拟试衣的完整工作流程:
虚拟试衣的原理
虚拟试衣的核心是人体骨骼检测 + 3D 模型渲染:
- 人体骨骼检测:AR Engine 检测摄像头画面中的人体,识别出肩膀、手臂、躯干等关键点
- 3D 模型渲染:根据骨骼位置,把衣服的 3D 模型"贴"在正确的位置
- 实时更新:随着人体移动,衣服模型跟着移动
第一步:定义人体关键点
import { arEngine } from '@kit.ArkGraphics2D';
import { common } from '@kit.AbilityKit';
导入需要的模块。
// 人体关键点索引
const BODY_JOINTS = {
HEAD: 0,
NECK: 1,
LEFT_SHOULDER: 2,
RIGHT_SHOULDER: 3,
LEFT_ELBOW: 4,
RIGHT_ELBOW: 5,
LEFT_WRIST: 6,
RIGHT_WRIST: 7,
HIP: 8,
LEFT_HIP: 9,
RIGHT_HIP: 10,
LEFT_KNEE: 11,
RIGHT_KNEE: 12,
LEFT_ANKLE: 13,
RIGHT_ANKLE: 14
};
AR Engine 检测人体时,会返回 15 个关键点的位置。每个关键点有一个索引,从头部(0)到脚踝(14)。
第二步:初始化 AR
@Entry
@Component
struct VirtualTryOn {
@State status: string = '初始化中...';
@State selectedClothing: string = 'tshirt';
private arSession: arEngine.ARSession | null = null;
定义状态变量。
async aboutToAppear() {
await this.initAR();
}
async initAR() {
const context: Context = this.getUIContext().getHostContext() as common.UIAbilityContext;
获取上下文。
// 检查 AR 能力
let isSupported = arEngine.isSupport(context);
if (!isSupported) {
this.status = '设备不支持 AR';
return;
}
先检查设备是否支持 AR。不支持的话直接提示用户。
// 创建 AR Session
let config: arEngine.ARSessionConfig = {
// 启用人体骨骼追踪
planeFindingMode: arEngine.PlaneFindingMode.DISABLE,
bodyTrackingMode: arEngine.BodyTrackingMode.ENABLE
};
this.arSession = await arEngine.createSession(context, config);
创建 AR Session 时,启用人体骨骼追踪,禁用平面检测(虚拟试衣不需要平面检测)。
if (this.arSession == null) {
this.status = '创建 AR Session 失败';
return;
}
// 启动 AR
this.arSession.start();
this.status = '请面对摄像头';
启动 AR,开始检测。
第三步:检测人体
// 开始检测人体
this.startBodyTracking();
}
startBodyTracking() {
// 每帧检测人体
setInterval(() => {
if (this.arSession == null) return;
// 获取人体数据
let bodies = this.arSession.getAllTrackables(arEngine.Body);
getAllTrackables(arEngine.Body) 获取所有检测到的人体。返回的是一个数组——理论上可以检测多个人,但我们这里只取第一个。
if (bodies.length > 0) {
let body = bodies[0];
this.status = '检测到人体,正在试衣...';
// 获取骨骼关键点
let joints = body.getJoints();
this.renderClothing(joints);
} else {
this.status = '请站在摄像头前';
}
}, 100); // 每 100ms 检测一次
}
每 100ms 检测一次人体。如果检测到,获取骨骼关键点并渲染衣服。
第四步:获取关键点位置
renderClothing(joints: Map<number, arEngine.ARBodyJoint>) {
// 根据选择的衣服类型渲染
switch (this.selectedClothing) {
case 'tshirt':
this.renderTShirt(joints);
break;
case 'jacket':
this.renderJacket(joints);
break;
case 'dress':
this.renderDress(joints);
break;
}
}
根据用户选择的衣服类型调用不同的渲染方法。
renderTShirt(joints: Map<number, arEngine.ARBodyJoint>) {
// 获取关键点位置
let leftShoulder = joints.get(BODY_JOINTS.LEFT_SHOULDER);
let rightShoulder = joints.get(BODY_JOINTS.RIGHT_SHOULDER);
let leftHip = joints.get(BODY_JOINTS.LEFT_HIP);
let rightHip = joints.get(BODY_JOINTS.RIGHT_HIP);
获取肩膀和腰部的关键点。
if (leftShoulder == null || rightShoulder == null ||
leftHip == null || rightHip == null) {
return;
}
如果关键点检测不到,直接返回。
// 计算 T 恤的位置和大小
let centerX = (leftShoulder.getPosition().x + rightShoulder.getPosition().x) / 2;
let centerY = (leftShoulder.getPosition().y + leftHip.getPosition().y) / 2;
let width = Math.abs(rightShoulder.getPosition().x - leftShoulder.getPosition().x) * 1.5;
let height = Math.abs(leftHip.getPosition().y - leftShoulder.getPosition().y);
根据肩膀和腰部的位置计算 T 恤应该放在哪里、多大尺寸。
// 这里会调用 3D 渲染引擎,把 T 恤模型放在计算出的位置
// 具体实现依赖于你使用的 3D 渲染方案
console.info(`渲染 T 恤: 中心(${centerX}, ${centerY}), 大小(${width}x${height})`);
}
实际项目中,这里会调用 3D 渲染引擎(比如 ArkGraphics 3D)把衣服模型放在计算出的位置。
第五步:页面布局
build() {
Column() {
Text(this.status)
.fontSize(18)
.margin({ top: 20 })
// AR 渲染区域
// 实际项目中,这里会放一个 AR 视图组件
// 衣服选择
Row() {
Button('T 恤')
.margin(10)
.onClick(() => this.selectedClothing = 'tshirt')
Button('夹克')
.margin(10)
.onClick(() => this.selectedClothing = 'jacket')
Button('裙子')
.margin(10)
.onClick(() => this.selectedClothing = 'dress')
}
.margin({ top: 20 })
}
.width('100%')
.height('100%')
}
显示状态文字和衣服选择按钮。
aboutToDisappear() {
if (this.arSession != null) {
this.arSession.stop();
this.arSession.release();
}
}
}
页面销毁时释放 AR 资源。
衣服位置计算流程
根据骨骼关键点计算衣服的放置位置:
实际应用中的注意事项
1. 性能优化
人体骨骼检测很消耗资源。不要每帧都检测,可以:
- 降低检测频率(比如每 100ms 检测一次)
- 用上一帧的结果做平滑过渡
- 在不需要时暂停检测
2. 骨骼点平滑
骨骼检测结果会有抖动。你可以用简单的平滑算法:
smoothJoint(current: Position, previous: Position, factor: number = 0.7): Position {
return {
x: previous.x * factor + current.x * (1 - factor),
y: previous.y * factor + current.y * (1 - factor)
};
}
3. 遮挡处理
当用户转身或手臂遮挡身体时,部分关键点可能检测不到。你需要处理这些边界情况。
性能优化策略
虚拟试衣需要注意性能优化和边界情况:
小结
虚拟试衣的核心流程:
arEngine.createSession创建 AR Session,启用人体追踪getAllTrackables(arEngine.Body)检测人体getJoints()获取骨骼关键点- 根据关键点位置计算衣服的放置位置
- 渲染 3D 衣服模型
AR Engine 提供了人体骨骼检测能力,但 3D 模型渲染部分需要你结合其他图形 API(比如 ArkGraphics 3D)来实现。
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐


所有评论(0)