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))