PageRenderTime 38ms CodeModel.GetById 12ms RepoModel.GetById 0ms app.codeStats 0ms

/serialize_features.py

https://bitbucket.org/GaugeAnomaly/face-clustering
Python | 111 lines | 80 code | 17 blank | 14 comment | 12 complexity | e191442f037e5b4a5cfbf87cfe244396 MD5 | raw file
  1. import sys
  2. import os
  3. import glob
  4. import dlib
  5. import pickle
  6. import argparse
  7. import sqlite3
  8. import shutil
  9. from scipy.misc import imread
  10. from face_models import Face, Embedding, mod_sqlite3
  11. from time import perf_counter
  12. def main(args):
  13. sqlite3.register_converter("face_pos_t", Face.convert)
  14. sqlite3.register_converter("emb_t", Embedding.convert)
  15. # Load all the models we need: a detector to find the faces, a shape predictor
  16. # to find face landmarks so we can precisely localize the face, and finally the
  17. # face recognition model.
  18. detector = dlib.cnn_face_detection_model_v1(args.detector)
  19. sp = dlib.shape_predictor(args.predictor)
  20. facerec = dlib.face_recognition_model_v1(args.recognizer)
  21. descriptors = []
  22. positions = []
  23. files_with_faces = []
  24. chips = []
  25. face_count = 0
  26. if not args.append:
  27. if os.path.isdir(args.all_faces_output):
  28. shutil.rmtree(args.all_faces_output)
  29. if os.path.exists(args.data_base):
  30. os.remove(args.data_base)
  31. os.makedirs(args.all_faces_output)
  32. if args.append:
  33. con = mod_sqlite3.connect(args.data_base, detect_types=sqlite3.PARSE_DECLTYPES)
  34. r, = zip(*con.execute('SELECT Count(*) FROM face'))
  35. r = r[0]
  36. face_count = r
  37. con.close()
  38. globs = glob.glob(os.path.join(args.input, "*.jpg"))
  39. if args.num_of_faces:
  40. globs = globs[:args.num_of_faces]
  41. files = sorted(globs)
  42. # Start the timing of the procedure
  43. start = perf_counter()
  44. # Now find all the faces and compute 128D face descriptors for each face.
  45. for f in files:
  46. img = imread(f, mode='RGB')
  47. # Ask the detector to find the bounding boxes of each face. The 1 in the
  48. # second argument indicates that we should upsample the image 1 time. This
  49. # will make everything bigger and allow us to detect more faces.
  50. mmdets = detector(img, 1)
  51. dets = dlib.rectangles()
  52. dets.extend([d.rect for d in mmdets])
  53. # print("Number of faces detected: {}".format(len(dets)))
  54. if 10 * face_count / len(files) in range(10,101,10):
  55. print(100 * face_count / len(files), "%% completed")
  56. # print(10 * face_count / len(files), "%% completed")
  57. # Now process each face we found.
  58. for k, d in enumerate(dets):
  59. # Get the landmarks/parts for the face in box d.
  60. shape = sp(img, d)
  61. # Compute the 128D vector that describes the face in img identified by
  62. # shape.
  63. file_path = os.path.join(args.all_faces_output, 'face_' + str(face_count))
  64. dlib.save_face_chip(img, shape, file_path)
  65. try:
  66. face_descriptor = facerec.compute_face_descriptor(img, shape)
  67. descriptors.append(Embedding(list(face_descriptor)))
  68. positions.append(Face(mmdets[k].rect)) # images.append((img, shape))
  69. files_with_faces.append(f)
  70. chips.append(file_path+'.jpg')
  71. face_count += 1
  72. except:
  73. print("Failed with image: ", f)
  74. print("Image Shape: ", img.shape)
  75. print('Total time:', perf_counter() - start)
  76. print(('Processed {} files in total').format(len(files)))
  77. con = mod_sqlite3.connect(args.data_base, detect_types=sqlite3.PARSE_DECLTYPES)
  78. if not args.append:
  79. con.execute('create table face(origin, chip, position face_pos_t, embedding emb_t, cluster_id, cluster_id2)')
  80. con.executemany('insert into face(origin, chip, position, embedding) values(?,?,?,?)', zip(files_with_faces, chips, positions, descriptors))
  81. con.commit()
  82. con.close()
  83. if __name__ == '__main__':
  84. parser = argparse.ArgumentParser()
  85. parser.add_argument('-a', '--append', help='Whether to append new data or rewrite existing data', action="store_true")
  86. parser.add_argument('-n', '--num_of_faces', help='The amount of faces to process', type=int)
  87. parser.add_argument('-p', '--predictor', help='Path to the landmark predictor model', default='./dats/shape_predictor_5_face_landmarks.dat')
  88. parser.add_argument('-r', '--recognizer', help='Path to the face recognition model', default='./dats/dlib_face_recognition_resnet_model_v1.dat')
  89. parser.add_argument('-i', '--input', help='Input folder containing images', default='./fotis/meri')
  90. parser.add_argument('-b', '--data_base', help='The SQLite database file to store information', default='./face_db.db')
  91. parser.add_argument('-d', '--detector', help='Path to the face detector model', default='./dats/mmod_human_face_detector.dat')
  92. parser.add_argument('-o', '--all_faces_output', help='Path to new folder where to save all face chips', default='./found_faces')
  93. args = parser.parse_args()
  94. main(args)