Commit 81050153 authored by 任婷婷's avatar 任婷婷

.

parent 4b647420
# coding: utf-8
# author: gushitong
from __future__ import division
import math
import numpy as np
from .base_part import BasePart
class Chin(BasePart):
"""
下巴模型
"""
CATEGORIES = ['sharp', 'round', 'square']
def __init__(self,roll_rand,**kwargs):
super(Chin,self).__init__(roll_rand,**kwargs)
self.contour_left1=self.p_0
self.contour_left6=self.p_5
self.contour_left7=self.p_6
self.contour_left8=self.p_7
self.contour_left9=self.p_8
self.contour_chin=self.p_9
self.contour_right6=self.p_13
self.contour_right7=self.p_12
self.contour_right8=self.p_11
self.contour_right9=self.p_10
self.contour_right1=self.p_16
def get_vector(self):
#return self.chin_slopes()
#result=self.chin_slopes()
result=[]
result=self.chin_baseline_angle()
angle=self.chin_bottom_angle()
result.append(angle)
ratio=self.face_chin_width_ratio()
result.append(ratio)
return result
def attrs(self):
return (
'p_0',
'p_5',
'p_4',
'p_6',
'p_7',
'p_8',
'p_9',
'p_13',
'p_12',
'p_11',
'p_10',
'p_16'
)
@property
def base_slope(self):
"""
base slope: 基准斜率
:return:
"""
return (self.slope_abs(self.contour_left1, self.contour_chin) +
self.slope_abs(self.contour_right1, self.contour_chin)) / 2
def slope_abs(self, point1, point2):
"""
absolute value of slope.
:param point1:
:param point2:
:return:
"""
return math.atan(abs((point1['y'] - point2['y']) / (point1['x'] - point2['x'])))
def slopes(self):
"""将相关的点拟合成抛物线,计算曲率"""
slopes = []
for i in range(6, 10):
s1 = self.slope_abs(getattr(self, 'contour_left' + str(i)), self.contour_chin)
s2 = self.slope_abs(getattr(self, 'contour_right' + str(i)), self.contour_chin)
slopes.append((s1 + s2) / (2 * self.base_slope))
return slopes
def chin_slopes(self):
slopes_l=[]
slopes_r=[]
slopes=[]
for i in range(6,9):
s1 = self.slope_abs(getattr(self, 'contour_left' + str(i)), self.contour_chin)
s2 = self.slope_abs(getattr(self, 'contour_right' + str(i)), self.contour_chin)
#print('s1 s2:',s1,s2)
slopes_l.append(s1)
slopes_r.append(s2)
slopes=slopes_l+slopes_r
#print('slopes:',slopes)
return slopes
def chin_baseline_angle(self):
#baseline
base=self.slope_abs(self.p_7,self.p_9)
left=self.slope_abs(self.p_6,self.p_8)
right=self.slope_abs(self.p_10,self.p_8)
angle_left=abs((left-base)/(1+left*base))
angle_right=abs((right-base)/(1+right*base))
return [angle_left,angle_right]
def chin_bottom_angle(self):
left=self.slope_abs(self.p_7,self.p_8)
right=self.slope_abs(self.p_9,self.p_8)
angle=abs((left-right)/(1+left*right))
return angle
def face_chin_width_ratio(self):
face_w=np.sqrt((self.p_0['x']-self.p_16['x'])**2+(self.p_0['y']-self.p_16['y'])**2)
chin_w=np.sqrt((self.p_4['x']-self.p_12['x'])**2+(self.p_4['y']-self.p_12['y'])**2)
#face_w=distance(self.p_0,self.p_16)
#chin_w=distance(self.p_4,self.p_12)
ratio=chin_w/face_w
#ratio=(face_w/chin_w-1)
return ratio
# coding:utf-8
# author:Thierry
from __future__ import division
import math
from .base_part import BasePart
import numpy as np
class Contour(BasePart):
"""
面部轮廓模型
"""
# 圆脸,鹅蛋,尖脸,方脸
CATEGORIES = ['round', 'oval', 'heart', 'square']
def __init__(self,roll_rand,**kwargs):
super(Contour,self).__init__(roll_rand,**kwargs)
self.contour_left1=self.p_0
self.contour_left2=self.p_0
self.contour_left3=self.p_1
self.contour_left4=self.p_2
self.contour_left5=self.p_3
self.contour_left6=self.p_4
self.contour_left7=self.p_5
self.contour_left8=self.p_6
self.contour_left9=self.p_7
self.contour_chin=self.p_8
self.contour_right1=self.p_16
self.contour_right2=self.p_16
self.contour_right3=self.p_15
self.contour_right4=self.p_14
self.contour_right5=self.p_13
self.contour_right6=self.p_12
self.contour_right7=self.p_11
self.contour_right8=self.p_10
self.contour_right9=self.p_9
def attrs(self):
return (
'p_0',
'p_1',
'p_2',
'p_3',
'p_4',
'p_5',
'p_6',
'p_7',
'p_8',
'p_9',
'p_10',
'p_11',
'p_12',
'p_13',
'p_14',
'p_15',
'p_16',
'p_19',
'p_24'
)
def get_vector(self):
result=self.slopes()
result+=self.face_chin_angle_plus()
result.append(self.width_height_ratio())
result.append(self.chin_bottom_angle())
print('re',result)
return result
@property
def base_slope(self):
"""
base slope: 基准斜率
:return:
"""
return (self.slope_abs(self.contour_left1, self.contour_chin) +
self.slope_abs(self.contour_right1, self.contour_chin)) / 2
def slope_abs(self, point1, point2):
"""
absolute value of slope.
:param point1:
:param point2:
:return:
"""
return math.atan(abs((point1['y'] - point2['y']) / (point1['x'] - point2['x'])))
def slopes(self):
"""将相关的点拟合成抛物线,计算曲率"""
slopes = []
for i in range(3, 10):
s1 = self.slope_abs(getattr(self, 'contour_left' + str(i)), self.contour_chin)
s2 = self.slope_abs(getattr(self, 'contour_right' + str(i)), self.contour_chin)
slopes.append((s1 + s2) / (2 * self.base_slope))
return slopes
def distance(self,pt1,pts):
dist=np.sqrt(np.square(pt1['x']-pt2['x'])+np.square(pt1['y']-pt2['y']))
#print('dist:',dist)
def face_chin_width_ratio(self):
face_w=np.sqrt((self.p_0['x']-self.p_16['x'])**2+(self.p_0['y']-self.p_16['y'])**2)
chin_w=np.sqrt((self.p_4['x']-self.p_12['x'])**2+(self.p_4['y']-self.p_12['y'])**2)
#face_w=distance(self.p_0,self.p_16)
#chin_w=distance(self.p_4,self.p_12)
ratio=chin_w/face_w
#ratio=(face_w/chin_w-1)
#print('chin width ratio:',ratio)
return ratio
def width_height_ratio(self):
center={}
center['x']=0.5*(self.p_19['x']+self.p_24['x'])
center['y']=0.5*(self.p_19['y']+self.p_24['y'])
face_w=np.sqrt((self.p_0['x']-self.p_16['x'])**2+(self.p_0['y']-self.p_16['y'])**2)
face_h=np.sqrt((self.p_8['x']-center['x'])**2+(self.p_8['y']-center['y'])**2)
return face_w/face_h
def chin_slopes(self):
#print('chin slopes')
s1 = self.slope_abs(self.contour_left4, self.contour_left7)
s2 = self.slope_abs(self.contour_right4, self.contour_right7)
s3 = self.slope_abs(self.contour_left8, self.contour_chin)
s4 = self.slope_abs(self.contour_right8, self.contour_chin)
#print('s1 s2:',s1,s2)
slopes=[s1,s2,s3,s4]
#print('slopes:',slopes)
return slopes
def face_chin_angle(self):
BA = [
self.p_4['x'] - self.p_0['x'],
self.p_4['y'] - self.p_0['y']
]
BC = [
self.p_4['x'] - self.p_7['x'],
self.p_4['y'] - self.p_7['y']
]
cosin_0 = (
(BA[0] * BC[0] + BA[1] * BC[1]) /
(math.sqrt(BA[0] ** 2 + BA[1] ** 2) * math.sqrt(BC[0] ** 2) + BC[1] ** 2)
)
BA_R = [
self.p_16['x'] - self.p_12['x'],
self.p_16['y'] - self.p_12['y']
]
BC_R = [
self.p_16['x'] - self.p_9['x'],
self.p_16['y'] - self.p_9['y']
]
cosin_1 = (
(BA_R[0] * BC_R[0] + BA_R[1] * BC_R[1]) /
(math.sqrt(BA_R[0] ** 2 + BA_R[1] ** 2) * math.sqrt(BC_R[0] ** 2) + BC_R[1] ** 2)
)
return [cosin_0,cosin_1]
def face_chin_angle_plus(self):
k1=self.slope_abs(self.p_1,self.p_4)
k2=self.slope_abs(self.p_7,self.p_4)
angle1=abs((k2-k1)/(1+k1*k2))
k3=self.slope_abs(self.p_15,self.p_12)
k4=self.slope_abs(self.p_9,self.p_12)
angle2=abs((k4-k3)/(1+k3*k4))
k5=self.slope_abs(self.p_6,self.p_7)
k6=self.slope_abs(self.p_9,self.p_10)
angle3=abs((k5-k6)/(1+k5*k6))
return [angle1,angle2,angle3]
def chin_bottom_angle(self):
left=self.slope_abs(self.p_7,self.p_8)
right=self.slope_abs(self.p_9,self.p_8)
angle=abs((left-right)/(1+left*right))
return angle
# coding:utf-8
# author:Thierry
import math
from .base_part import BasePart
class Eye(BasePart):
"""
眼部模型
"""
CATEGORIES = ['danfeng', 'xingren', 'xiachui', 'xichang']
def __init__(self,roll_rand,**kwargs):
super(Eye,self).__init__(roll_rand,**kwargs)
self.left_eye_bottom=self.p_47
self.left_eye_right_corner=self.p_45
self.left_eye_left_corner=self.p_42
self.left_eye_top=self.p_43
def attrs(self):
return (
'p_42',
'p_43',
'p_44',
'p_45',
'p_46',
'p_47',
)
def get_vector(self):
#print('vector result',self.inner_upper_rand())
return [
self.inner_upper_rand(),
self.top_inner_outer_rand(),
self.bottom_inner_outer_rand(),
self.inner_top_bottom_rand(),
self.outer_top_bottom_rand()
]
def inner_upper_rand(self):
"""
内外眼角上挑的弧度(值越大,越趋近丹凤眼)
"""
adjacent = self.left_eye_right_corner['x'] - self.left_eye_left_corner['x']
opposite = self.left_eye_right_corner['y'] - self.left_eye_left_corner['y']
#print('a',adjacent,'opp',opposite)
return math.atan2(opposite, adjacent) - self.roll_rand
def top_inner_outer_rand(self):
"""
眼顶部中心和内外眼角的夹角
"""
# 顶部内夹角
inner_opposite = self.left_eye_right_corner['x'] - self.left_eye_top['x']
inner_adjacent = self.left_eye_right_corner['y'] - self.left_eye_top['y']
inner_rand = math.atan2(inner_opposite, inner_adjacent)
# 顶部外夹角
outer_opposite = self.left_eye_top['x'] - self.left_eye_left_corner['x']
outer_adjacent = self.left_eye_left_corner['y'] - self.left_eye_top['y']
outer_rand = math.atan2(outer_opposite, outer_adjacent)
return inner_rand + outer_rand
def bottom_inner_outer_rand(self):
"""
眼底部的和内外眼角的夹角
"""
# 底部内夹角
inner_opposite = self.left_eye_right_corner['x'] - self.left_eye_bottom['x']
inner_adjacent = self.left_eye_bottom['y'] - self.left_eye_right_corner['y']
inner_rand = math.atan2(inner_opposite, inner_adjacent)
# 底部外夹角
outer_opposite = self.left_eye_bottom['x'] - self.left_eye_left_corner['x']
outer_adjacent = self.left_eye_bottom['y'] - self.left_eye_left_corner['y']
outer_rand = math.atan2(outer_opposite, outer_adjacent)
return inner_rand + outer_rand
def inner_top_bottom_rand(self):
"""
内眼角和顶部底部的夹角
"""
# 内眼角与顶部夹角
top_opposite = self.left_eye_right_corner['y'] - self.left_eye_top['y']
top_adjacent = self.left_eye_right_corner['x'] - self.left_eye_top['x']
top_rand = math.atan2(top_opposite, top_adjacent)
# 内眼角与底部夹角
bottom_opposite = self.left_eye_bottom['y'] - self.left_eye_right_corner['y']
bottom_adjacent = self.left_eye_right_corner['x'] - self.left_eye_bottom['x']
bottom_rand = math.atan2(bottom_opposite, bottom_adjacent)
return top_rand + bottom_rand
def outer_top_bottom_rand(self):
"""
外眼角和顶部底部的夹角
"""
# 外眼角与顶部夹角
top_opposite = self.left_eye_left_corner['y'] - self.left_eye_top['y']
top_adjacent = self.left_eye_top['x'] - self.left_eye_left_corner['x']
top_rand = math.atan2(top_opposite, top_adjacent)
# 外眼角与底部夹角
bottom_opposite = self.left_eye_bottom['y'] - self.left_eye_left_corner['y']
bottom_adjacent = self.left_eye_bottom['x'] - self.left_eye_left_corner['x']
bottom_rand = math.atan2(bottom_opposite, bottom_adjacent)
return top_rand + bottom_rand
def aspect_ratio(self):
"""
宽高比(值越大,越圆)
"""
return float(self._width()) / float(self._height())
def _height(self):
return self.left_eye_bottom['y'] - self.left_eye_top['y']
def _width(self):
return self.left_eye_right_corner['x'] - self.left_eye_left_corner['x']
# coding: utf-8
# from __future__ import division
import math
from .base_part import BasePart
class EyeBrow(BasePart):
"""
眉毛模型
"""
CATEGORIES = ['pingzhi', 'xiachui', 'liuye', 'gongxing', 'shangtiao']
def __init__(self,roll_rand,**kwargs):
super(EyeBrow,self).__init__(roll_rand,**kwargs)
self.left_eyebrow_left_corner=self.p_17
self.left_eyebrow_upper_left_quarter=self.p_18
self.left_eyebrow_lower_left_quarter=self.p_18
self.left_eyebrow_lower_middle=self.p_19
self.left_eyebrow_right_corner=self.p_21
self.left_eyebrow_lower_right_quarter=self.p_20
self.left_eyebrow_upper_right_quarter=self.p_20
self.left_eyebrow_upper_middle=self.p_19
self.right_eyebrow_left_corner=self.p_22
self.right_eyebrow_right_corner=self.p_26
self.right_eyebrow_upper_middle=self.p_24
self.right_eyebrow_upper_right_quarter=self.p_25
self.left_0=self.p_17
self.left_1=self.p_18
self.left_2=self.p_19
self.left_3=self.p_20
self.left_4=self.p_21
self.right_0=self.p_22
self.right_1=self.p_23
self.right_2=self.p_24
self.right_3=self.p_25
self.right_4=self.p_26
def attrs(self):
return (
'p_17',
'p_20',
'p_19',
'p_21',
'p_22',
'p_25',
'p_26',
'p_18',
'p_42',
'p_45',
'p_23',
'p_24'
)
def _corner_upper_middle_angle(self):
"""
left upper middle: B as origin
left corner: A
right corner: C
return: cosin <ABC>
"""
BA = [
self.left_eyebrow_left_corner['x'] - self.left_eyebrow_upper_middle['x'],
self.left_eyebrow_left_corner['y'] - self.left_eyebrow_upper_middle['y']
]
BC = [
self.left_eyebrow_right_corner['x'] - self.left_eyebrow_upper_middle['x'],
self.left_eyebrow_right_corner['y'] - self.left_eyebrow_upper_middle['y']
]
cosin = (
(BA[0] * BC[0] + BA[1] * BC[1]) /
(math.sqrt(BA[0] ** 2 + BA[1] ** 2) * math.sqrt(BC[0] ** 2) + BC[1] ** 2)
)
return cosin
def _q_length_ratio(self):
"""眉峰 占据 整个眉长的比例."""
al = self.left_eyebrow_right_corner['x'] - self.left_eyebrow_left_corner['x']
bl = self.left_eyebrow_right_corner['x'] - self.left_eyebrow_upper_left_quarter['x']
ar = self.right_eyebrow_right_corner['x'] - self.right_eyebrow_left_corner['x']
br = self.right_eyebrow_left_corner['x'] - self.right_eyebrow_upper_right_quarter['x']
a = abs(al) + abs(ar)
b = abs(bl) + abs(br)
return b / a
def _q_length_ratio_plus(self):
"""眉峰 占据 整个眉长的比例."""
left_high={}
right_high={}
if self.p_18['y']>self.p_19['y']:
left_high['x']=self.p_18['x']
else:
left_high['x']=self.p_19['x']
if self.p_24['y']>self.p_25['y']:
right_high['x']=self.p_24['x']
else:
right_high['x']=self.p_25['x']
al = self.p_21['x'] - left_high['x']
bl = left_high['x'] - self.p_17['x']
ratio_left= al/bl
ar = right_high['x'] - self.p_22['x']
br = self.p_26['x'] - right_high['x']
ratio_right=ar/br
print('length ratio:',ratio_left,ratio_right)
return ratio_left
def _corner_upper_q_slope(self):
y = self.right_eyebrow_left_corner['y'] - self.right_eyebrow_upper_right_quarter['y']
x = self.right_eyebrow_upper_right_quarter['x'] - self.right_eyebrow_left_corner['x']
if x==0:
return 100
print('y/x:',y/x)
return y / x
def _corner_upper_q_slope_plus(self):
yr = self.p_26['y'] - self.p_25['y']
xr = self.p_26['x'] - self.p_25['x']
if xr!=0:
ratio_r=yr/xr
else:
ratio_r=100
yl = self.p_18['y'] - self.p_17['y']
xl = self.p_18['x'] - self.p_17['x']
if xl!=0:
ratio_l=yl/xl
else:
ratio_l=100
print('meiwei shangqiao ratio:',ratio_r,ratio_l)
return ratio_l,ratio_r
def head_middle_end_angle(self):
s1=slope_abs(self.left_2,self.left_0)
s2=slope_abs(self.left_4,self.left_2)
s3=slope_abs(self.right_2,self.right_0)
s4=slope_abs(self.right_4,self.right_2)
print('head middle end ratio:',s1,s2,s3,s4)
return s1,s2,s3,s4
def slope_abs(self, point1, point2):
"""
absolute value of slope.
:param point1:
:param point2:
:return:
"""
return math.atan(abs((point1['y'] - point2['y']) / (point1['x'] - point2['x'])))
def eyebrow_slopes(self):
slopes=[]
slopes_l=[]
slopes_r=[]
for i in range(0,5):
if i!= 2:
s1 = self.slope_abs(getattr(self, 'left_' + str(i)), self.left_2)
s2 = self.slope_abs(getattr(self, 'right_' + str(i)), self.right_2)
slopes_l.append(s1)
slopes_r.append(s2)
slopes=slopes_l+slopes_r
return slopes
def eyebrow_raw_points(self):
return[self.left_0,self.left_1,self.left_2,self.left_3,self.left_4,self.right_0,self.right_1,self.right_2,self.right_3,self.right_4]
def get_vector(self):
#method 1
result= self.eyebrow_slopes()
print('result1:',result)
# angle= self._corner_upper_middle_angle()
#method 2
#result=self.eyebrow_raw_points()
angle= self._corner_upper_middle_angle()
#l,r=self._corner_upper_q_slope_plus()
#result=[angle,l,r]
#s1,s2,s3,s4=self.head_middle_end_angle()
#result=[angle,s1,s2,s3,s4]
result.append(angle)
print('result1:',result)
#print('result2:',result)
return result
# coding: utf-8
# author: gushitong
from __future__ import division
import math
from .base_part import BasePart
def dist(point1, point2):
return math.sqrt((point1['y'] - point2['y']) ** 2 + (point1['x'] - point2['x']) ** 2)
class Lip(BasePart):
CATEGORIES = ['thin', 'standard', 'thick']
def __init__(self,roll_rand,**kwargs):
super(Lip,self).__init__(roll_rand,**kwargs)
self.mouth_lower_lip_top=self.p_66
self.mouth_lower_lip_bottom=self.p_57
self.mouth_left_corner=self.p_48
self.mouth_upper_lip_top=self.p_51
self.mouth_upper_lip_bottom=self.p_62
self.mouth_right_corner=self.p_54
def get_vector(self):
result=self.angle()
top,bottom=self.thickness()
result.append(top)
result.append(bottom)
return result
def attrs(self):
return (
'p_66',
'p_57',
'p_48',
'p_51',
'p_62',
'p_54'
)
def counteract(self):
a = getattr(self, 'mouth_lower_lip_bottom')
b = getattr(self, 'mouth_lower_lip_top')
c = getattr(self, 'mouth_left_corner')
d = getattr(self, 'mouth_right_corner')
e = getattr(self, 'mouth_upper_lip_bottom')
f = getattr(self, 'mouth_upper_lip_top')
a['y'] += (c['y'] - b['y'])
b['y'] = c['y']
e['y'] = d['y']
f['y'] -= (e['y'] - d['y'])
return a, b, c, d, e, f
def thickness(self):
width=self.p_54['x']-self.p_48['x']
top=(self.p_62['y']-self.p_51['y'])/width
bottom=(self.p_57['y']-self.p_66['y'])/width
return top,bottom
def angle(self):
"""
利用余弦定理计算四个唇角
:return:
"""
a, b, c, d, e, f = self.counteract()
l1, l2, l3, l4, l5 = dist(a, b), dist(a, c), dist(a, d), dist(b, c), dist(b, d)
l6, l7, l8, l9, l10 = dist(e, f), dist(e, c), dist(e, d), dist(f, c), dist(f, d)
bottom_left_lip_angle = math.degrees(math.acos((l2**2 + l4**2 - l1**2)/(2*l2*l4)))
bottom_right_lip_angle = math.degrees(math.acos((l3**2 + l5**2 - l1**2)/(2*l3*l5)))
top_left_lip_angle = math.degrees(math.acos((l7**2 + l9**2 - l6**2)/(2*l7*l9)))
top_right_lip_angle = math.degrees(math.acos((l8**2 + l10**2 - l6**2)/(2*l8*l10)))
return [
(bottom_left_lip_angle + bottom_right_lip_angle) / 2,
(top_left_lip_angle + top_right_lip_angle) / 2
]
# coding:utf-8
# author:Thierry
from .base_part import BasePart
class Nose(BasePart):
"""
鼻部模型
"""
CATEGORIES = ['normal', 'wide']
def __init__(self,roll_rand,**kwargs):
super(Nose,self).__init__(roll_rand,**kwargs)
self.left_eye_right_corner=self.p_39
self.nose_left=self.p_31
self.right_eye_left_corner=self.p_42
self.nose_right=self.p_35
def attrs(self):
return (
'p_31',
'p_35',
'p_39',
'p_42',
)
def get_vector(self):
return [self._wing_root_ratio()]
def _wing_root_ratio(self):
return self._wing_width() / self._root_width()
def _root_width(self):
"""
内眼角的宽度
"""
return self.left_eye_right_corner['x'] - self.right_eye_left_corner['x']
def _wing_width(self):
"""
鼻翼的宽度
"""
return self.nose_right['x'] - self.nose_left['x']
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment