face_detection.py 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. import cv2
  2. import dlib
  3. import numpy as np
  4. ## Face detection
  5. def face_detection(img,upsample_times=1):
  6. # Ask the detector to find the bounding boxes of each face. The 1 in the
  7. # second argument indicates that we should upsample the image 1 time. This
  8. # will make everything bigger and allow us to detect more faces.
  9. detector = dlib.get_frontal_face_detector()
  10. faces = detector(img, upsample_times)
  11. return faces
  12. PREDICTOR_PATH = 'models/shape_predictor_68_face_landmarks.dat'
  13. predictor = dlib.shape_predictor(PREDICTOR_PATH)
  14. ## Face and points detection
  15. def face_points_detection(img, bbox:dlib.rectangle):
  16. # Get the landmarks/parts for the face in box d.
  17. shape = predictor(img, bbox)
  18. # loop over the 68 facial landmarks and convert them
  19. # to a 2-tuple of (x, y)-coordinates
  20. coords = np.asarray(list([p.x, p.y] for p in shape.parts()), dtype=np.int)
  21. # return the array of (x, y)-coordinates
  22. return coords
  23. def select_face(im, r=10, choose=True):
  24. faces = face_detection(im)
  25. if len(faces) == 0:
  26. return None, None, None
  27. if len(faces) == 1 or not choose:
  28. idx = int(np.argmax([(face.right() - face.left()) * (face.bottom() - face.top()) for face in faces]))
  29. bbox = faces[idx]
  30. else:
  31. bbox = []
  32. def click_on_face(event, x, y, flags, params):
  33. if event != cv2.EVENT_LBUTTONDOWN:
  34. return
  35. for face in faces:
  36. if face.left() < x < face.right() and face.top() < y < face.bottom():
  37. bbox.append(face)
  38. break
  39. im_copy = im.copy()
  40. for face in faces:
  41. # draw the face bounding box
  42. cv2.rectangle(im_copy, (face.left(), face.top()), (face.right(), face.bottom()), (0, 0, 255), 1)
  43. cv2.imshow('Click the Face:', im_copy)
  44. cv2.setMouseCallback('Click the Face:', click_on_face)
  45. while len(bbox) == 0:
  46. cv2.waitKey(1)
  47. cv2.destroyAllWindows()
  48. bbox = bbox[0]
  49. points = np.asarray(face_points_detection(im, bbox))
  50. im_w, im_h = im.shape[:2]
  51. left, top = np.min(points, 0)
  52. right, bottom = np.max(points, 0)
  53. x, y = max(0, left - r), max(0, top - r)
  54. w, h = min(right + r, im_h) - x, min(bottom + r, im_w) - y
  55. return points - np.asarray([[x, y]]), (x, y, w, h), im[y:y + h, x:x + w]
  56. def get_landmarks(im):
  57. """
  58. Function that returns the face landmarks.
  59. """
  60. rects = face_detection(im, upsample_times=1)
  61. if len(rects) > 1:
  62. #print("Too Many Faces") #raise TooManyFaces
  63. return []
  64. if len(rects) == 0:
  65. #print("No Faces") #raise NoFaces
  66. return []
  67. return np.matrix([[p.x, p.y] for p in predictor(im, rects[0]).parts()])
  68. SCALE_FACTOR = 1
  69. def read_im_and_landmarks(fname):
  70. """
  71. Function that read the images and gets the face landmarks
  72. in the read images.
  73. """
  74. im = cv2.imread(fname, cv2.IMREAD_COLOR)
  75. im = cv2.resize(im, (im.shape[1] * SCALE_FACTOR,
  76. im.shape[0] * SCALE_FACTOR))
  77. s = get_landmarks(im)
  78. return im, s
  79. def mask_mouth(source_img):
  80. img, marks = read_im_and_landmarks(source_img)
  81. tmp_img=img.copy()
  82. tmp_blank_img=img.copy()
  83. tmp_blank_img=tmp_blank_img*0
  84. mask_list=marks[49:61]
  85. draw_img=cv2.drawContours(tmp_blank_img,[mask_list],-1,(255,255,255),-1)
  86. draw_img_re=cv2.bitwise_not(draw_img)
  87. tmp_img=tmp_img&draw_img_re
  88. return tmp_img