def test_getBiggestFace(): emptyPoints = dlib.dpoints(194) biggest = dlib.dpoints(40) biggest.append(dlib.dpoint(100, 100)) biggest.resize(194 + 1) faces = ([emptyPoints] * 5) + [biggest] assert _getBiggestFace(faces) == biggest
def test__toRelative(a, b, c): def _mkp(t: Tuple[float, float]) -> dlib.dpoint: """ make dlib.dpoint from Tuple""" return dlib.dpoint(t[0], t[1]) def _pSub(t: Tuple[float, float], c: Tuple[float, float]) -> dlib.dpoint: return dlib.dpoint(t[0] - c[0], t[1] - c[1]) assert _toRelative(dlib.dpoints([_mkp(a), _mkp(b)]), _mkp(c)) \ == dlib.dpoints([_pSub(a, c), _pSub(b, c)])
def _toRelative(target: dlib.dpoints, center: dlib.dpoint) -> dlib.dpoints: """ convert target into relative coordinates Only Center will be left as is. """ # convert all points to relative converted = list(map(lambda p: p - center, target)) # center position holds absolute coordinate converted[49] = center return dlib.dpoints(converted)
def _points2dpoints(ps: dlib.points) -> dlib.dpoints: """convert dlib.points object to dlib.dpoints object. All points() are should be converted to dpoints, as we use float values """ ret = dlib.dpoints() for p in ps: ret.append(dlib.dpoint(float(p.x), float(p.y))) return ret
def _getBiggestFace(faces: List[dlib.dpoints]) -> dlib.dpoints: """ Return biggest face in given list 'biggest face' is one that has biggest width """ def ln(p: dlib.dpoints) -> float: return abs((p[40] - p[0]).x) return reduce(lambda p, q: p if ln(p) > ln(q) else q, faces, dlib.dpoints(194))
def test_normalization(): # inList {{{ inList = [ 0, 1, 10, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 11, 96, 97, 98, 99, 114, 115, 116, 117, 118, 119, 12, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 13, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 14, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 15, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 16, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 17, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 18, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 19, 190, 191, 192, 193, 2, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 3, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 4, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 5, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 6, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 7, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 8, 80, 81, 82, 83, 84, 85, 100, 101, 102, 103, 9, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113 ] # }}} testPoints = dlib.dpoints(list(map(lambda n: dlib.dpoint(n, n), inList))) correct = dlib.dpoints( list(map(lambda n: dlib.dpoint(n, n), list(range(0, 194))))) assert _normalization(testPoints) == correct
def test_facemark(): # definition of correct_points {{{ correct_points = [ (-301, -48), (-299, -31), (-295, -14), (-291, 4), (-286, 21), (-280, 37), (-274, 54), (-267, 70), (-258, 85), (-249, 99), (-237, 113), (-224, 125), (-209, 135), (-194, 144), (-178, 151), (-162, 158), (-145, 165), (-129, 172), (-112, 178), (-95, 183), (-78, 188), (-60, 191), (-42, 192), (-24, 191), (-7, 187), (8, 180), (21, 169), (32, 155), (40, 140), (47, 124), (54, 107), (61, 90), (67, 73), (72, 56), (77, 39), (81, 22), (85, 5), (88, -13), (90, -30), (91, -48), (90, -66), (-39, -66), (-46, -55), (-52, -42), (-56, -28), (-53, -14), (-42, -6), (-28, -2), (-15, -1), (0, 0), (14, 1), (28, -1), (40, -7), (50, -17), (53, -31), (50, -45), (45, -58), (38, -71), (-91, 67), (-82, 62), (-71, 58), (-61, 55), (-51, 51), (-40, 47), (-30, 44), (-19, 42), (-9, 41), (3, 40), (14, 39), (25, 38), (36, 40), (43, 47), (44, 57), (40, 67), (35, 76), (26, 83), (16, 88), (5, 90), (-6, 91), (-18, 90), (-28, 88), (-39, 86), (-50, 83), (-60, 80), (-71, 77), (-81, 73), (41, 55), (34, 58), (25, 60), (16, 61), (8, 63), (-1, 64), (-10, 65), (-20, 65), (-29, 65), (-38, 65), (-47, 65), (-56, 65), (-65, 66), (-75, 66), (-84, 65), (-75, 65), (-66, 64), (-57, 64), (-48, 63), (-39, 61), (-30, 61), (-21, 61), (-12, 61), (-3, 60), (5, 59), (14, 57), (23, 55), (32, 54), (20, -136), (23, -142), (28, -147), (33, -151), (39, -154), (45, -157), (52, -158), (59, -158), (66, -157), (72, -153), (76, -148), (76, -141), (73, -136), (67, -133), (60, -131), (54, -130), (46, -130), (39, -131), (33, -133), (26, -134), (-87, -130), (-93, -136), (-101, -141), (-109, -144), (-118, -146), (-127, -145), (-136, -144), (-144, -141), (-152, -137), (-159, -133), (-167, -127), (-161, -123), (-153, -121), (-144, -120), (-135, -119), (-126, -120), (-117, -121), (-108, -123), (-99, -124), (-90, -124), (19, -171), (21, -180), (27, -188), (36, -193), (45, -196), (54, -199), (64, -201), (73, -201), (82, -199), (89, -194), (94, -186), (97, -175), (89, -174), (81, -177), (72, -178), (64, -178), (54, -177), (45, -174), (36, -171), (27, -168), (-49, -179), (-63, -189), (-79, -194), (-97, -196), (-115, -197), (-133, -197), (-151, -195), (-167, -189), (-183, -181), (-197, -171), (-209, -159), (-197, -156), (-180, -161), (-163, -166), (-146, -169), (-127, -171), (-109, -171), (-91, -170), (-74, -167), (-55, -166) ] # }}} correct = dlib.dpoints() for p in correct_points: correct.append(dlib.dpoint(p[0], p[1])) assert facemark(faceFrame) == correct
def test_Face_fromDPoints(): points = dlib.dpoints([dlib.dpoint(x, x) for x in range(194)]) # Those values are defined in LANDMARK_NUM correct = Face( AbsoluteCoord(49.0, 49.0), RelativeCoord(0.0, 0.0), RelativeCoord(40.0, 40.0), RelativeCoord(19.0, 19.0), Eye(Coord(129.0, 129.0), Coord(120.0, 120.0), Coord(124.0, 124.0), Coord(114.0, 114.0)), Eye(Coord(149.0, 149.0), Coord(140.0, 140.0), Coord(135.0, 135.0), Coord(145.0, 145.0)), Mouth(Coord(79.0, 79.0), Coord(65.0, 65.0), Coord(71.0, 71.0), Coord(58.0, 58.0)), Nose(Coord(49.0, 49.0), Coord(54.0, 54.0), Coord(44.0, 44.0)), EyeBrow(Coord(169.0, 169.0), Coord(159.0, 159.0), Coord(164.0, 164.0), Coord(154.0, 154.0)), EyeBrow(Coord(190.0, 190.0), Coord(179.0, 179.0), Coord(174.0, 174.0), Coord(185.0, 185.0))) assert Face.fromDPoints(points) == correct
def test_getBiggestFace_noface(): assert _getBiggestFace([]) == dlib.dpoints(194)
def _sortDpoints(face: dlib.dpoints) -> dlib.dpoints: """Sort facemark result. FOR INTERNAL USE Please refer to [this image]() [WIP] This code was written by @kekeho(Qiita), refer to: https://qiita.com/kekeho/items/0b2d4ed5192a4c90a0ac """ # nose nose = list(range(130, 147 + 1)) nose.remove(139) # right eyebrows right_eyebrow = list(range(62, 83 + 1)) right_eyebrow.remove(68) right_eyebrow.remove(79) # left eyebrows left_eyebrow = list(range(84, 105 + 1)) left_eyebrow.remove(90) left_eyebrow.remove(101) # right eye right_eye = list(range(18, 39 + 1)) right_eye.remove(24) right_eye.remove(35) # left_eye left_eye = list(range(40, 61 + 1)) left_eye.remove(46) left_eye.remove(57) # outside lips outside_lips = list(range(148, 178 + 1)) outside_lips.remove(150) outside_lips.remove(161) outside_lips.remove(172) # inside lips inside_lips = list(range(3, 17 + 1)) inside_lips.remove(13) add_list_lips = list(range(179, 193 + 1)) add_list_lips.remove(183) inside_lips += add_list_lips # chin chin = [0, 1, 106, 117, 128, 139, 150, 161, 172, 183, 2, 13, 24, 35, 46, 57, 68, 79, 90, 101] add_list = list(range(107, 129 + 1)) add_list.remove(117) add_list.remove(128) chin += add_list for nose_i, fm_i in enumerate(nose): nose[nose_i] = face[fm_i] for reb_i, fm_i in enumerate(right_eyebrow): right_eyebrow[reb_i] = face[fm_i] for leb_i, fm_i in enumerate(left_eyebrow): left_eyebrow[leb_i] = face[fm_i] for re_i, fm_i in enumerate(right_eye): right_eye[re_i] = face[fm_i] for le_i, fm_i in enumerate(left_eye): left_eye[le_i] = face[fm_i] for ol_i, fm_i in enumerate(outside_lips): outside_lips[ol_i] = face[fm_i] for il_i, fm_i in enumerate(inside_lips): inside_lips[il_i] = face[fm_i] for chin_i, fm_i in enumerate(chin): chin[chin_i] = face[fm_i] return dlib.dpoints(chin + nose + outside_lips + inside_lips + right_eye + left_eye + right_eyebrow + left_eyebrow)