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

在R中实现人脸关键点坐标对齐:统一眼点Y与特定点X坐标

人脸关键点对齐的R语言实现

需求拆解

你需要实现两个核心对齐目标:

  • 让关键点39和42的Y坐标一致(使眼睛连线水平)
  • 让关键点27和8的X坐标相同(使鼻梁垂直)

下面是具体的实现步骤和代码,假设你的数据框名为face_landmarks,包含landmark_id、x_new_norm、y_new_norm三列。


步骤1:提取目标关键点坐标

先从数据中取出需要用于计算变换的四个关键点:

library(dplyr)
library(tidyr)

# 提取关键点位坐标
key_coords <- face_landmarks %>%
  filter(landmark_id %in% c(8, 27, 39, 42)) %>%
  pivot_wider(
    names_from = landmark_id,
    values_from = c(x_new_norm, y_new_norm)
  )

# 赋值到变量方便后续计算
x8 <- key_coords$x_new_norm_8
y8 <- key_coords$y_new_norm_8
x27 <- key_coords$x_new_norm_27
y27 <- key_coords$y_new_norm_27
x39 <- key_coords$x_new_norm_39
y39 <- key_coords$y_new_norm_39
x42 <- key_coords$x_new_norm_42
y42 <- key_coords$y_new_norm_42

步骤2:旋转变换让眼睛连线水平

计算眼睛连线的倾斜角度,对所有关键点做旋转变换,让39和42的Y坐标一致:

# 计算旋转弧度:让39-42的连线水平
rotate_angle <- atan2(y42 - y39, x42 - x39)

# 定义旋转变换函数(以39点为旋转中心,减少整体偏移)
rotate <- function(x, y, angle, cx, cy) {
  list(
    x_rot = (x - cx) * cos(-angle) - (y - cy) * sin(-angle) + cx,
    y_rot = (x - cx) * sin(-angle) + (y - cy) * cos(-angle) + cy
  )
}

# 应用旋转到所有关键点
landmarks_rotated <- face_landmarks %>%
  rowwise() %>%
  mutate(rotate(x_new_norm, y_new_norm, rotate_angle, x39, y39)) %>%
  ungroup()

此时检查39和42的Y坐标,应该已经相等。

步骤3:平移调整让鼻梁垂直

旋转后,调整所有点的X坐标,让27和8的X值相同:

# 取旋转后的27和8点的X坐标
x27_rot <- landmarks_rotated %>% filter(landmark_id == 27) %>% pull(x_rot)
x8_rot <- landmarks_rotated %>% filter(landmark_id == 8) %>% pull(x_rot)

# 计算X方向偏移量,将8点对齐到27点的X位置
x_shift <- x27_rot - x8_rot

# 应用平移得到最终对齐后的坐标
landmarks_aligned <- landmarks_rotated %>%
  mutate(
    x_aligned = x_rot + x_shift,
    y_aligned = y_rot
  )

验证效果

可以通过代码检查对齐是否达标,或者绘制关键点可视化:

# 检查眼睛Y坐标是否一致
landmarks_aligned %>% filter(landmark_id %in% c(39,42)) %>% select(landmark_id, y_aligned)

# 检查鼻梁X坐标是否相同
landmarks_aligned %>% filter(landmark_id %in% c(27,8)) %>% select(landmark_id, x_aligned)

# 绘制对齐后的关键点(可选)
library(ggplot2)
ggplot(landmarks_aligned, aes(x = x_aligned, y = y_aligned)) +
  geom_point(size = 2, aes(color = factor(landmark_id))) +
  coord_fixed() +
  theme_minimal() +
  theme(legend.position = "none")

可选优化

  • 可以更换旋转中心(比如用人脸中心点),避免人脸整体偏移;
  • 如果需要统一人脸大小,对齐后可以加入缩放步骤,比如将眼睛间距固定为某个值;
  • 处理多个人脸数据时,将上述逻辑封装成函数,用group_by按人脸分组处理。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 03:31:05