dlib's face landmark detection
http://dlib.net/face_landmark_detection.py.html
运行起来问题不大,最后每个面孔会返回68个点,这68个点分别是:
- 0, 17 => 下巴
- 17,22 => 左眉毛
- 22,27 => 右眉毛
- 27,31 => 鼻梁
- 31,36 => 鼻子
- 36,42 => 左眼,顺时针
- 42,48 => 右眼,顺时针
- 48,68 => 嘴巴,顺时针
code:
class FaceLandMark:
def __init__(self, points, h, w):
self.ps = points
def left_eye_center(self):
idxs = (37,38,40,41)
x = sum(map(lambda u: self.ps[u][0], idxs)) * 0.25
y = sum(map(lambda u: self.ps[u][1], idxs)) * 0.25
return (x, y)
def right_eye_center(self):
idxs = (43, 44, 46, 47)
x = sum(map(lambda u: self.ps[u][0], idxs)) * 0.25
y = sum(map(lambda u: self.ps[u][1], idxs)) * 0.25
return (x, y)
def xy_off(xy, off = 10):
(x, y) = xy
return (x + off, y + off)
def write_points(src, dst, ps):
im = Image.open(src)
draw = ImageDraw.Draw(im)
draw.line(ps, fill = 'white')
im.save(dst)
def write_circle(xys,src, dst, radius = 10):
im = Image.open(src)
draw = ImageDraw.Draw(im)
for xy in xys:
draw.ellipse([xy_off(xy, -radius), xy_off(xy, radius)], fill = 'white')
im.save(dst)
code:
def skin_retouch(im, v1 = 3, v2 = 1, p = 50):
dx = v1 * 5
fc = v1 * 12.5
raw = np.asarray(im).astype(np.float32)
temp1 = cv2.bilateralFilter(raw, dx, fc, fc)
temp2 = temp1 - raw + 128
temp3 = cv2.GaussianBlur(temp2, (2 * v1 - 1, 2 * v1 - 1,), 0, 0)
temp4 = raw + 2 * temp3 - 255
dst = (raw * (100 - p) + temp4 * p) * 0.01
return Image.fromarray(dst.astype(np.uint8))