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

如何利用ARCore提取用户面部眼眉区域的独立图像?

使用ARCore提取面部眼眉区域独立图像的方法

ARCore本身没有直接提供提取面部特定区域的API,但可以基于其面部追踪的核心数据(面部网格、纹理坐标、关键点)自定义实现,具体步骤如下:

1. 初始化面部追踪并获取Face实例

确保AR会话开启面部追踪模式,在每一帧回调中获取当前检测到的Face对象:

// 初始化AR会话时配置面部追踪
val config = ARSessionConfiguration(session)
config.enableFaceTracking = true
session.configure(config)

// 在帧更新逻辑中获取Face
session.update()
val faceList = session.getAllTrackables(Face::class.java)
if (faceList.isNotEmpty()) {
    val face = faceList.first()
    // 后续区域提取逻辑
}

2. 定位眼眉区域的关键点边界

利用FaceLandmark获取眼眉及周边关键标记点,推导目标区域的UV坐标范围:

// 获取左右眼眉、眼睛的核心关键点
val leftEyebrowTop = face.getLandmark(FaceLandmark.Type.LEFT_EYEBROW_TOP)
val leftEyebrowBottom = face.getLandmark(FaceLandmark.Type.LEFT_EYEBROW_BOTTOM)
val leftEyeTop = face.getLandmark(FaceLandmark.Type.LEFT_EYE_TOP)
val leftEyeBottom = face.getLandmark(FaceLandmark.Type.LEFT_EYE_BOTTOM)

val rightEyebrowTop = face.getLandmark(FaceLandmark.Type.RIGHT_EYEBROW_TOP)
val rightEyebrowBottom = face.getLandmark(FaceLandmark.Type.RIGHT_EYEBROW_BOTTOM)
val rightEyeTop = face.getLandmark(FaceLandmark.Type.RIGHT_EYE_TOP)
val rightEyeBottom = face.getLandmark(FaceLandmark.Type.RIGHT_EYE_BOTTOM)

// 计算目标区域的UV边界
val allLandmarkUvs = listOf(
    leftEyebrowTop.uvCoordinate, leftEyebrowBottom.uvCoordinate,
    leftEyeTop.uvCoordinate, leftEyeBottom.uvCoordinate,
    rightEyebrowTop.uvCoordinate, rightEyebrowBottom.uvCoordinate,
    rightEyeTop.uvCoordinate, rightEyeBottom.uvCoordinate
)
val minU = allLandmarkUvs.minOf { it.x }
val maxU = allLandmarkUvs.maxOf { it.y }
val minV = allLandmarkUvs.minOf { it.x }
val maxV = allLandmarkUvs.maxOf { it.y }

3. 从相机纹理中裁剪对应区域

将UV坐标转换为像素坐标,从相机帧的YUV纹理中裁剪目标区域:

// 获取当前相机帧图像
val frame = session.update()
val image = frame.acquireCameraImage()
val width = image.width
val height = image.height

// 将UV坐标转为图像像素坐标(适配YUV纹理的坐标系翻转)
val startX = (minU * width).toInt()
val endX = (maxU * width).toInt()
val startY = ((1 - maxV) * height).toInt()
val endY = ((1 - minV) * height).toInt()

// 裁剪并转换为RGB Bitmap
val yuvImage = YuvImage(image.planes[0].buffer, ImageFormat.NV21, width, height, null)
val outputStream = ByteArrayOutputStream()
yuvImage.compressToJpeg(Rect(startX, startY, endX, endY), 100, outputStream)
val croppedBitmap = BitmapFactory.decodeByteArray(outputStream.toByteArray(), 0, outputStream.size())

4. 优化细节

  • 若关键点定位精度不足,可结合FaceMesh的三角面数据,获取覆盖眼眉区域的所有网格顶点UV,进一步缩小误差;
  • 不同设备的相机纹理坐标系可能有差异,需测试调整V轴翻转逻辑;
  • 可添加帧间平滑处理,避免裁剪区域出现抖动。

内容的提问来源于stack exchange,提问作者SharpAffair

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 20:50:20