generate_train_data.py 3.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. import os
  2. import cv2
  3. import dlib
  4. import time
  5. import argparse
  6. import numpy as np
  7. from imutils import video
  8. DOWNSAMPLE_RATIO = 4
  9. def reshape_for_polyline(array):
  10. return np.array(array, np.int32).reshape((-1, 1, 2))
  11. def main():
  12. os.makedirs('original', exist_ok=True)
  13. os.makedirs('landmarks', exist_ok=True)
  14. cap = cv2.VideoCapture(args.filename)
  15. fps = video.FPS().start()
  16. count = 0
  17. while cap.isOpened():
  18. ret, frame = cap.read()
  19. frame_resize = cv2.resize(frame, None, fx=1 / DOWNSAMPLE_RATIO, fy=1 / DOWNSAMPLE_RATIO)
  20. gray = cv2.cvtColor(frame_resize, cv2.COLOR_BGR2GRAY)
  21. faces = detector(gray, 1)
  22. black_image = np.zeros(frame.shape, np.uint8)
  23. t = time.time()
  24. # Perform if there is a face detected
  25. if len(faces) == 1:
  26. for face in faces:
  27. detected_landmarks = predictor(gray, face).parts()
  28. landmarks = [[p.x * DOWNSAMPLE_RATIO, p.y * DOWNSAMPLE_RATIO] for p in detected_landmarks]
  29. jaw = reshape_for_polyline(landmarks[0:17])
  30. left_eyebrow = reshape_for_polyline(landmarks[22:27])
  31. right_eyebrow = reshape_for_polyline(landmarks[17:22])
  32. nose_bridge = reshape_for_polyline(landmarks[27:31])
  33. lower_nose = reshape_for_polyline(landmarks[30:35])
  34. left_eye = reshape_for_polyline(landmarks[42:48])
  35. right_eye = reshape_for_polyline(landmarks[36:42])
  36. outer_lip = reshape_for_polyline(landmarks[48:60])
  37. inner_lip = reshape_for_polyline(landmarks[60:68])
  38. color = (255, 255, 255)
  39. thickness = 3
  40. cv2.polylines(black_image, [jaw], False, color, thickness)
  41. cv2.polylines(black_image, [left_eyebrow], False, color, thickness)
  42. cv2.polylines(black_image, [right_eyebrow], False, color, thickness)
  43. cv2.polylines(black_image, [nose_bridge], False, color, thickness)
  44. cv2.polylines(black_image, [lower_nose], True, color, thickness)
  45. cv2.polylines(black_image, [left_eye], True, color, thickness)
  46. cv2.polylines(black_image, [right_eye], True, color, thickness)
  47. cv2.polylines(black_image, [outer_lip], True, color, thickness)
  48. cv2.polylines(black_image, [inner_lip], True, color, thickness)
  49. # Display the resulting frame
  50. count += 1
  51. print(count)
  52. cv2.imwrite("original/{}.png".format(count), frame)
  53. cv2.imwrite("landmarks/{}.png".format(count), black_image)
  54. fps.update()
  55. print('[INFO] elapsed time: {:.2f}'.format(time.time() - t))
  56. if count == args.number: # only take 400 photos
  57. break
  58. elif cv2.waitKey(1) & 0xFF == ord('q'):
  59. break
  60. else:
  61. print("No face detected")
  62. fps.stop()
  63. print('[INFO] elapsed time (total): {:.2f}'.format(fps.elapsed()))
  64. print('[INFO] approx. FPS: {:.2f}'.format(fps.fps()))
  65. cap.release()
  66. cv2.destroyAllWindows()
  67. if __name__ == '__main__':
  68. parser = argparse.ArgumentParser()
  69. parser.add_argument('--file', dest='filename', type=str, help='Name of the video file.')
  70. parser.add_argument('--num', dest='number', type=int, help='Number of train data to be created.')
  71. parser.add_argument('--landmark-model', dest='face_landmark_shape_file', type=str, help='Face landmark model file.')
  72. args = parser.parse_args()
  73. # Create the face predictor and landmark predictor
  74. detector = dlib.get_frontal_face_detector()
  75. predictor = dlib.shape_predictor(args.face_landmark_shape_file)
  76. main()