其他分享
首页 > 其他分享> > 在Blender中使用代码控制人物模型的眼部动作 - 睁眼与闭眼

在Blender中使用代码控制人物模型的眼部动作 - 睁眼与闭眼

作者:互联网

在Blender中使用代码控制人物模型的眼部动作 - 睁眼与闭眼

flyfish

眼睛eyeBlink_R闭眼的数值分别是0、0.5、1。而眼睛的纵横比与之相反,眼睛的纵横比越大,眼睛睁的越大。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

眼睛的纵横比的计算方法

在这里插入图片描述

眼睛的纵横比越大,眼睛睁的越大。

在这里插入图片描述

代码实现

关于眼部的关键点在mediapipe中的定义

定义左右眼常量

from enum import Enum
class Eyes(Enum):
    LEFT = 1
    RIGHT = 2 

下面定义的函数都放在FacialFeatures类中

eye_key_indicies=[
    [
    # Left eye
    # eye lower contour
    33,
    7,
    163,
    144,
    145,
    153,
    154,
    155,
    133,
    # eye upper contour (excluding corners)
    246,
    161,
    160,
    159,
    158,
    157,
    173
    ],
    [
    # Right eye
    # eye lower contour
    263,
    249,
    390,
    373,
    374,
    380,
    381,
    382,
    362,
    # eye upper contour (excluding corners)
    466,
    388,
    387,
    386,
    385,
    384,
    398
    ]
]

根据公式计算眼睛的纵横比

def eye_aspect_ratio(image_points, side):

  p1, p2, p3, p4, p5, p6 = 0, 0, 0, 0, 0, 0

  if side == Eyes.LEFT:

      eye_key_left = FacialFeatures.eye_key_indicies[0]

      p2 = np.true_divide(
          np.sum([image_points[eye_key_left[10]], image_points[eye_key_left[11]]], axis=0),
          2)
      p3 = np.true_divide(
          np.sum([image_points[eye_key_left[13]], image_points[eye_key_left[14]]], axis=0),
          2)
      p6 = np.true_divide(
          np.sum([image_points[eye_key_left[2]], image_points[eye_key_left[3]]], axis=0),
          2)
      p5 = np.true_divide(
          np.sum([image_points[eye_key_left[5]], image_points[eye_key_left[6]]], axis=0),
          2)
      p1 = image_points[eye_key_left[0]]
      p4 = image_points[eye_key_left[8]]



  elif side == Eyes.RIGHT:
      eye_key_right = FacialFeatures.eye_key_indicies[1]

      p3 = np.true_divide(
          np.sum([image_points[eye_key_right[10]], image_points[eye_key_right[11]]], axis=0),
          2)
      p2 = np.true_divide(
          np.sum([image_points[eye_key_right[13]], image_points[eye_key_right[14]]], axis=0),
          2)
      p5 = np.true_divide(
          np.sum([image_points[eye_key_right[2]], image_points[eye_key_right[3]]], axis=0),
          2)
      p6 = np.true_divide(
          np.sum([image_points[eye_key_right[5]], image_points[eye_key_right[6]]], axis=0),
          2)
      p1 = image_points[eye_key_right[8]]
      p4 = image_points[eye_key_right[0]]




  eye = np.linalg.norm(p2-p6) + np.linalg.norm(p3-p5)
  eye /= (2 * np.linalg.norm(p1-p4) + 1e-6)

  return eye

调用eye_aspect_ratio函数

eye_left = FacialFeatures.eye_aspect_ratio(self.image_points, Eyes.LEFT)
eye_right = FacialFeatures.eye_aspect_ratio(self.image_points, Eyes.RIGHT)  

关于纵横比的数值如下

结论是
眼睛的纵横比越大,眼睛睁的越大。 1 表示close ,0 表示open

闭眼的数值 close

eyeBlink_L: 0.034907369694056445
eyeBlink_L: 0.02886449999216779
eyeBlink_L: 0.027779683008495676
eyeBlink_L: 0.0296733873711843
eyeBlink_L: 0.025194830756791985
eyeBlink_L: 0.023925703810540076
eyeBlink_L: 0.02362555158269431
eyeBlink_L: 0.024502263712133474
eyeBlink_L: 0.02261911947849663
eyeBlink_L: 0.030179823404591934
eyeBlink_L: 0.02952825209564929
eyeBlink_L: 0.032452940890050824
eyeBlink_L: 0.024476440135416905

睁眼的数值 open

eyeBlink_L: 0.2934850903969735
eyeBlink_L: 0.27661537962019994
eyeBlink_L: 0.27586431888208146
eyeBlink_L: 0.26969061962212526
eyeBlink_L: 0.29001642888895196
eyeBlink_L: 0.28746851414952634
eyeBlink_L: 0.2790754801372039
eyeBlink_L: 0.2734639228995299
eyeBlink_L: 0.280324166145431
eyeBlink_L: 0.29565485858355134
eyeBlink_L: 0.2897504295557396
eyeBlink_L: 0.29699920831651744

根据上述展示的数值定义一个阈值

eye_threshold = 0.2 
if eye_left > eye_threshold:
    eye_left = 0
else:
    eye_left = 1

if eye_right > eye_threshold:
    eye_right = 0
else:
    eye_right = 1    

向模型的形态键赋值

shape_keys['eyeBlink_L'].value = eye_left
shape_keys['eyeBlink_L'].keyframe_insert(data_path='value')

shape_keys['eyeBlink_R'].value = eye_right
shape_keys['eyeBlink_R'].keyframe_insert(data_path='value') 

标签:eye,image,eyeBlink,points,key,np,闭眼,眼部,Blender
来源: https://blog.csdn.net/flyfish1986/article/details/122672716