コード例 #1
0
def export_to_json(args):
    preds_per_person = utils.load_faces_from_csv(args.db, args.imgs_root)
    if len(preds_per_person) == 0:
        print('no faces loaded')
        exit()

    json_dir = os.path.join(args.db, 'exif_json')
    if not os.path.isdir(json_dir):
        utils.mkdir_p(json_dir)

    for p in preds_per_person:
        if p == 'deleted' or p == 'unknown':
            continue

        print('exporting {}'.format(p))

        for f in preds_per_person[p]:
            # check mask
            if args.mask_folder != None:
                if os.path.dirname(f[1]) != args.mask_folder:
                    continue
            if not os.path.isfile(f[1]):
                continue
            json_path = json_dir + f[1][:-3] + 'json'
            if os.path.isfile(json_path):
                continue
            if not os.path.isdir(os.path.dirname(json_path)):
                utils.mkdir_p(os.path.dirname(json_path))

            arg_str = 'exiftool -json "' + f[1] + '" > "' + json_path + '"'
            os.system(arg_str)
コード例 #2
0
def export_new_format(args):
    # faces = utils.load_img_labels(args.imgs_root)
    # d1, d2, d3 = utils.get_faces_dicts(faces)
    # utils.store_to_img_labels(faces, d1)

    preds_per_person = utils.load_faces_from_csv(args.db, args.imgs_root)
    if len(preds_per_person) == 0:
        print('no faces loaded')
        exit()
    files_faces = utils.get_faces_in_files(preds_per_person,
                                           ignore_unknown=False)

    faces = []
    names = []
    for f in files_faces:
        (name, idx) = files_faces[f][0]
        img_timestamp = preds_per_person[name][idx][4]
        img_labels = utils.IMG_LABELS(img_timestamp)
        for (name, idx) in files_faces[f]:

            if not name in names:
                names.append(name)
                name_id = len(names) - 1
            else:
                name_id = names.index(name)

            ppp = preds_per_person[name][idx]
            loc = ppp[0][1]
            desc = ppp[2]
            timestamp = ppp[4]
            confirmed = ppp[3]
            face = utils.FACE(loc, desc, name_id, timestamp, confirmed)
            faces.append(face)
            img_labels.faces.append(face)

        # write img_label
        # bin_path = os.path.join(os.path.dirname(f), os.path.splitext(os.path.basename(f))[0] + '.pkl')
        bin_path = f + '.pkl'
        with open(bin_path, 'wb') as fid:
            pickle.dump(img_labels, fid)

        # with open(bin_path, 'rb') as fid:
        #   img_labels_test = pickle.load(fid)
        #   for face in img_labels_test.faces:
        #     face.path = f

    # write name_id mapping
    names_path = os.path.join(args.outdir, 'name_mapping.csv')
    with open(names_path, "w") as csvfile:
        filewriter = csv.writer(csvfile, delimiter=';')
        for i, n in enumerate(names):
            filewriter.writerow([str(i), n])
コード例 #3
0
def export_album(args):
  preds_per_person = utils.load_faces_from_csv(args.db)
  if len(preds_per_person) == 0:
    print('no faces loaded')
    exit()

  album_dir = os.path.join(args.outdir, 'faces')
  utils.mkdir_p(album_dir)

  for p in preds_per_person:
    print('exporting {}'.format(p))
    face_dir = os.path.join(album_dir, p)
    utils.mkdir_p(face_dir)
    for f in preds_per_person[p]:
      symlinkname = os.path.join(face_dir, os.path.basename(f[1]))
      if not os.path.islink(symlinkname):
        os.symlink(f[1], symlinkname)

  return album_dir
コード例 #4
0
def export_to_json(args):
  preds_per_person = utils.load_faces_from_csv(args.db)
  if len(preds_per_person) == 0:
    print('no faces loaded')
    exit()

  json_dir = os.path.join(args.db, 'exif_json')
  if not os.path.isdir(json_dir):
    utils.mkdir_p(json_dir)

  for p in preds_per_person:
    print('exporting {}'.format(p))
    for f in preds_per_person[p]:
      if not os.path.isfile(f[1]):
        continue
      json_path = os.path.join(json_dir, f[1].replace('/', '_')[1:-3] + 'json')
      json_path = json_path.replace(' ', '_')
      if os.path.isfile(json_path):
        continue
      else:
        arg_str = 'exiftool -json "' + f[1] + '" > ' + json_path
        os.system(arg_str)
コード例 #5
0
def export_thumbnails(args):
    preds_per_person = utils.load_faces_from_csv(args.db, args.imgs_root)
    files_faces = utils.get_faces_in_files(preds_per_person)
    if len(preds_per_person) == 0:
        print('no faces loaded')
        exit()

    # face_prefix = 'f '
    size = (1024, 1024)

    for f in files_faces:
        rel_path = os.path.relpath(f, args.imgs_root)
        out_path = os.path.join(args.outdir, rel_path)
        print('Writing {}'.format(f))
        if not os.path.isdir(os.path.dirname(out_path)):
            os.makedirs(os.path.dirname(out_path))

        keywords = []
        for i in files_faces[f]:
            cls, idx = i
            if cls != 'unknown' and cls != 'detected' and cls != 'deleted':
                keywords.append(cls)
        if len(keywords) == 0:
            print('only ignored keywords found -> skipping')
            continue

        if os.path.isfile(out_path):
            print('skipping')
            continue

        im = cv2.imread(f)
        im = utils.resizeCV(im, size[1])
        if f.lower().endswith(('.jpg', '.jpeg')):
            cv2.imwrite(out_path, im, [cv2.IMWRITE_JPEG_QUALITY, 80])
        elif f.lower().endswith(('.png')):
            cv2.imwrite(out_path, im, [cv2.IMWRITE_PNG_COMPRESSION, 2])
        else:
            print('unsupported file format of {}'.format(f))
            exit()
コード例 #6
0
def show_class(args, svm_clf):

    preds_per_person = utils.load_faces_from_csv(args.db)

    if args.face == 'all':
        classes = preds_per_person
    else:
        classes = [args.face]

    for cls in classes:
        face_locations, face_encodings = utils.initialize_face_data(
            preds_per_person, cls)

        print('{} members of {}'.format(len(face_locations), cls))
        if len(face_locations) == 0:
            return

        key = 0
        ix = 0
        save = []
        while key != 27 and len(face_locations) > 0:

            while len(save) > 100:
                save.pop(0)

            if ix >= len(face_locations):
                ix = 0

            elif ix < 0:
                ix = len(face_locations) - 1

            names, probs = predict_face_svm(face_encodings[ix], svm_clf)
            name = names[0]

            #nr_conf, nr_ignored, nr_not_ignored = utils.count_preds_status(preds_per_person[cls])
            #str_count = 'total: ' + str(len(preds_per_person[cls])) + ', confirmed: ' + str(nr_conf) + ', ignored: ' + str(nr_ignored)
            str_count = str(ix + 1) + ' / ' + str(len(preds_per_person[cls]))

            predictions = []
            predictions.append((cls, face_locations[ix]))
            key = utils.show_prediction_labels_on_image(
                predictions, None, preds_per_person[cls][ix][3], 0,
                preds_per_person[cls][ix][1], str_count)
            if key == 46:  # key '.'
                ix += 1
            elif key == 44:  # key ','
                ix -= 1
            elif key == 114:  # key 'r'
                ix = random.randint(0, len(face_locations))
                while (preds_per_person[cls][ix][3] != 0):
                    ix = random.randint(0, len(face_locations) - 1)
            elif key == 99:  # key 'c'
                new_name = utils.guided_input(preds_per_person)
                if new_name != "":
                    save.append(copy.deepcopy(preds_per_person[cls]))
                    # add pred in new list
                    if preds_per_person.get(new_name) == None:
                        preds_per_person[new_name] = []
                    tmp = preds_per_person[cls][ix]
                    preds_per_person[new_name].append(
                        ((new_name, tmp[0][1]), tmp[1], tmp[2], tmp[3],
                         tmp[4]))
                    # delete pred in current list
                    face_locations, face_encodings = utils.delete_element_preds_per_person(
                        preds_per_person, cls, ix)
                    print("face changed: {} ({})".format(
                        new_name, len(preds_per_person[new_name])))
            elif key == 117:  # key 'u'
                save.append(copy.deepcopy(preds_per_person[cls]))
                new_name = 'unknown'
                # add pred in new list
                if preds_per_person.get(new_name) == None:
                    preds_per_person[new_name] = []
                tmp = preds_per_person[cls][ix]
                preds_per_person[new_name].append(
                    ((new_name, tmp[0][1]), tmp[1], tmp[2], tmp[3], tmp[4]))
                # delete pred in current list
                face_locations, face_encodings = utils.delete_element_preds_per_person(
                    preds_per_person, cls, ix)
                print("face changed: {} ({})".format(
                    new_name, len(preds_per_person[new_name])))
            elif key == 47:  # key '/'
                save.append(copy.deepcopy(preds_per_person[cls]))
                tmp = preds_per_person[cls][ix]
                if tmp[3] == 0:
                    preds_per_person[cls][ix] = tmp[0], tmp[1], tmp[2], 1, tmp[
                        4]
                elif tmp[3] == 1:
                    preds_per_person[cls][ix] = tmp[0], tmp[1], tmp[2], 0, tmp[
                        4]
                #while (preds_per_person[cls][ix][3] == 0 and not ix == len(face_locations) - 1):
                ix += 1
                print("face confirmed: {} ({})".format(
                    tmp[0], len(preds_per_person[cls])))
            elif key == 102:  #key 'f'
                while (preds_per_person[cls][ix][3] != 0
                       and ix < len(face_locations) - 1):
                    ix += 1
            elif key >= 48 and key <= 57:  # keys '0' - '9'
                save.append(copy.deepcopy(preds_per_person[cls]))
                new_name = names[key - 48]
                tmp = preds_per_person[cls][ix]
                preds_per_person[new_name].append(
                    ((new_name, tmp[0][1]), tmp[1], tmp[2], tmp[3], tmp[4]))
                # delete pred in current list
                face_locations, face_encodings = utils.delete_element_preds_per_person(
                    preds_per_person, cls, ix)
                print("face confirmed: {} ({})".format(
                    new_name, len(preds_per_person[new_name])))
            elif key == 100:  # key 'd'
                if 1:
                    save.append(copy.deepcopy(preds_per_person[cls]))
                    new_name = 'deleted'
                    # add pred in new list
                    if preds_per_person.get(new_name) == None:
                        preds_per_person[new_name] = []
                    tmp = preds_per_person[cls][ix]
                    preds_per_person[new_name].append(
                        ((new_name, tmp[0][1]), tmp[1], tmp[2], tmp[3],
                         tmp[4]))
                    # delete pred in current list
                    face_locations, face_encodings = utils.delete_element_preds_per_person(
                        preds_per_person, cls, ix)
                else:
                    save.append(copy.deepcopy(preds_per_person[cls]))
                    # delete face
                    face_locations, face_encodings = utils.delete_element_preds_per_person(
                        preds_per_person, cls, ix)
                print("face deleted")
            elif key == 97:  # key 'a'
                # delete all faces of this class in the current image
                save.append(copy.deepcopy(preds_per_person[cls]))
                image_path = preds_per_person[cls][ix][1]
                i = 0
                while i < len(preds_per_person[cls]):
                    compare_path = preds_per_person[cls][i][1]
                    if preds_per_person[cls][i][1] == image_path:
                        face_locations, face_encodings = utils.delete_element_preds_per_person(
                            preds_per_person, cls, i)
                    else:
                        i += 1
                print("all faces in {} deleted".format(image_path))

            elif key == 98:  #key 'b'
                if len(save) > 0:
                    preds_per_person[cls] = copy.deepcopy(save.pop())
                    face_locations, face_encodings = utils.initialize_face_data(
                        preds_per_person, cls)
                    print("undone last action")
            elif key == 115:  #key 's'
                utils.export_persons_to_csv(preds_per_person, args.db)
                print('saved')

        utils.export_persons_to_csv(preds_per_person, args.db)
コード例 #7
0
def train(args):
    X = []
    y = []
    train_dir = args.traindir

    detector = dlib.get_frontal_face_detector()
    sp = dlib.shape_predictor("models/shape_predictor_5_face_landmarks.dat")
    facerec = dlib.face_recognition_model_v1(
        "models/dlib_face_recognition_resnet_model_v1.dat")

    if len(utils.get_files_in_dir(train_dir, '.csv')) != 0:
        # train using csv files
        print('Training using .csv files.')

        preds_per_person = utils.load_faces_from_csv(train_dir)
        for p in preds_per_person:
            if p != 'unknown':
                for l in preds_per_person[p]:
                    X.append(l[2])
                    y.append(p)

        if len(X) == 0:
            print('No faces found in database {}'.format(train_dir))
            return

    elif len(os.listdir(train_dir)) != 0:
        # train using train folder
        # Loop through each person in the training set
        print('Training using faces in subfolders.')
        for class_dir in os.listdir(train_dir):
            if not os.path.isdir(os.path.join(train_dir, class_dir)):
                continue

            images = utils.get_images_in_dir(os.path.join(
                train_dir, class_dir))
            if len(images) == 0:
                continue

            print('adding {} to training data'.format(class_dir))
            # Loop through each training image for the current person
            for img_path in images:
                locations, descriptors = utils.detect_faces_in_image(
                    img_path, detector, facerec, sp, use_entire_image=True)

                # Add face descriptor for current image to the training set
                X.append(descriptors[0])
                y.append(class_dir)
            print('{} faces used for training'.format(len(images)))
    else:
        print('Training directory does not contain valid training data.')
        return

    # Determine how many neighbors to use for weighting in the KNN classifier
    n_neighbors = int(round(math.sqrt(len(X))))
    print("Chose n_neighbors automatically:", n_neighbors)

    # Create and train the KNN classifier
    print("Training model with KNN ...")
    knn_clf = neighbors.KNeighborsClassifier(n_neighbors=n_neighbors,
                                             algorithm='ball_tree',
                                             weights='distance')
    knn_clf.fit(X, y)

    # Save the trained KNN classifier
    with open(os.path.join(args.outdir, 'knn.clf'), 'wb') as f:
        pickle.dump(knn_clf, f)

    # train the svm
    print("Training model with an SVM ...")
    recognizer = SVC(C=1.0, kernel="linear", probability=True)
    recognizer.fit(X, y)

    # Save the trained SVM
    with open(os.path.join(args.outdir, 'svm.clf'), 'wb') as f:
        pickle.dump(recognizer, f)

    print('Trained models with {} faces'.format(len(X)))
コード例 #8
0
def save_to_exif(args):
  preds_per_person = utils.load_faces_from_csv(args.db)
  if len(preds_per_person) == 0:
    print('no faces loaded')
    exit()
コード例 #9
0
def save_to_exif(args):
    face_prefix = 'f '
    # json_dir = os.path.join(args.db, 'exif_json')

    preds_per_person = utils.load_faces_from_csv(args.db, args.imgs_root)
    if len(preds_per_person) == 0:
        print('no faces loaded')
        exit()

    keywords_files = {}

    for p in preds_per_person:
        # print('exporting {}'.format(p))
        for f in preds_per_person[p]:
            # check mask
            if args.mask_folder != None:
                if os.path.dirname(f[1]) != args.mask_folder:
                    continue

            if os.path.isfile(f[1]):
                if keywords_files.get(f[1]) == None:
                    keywords_files[f[1]] = []
                if p != 'unknown' and p != 'deleted':
                    keywords_files[f[1]].append(face_prefix + p)

    if args.mask_folder == None:
        all_images = utils.get_images_in_dir_rec(args.imgs_root)
    else:
        all_images = utils.get_images_in_dir_rec(args.mask_folder)

    for i, k in enumerate(all_images):
        if args.mask_folder != None:
            if os.path.dirname(k) != args.mask_folder:
                continue
        changed = False
        print('processing exif {}/{} ... {}'.format(i, len(all_images), k))
        ex = exif.ExifEditor(k)
        # test = ex.getDictTags()
        tag = ex.getTag('Description')
        if tag != os.path.basename(os.path.dirname(k)):
            ex.setTag('Description', os.path.basename(os.path.dirname(k)))
            print('updated tag <Description>')

        # get face keywords (they start with 'f ')
        kw_faces_exif = []
        kw_others = []
        kws = ex.getKeywords()

        # multiple keywords found
        for kw in kws:
            if kw[:2] == face_prefix:
                kw_faces_exif.append(kw)
            else:
                kw_others.append(kw)

        new_kws = []

        if keywords_files.get(k) == None:
            if args.overwrite:
                changed = True
        else:
            if set(keywords_files[k]) != set(kw_faces_exif):
                new_kws = keywords_files[k]
                if not args.overwrite:
                    new_kws = new_kws + kw_others
                changed = True

        if changed:
            ex.setKeywords(new_kws)

        else:
            print('no change in exif found')
コード例 #10
0
ファイル: cluster.py プロジェクト: humenbergerm/faces
def cluster_faces_in_class(args):
    preds_per_person = utils.load_faces_from_csv(args.db, args.imgs_root)
    if preds_per_person.get(args.cls) == None:
        print('Class {} not found.'.format(args.cls))
        return

    descriptors = []
    for i, p in enumerate(preds_per_person[args.cls]):
        descriptors.append(dlib.vector(p[2]))

    # cluster the faces
    print('clustering...')
    all_indices = []
    all_lengths = []

    if 1:
        # chinese whispers
        labels = dlib.chinese_whispers_clustering(descriptors, args.threshold)
        num_classes = len(set(labels))
        print("Number of clusters: {}".format(num_classes))
        for j in range(0, num_classes):
            class_length = len([label for label in labels if label == j])
            if class_length >= args.min_members:
                indices = []
                for i, label in enumerate(labels):
                    if label == j:
                        indices.append(i)
                all_indices.append(indices)
                all_lengths.append(class_length)
    else:
        #DBSCAN
        from sklearn.cluster import DBSCAN
        clt = DBSCAN(eps=args.threshold,
                     metric="euclidean",
                     n_jobs=4,
                     min_samples=args.min_members)
        clt.fit(descriptors)
        labels = np.unique(clt.labels_)
        num_classes = len(np.where(labels > -1)[0])

        if num_classes > 1:  # to be checked!!
            print("Number of clusters: {}".format(num_classes))
            for j in labels:
                idxs = np.where(clt.labels_ == j)[0]
                class_length = len(idxs)
                indices = []
                for i in idxs:
                    indices.append(i)
                all_indices.append(indices)
                all_lengths.append(class_length)

    sort_index = np.argsort(np.array(all_lengths))[::-1]

    # Move the clustered faces to individual groups
    print('Moving the clustered faces to the database.')
    to_delete = []
    for i in sort_index[:args.max_clusters]:
        cluster_name = "group_" + str(i)

        # export to folders
        if args.export:
            cluster_path = os.path.join(args.outdir, cluster_name)
            if not os.path.isdir(cluster_path):
                os.makedirs(cluster_path)

        to_delete += all_indices[i]
        for n, index in enumerate(all_indices[i]):
            utils.insert_element_preds_per_person(preds_per_person, args.cls,
                                                  index, cluster_name)
            if args.export:
                file_name = os.path.join(
                    cluster_path,
                    'face_' + cluster_name + '_' + str(n) + '.jpg')
                utils.save_face_crop(file_name,
                                     preds_per_person[args.cls][index][1],
                                     preds_per_person[args.cls][index][0][1])

    to_delete = sorted(to_delete)
    to_delete.reverse()
    for i in to_delete:
        preds_per_person[cls].pop(
            i
        )  # if not, they would exist double, in 'deleted' and in the cluster group
        # utils.delete_element_preds_per_person(preds_per_person, args.cls, i)

    utils.export_persons_to_csv(preds_per_person, args.imgs_root, args.db)