oKen38461's picture
初回コミットに基づくファイルの追加
ac7cda5
import numpy as np
from dataclasses import dataclass
@dataclass
class EyeIdxMP:
LO = [33]
LI = [133]
LD = [7, 163, 144, 145, 153, 154, 155] # O -> I
LU = [246, 161, 160, 159, 158, 157, 173] # O -> I
RO = [263]
RI = [362]
RD = [249, 390, 373, 374, 380, 381, 382] # O -> I
RU = [466, 388, 387, 386, 385, 384, 398] # O -> I
LW = [33, 133] # oi
LH0 = [145, 159]
LH1 = [144, 160]
LH2 = [153, 158]
RW = [263, 362] # oi
RH0 = [374, 386]
RH1 = [373, 387]
RH2 = [380, 385]
LB = [468] # eye ball
RB = [473]
class EyeAttrUtilsByMP:
def __init__(self, lmks_mp):
self.IDX = EyeIdxMP()
self.lmks = lmks_mp # [n, 478, 3]
self.L_width = self._dist_idx(*self.IDX.LW) # [n]
self.R_width = self._dist_idx(*self.IDX.RW)
self.L_h0 = self._dist_idx(*self.IDX.LH0)
self.L_h1 = self._dist_idx(*self.IDX.LH1)
self.L_h2 = self._dist_idx(*self.IDX.LH2)
self.R_h0 = self._dist_idx(*self.IDX.RH0)
self.R_h1 = self._dist_idx(*self.IDX.RH1)
self.R_h2 = self._dist_idx(*self.IDX.RH2)
self.L_open = (self.L_h0 + self.L_h1 + self.L_h2) / (self.L_width + 1e-8) # [n]
self.R_open = (self.R_h0 + self.R_h1 + self.R_h2) / (self.R_width + 1e-8)
self.L_center = self._center_idx(*self.IDX.LW) # [n, 3/2]
self.R_center = self._center_idx(*self.IDX.RW)
self.L_ball = self.lmks[:, self.IDX.LB[0]] # [n, 3/2]
self.R_ball = self.lmks[:, self.IDX.RB[0]]
self.L_ball_direc = (self.L_ball - self.L_center) / (self.L_width[:, None] + 1e-8) # [n, 3/2]
self.R_ball_direc = (self.R_ball - self.R_center) / (self.R_width[:, None] + 1e-8)
self.L_eye_direc = self._direc_idx(*self.IDX.LW) # I->O
self.R_eye_direc = self._direc_idx(*self.IDX.RW)
self.L_ball_move_dist = self._dist(self.L_ball, self.L_center)
self.R_ball_move_dist = self._dist(self.R_ball, self.R_center)
self.L_ball_move_direc = self._direc(self.L_ball, self.L_center) - self.L_eye_direc
self.R_ball_move_direc = self._direc(self.R_ball, self.R_center) - self.R_eye_direc
self.L_ball_move = self.L_ball_move_direc * self.L_ball_move_dist[:, None]
self.R_ball_move = self.R_ball_move_direc * self.R_ball_move_dist[:, None]
def LR_open(self):
LR_open = np.stack([self.L_open, self.R_open], -1) # [n, 2]
return LR_open
def LR_ball_direc(self):
LR_ball_direc = np.stack([self.L_ball_direc, self.R_ball_direc], -1) # [n, 3, 2]
return LR_ball_direc
def LR_ball_move(self):
LR_ball_move = np.stack([self.L_ball_move, self.R_ball_move], -1)
return LR_ball_move
@staticmethod
def _dist(p1, p2):
# p1/p2: [n, 3/2]
return (((p1 - p2) ** 2).sum(-1)) ** 0.5 # [n]
@staticmethod
def _center(p1, p2):
return (p1 + p2) * 0.5 # [n, 3/2]
def _direc(self, p1, p2):
# p1 - p2, (2->1)
return (p1 - p2) / (self._dist(p1, p2)[:, None] + 1e-8)
def _dist_idx(self, idx1, idx2):
p1 = self.lmks[:, idx1]
p2 = self.lmks[:, idx2]
d = self._dist(p1, p2)
return d
def _center_idx(self, idx1, idx2):
p1 = self.lmks[:, idx1]
p2 = self.lmks[:, idx2]
c = self._center(p1, p2)
return c
def _direc_idx(self, idx1, idx2):
p1 = self.lmks[:, idx1]
p2 = self.lmks[:, idx2]
dir = self._direc(p1, p2)
return dir