def __clusterize(self, files_faces, debug_out_folder=None): self.__start_stage(len(files_faces)) encs = [] indexes = list(range(len(files_faces))) random.shuffle(indexes) for i in indexes: for j in range(len(files_faces[i]['faces'])): encs.append(dlib.vector( files_faces[i]['faces'][j]['encoding'])) labels = dlib.chinese_whispers_clustering( encs, self.__threshold_clusterize) labels = self.__reassign_by_count(labels) lnum = 0 for i in indexes: if self.__step_stage(): break for j in range(len(files_faces[i]['faces'])): files_faces[i]['faces'][j]['name'] = \ 'unknown_{:05d}'.format(labels[lnum]) lnum += 1 if debug_out_folder: filename = files_faces[i]['filename'] media = tools.load_media(filename, self.__max_size, self.__max_video_frames, self.__video_frames_step) debug_out_file_name = self.__extract_filename(filename) self.__save_debug_images( files_faces[i]['faces'], media, debug_out_folder, debug_out_file_name) self.__end_stage()
def __save_faces(self, files_faces, debug_out_folder): for ff in files_faces: if self.__step_stage(): break filename = ff['filename'] log.info(f"save faces from image: {filename}") media = tools.load_media(filename, self.__max_size, self.__max_video_frames, self.__video_frames_step) debug_out_file_name = self.__extract_filename(filename) is_video = tools.get_low_ext(filename) in tools.VIDEO_EXTS self.__save_debug_images( ff['faces'], media, debug_out_folder, debug_out_file_name, is_video=is_video) self.__step_stage_face(len(ff['faces'])) self.__end_stage()
def get_faces_by_face(self, filename, debug_out_folder, remove_file=False): if self.__init_stage('get_faces_by_face', locals()): return image = tools.LazyImage(filename, self.__max_size) encoded_faces = self.encode_faces(image.get()) face = encoded_faces[0] log.debug(f'found face: {face}') all_encodings = self.__db.get_all_encodings(self.__max_workers) res = [r for r in self.__executor.map( self.__encoder.distance, all_encodings[0], itertools.repeat(face['encoding']))] distances = numpy.concatenate(res) filtered = [] for dist, info in zip(distances, all_encodings[1]): if dist < 0.4: filtered.append((dist, info)) filtered.sort() log.debug(f'{len(filtered)} faces matched') self.__start_stage(len(filtered)) for dist, info in filtered: if self.__step_stage(): break fname, face = info face['dist'] = dist media = tools.load_media(fname, self.__max_size, self.__max_video_frames, self.__video_frames_step) debug_out_file_name = self.__extract_filename(fname) self.__save_debug_images( (face,), media, debug_out_folder, debug_out_file_name) self.__step_stage_face() if remove_file: log.debug(f'removing temp file: {filename}') os.remove(filename)
def __match_files_faces( self, files_faces, debug_out_folder, save_all_faces=False, skip_face_gen=False): cnt_all = 0 cnt_changed = 0 for ff in files_faces: if self.__step_stage(): break filename = ff['filename'] log.info(f"match image: {filename}") is_video = tools.get_low_ext(filename) in tools.VIDEO_EXTS if not self.__match_faces(ff['faces']): continue for face in ff['faces']: if self.__step_stage_face(): break cnt_all += 1 changed = False if 'oldname' in face and face['oldname'] != face['name']: self.__db.set_name(face['face_id'], face['name'], face['dist'], face['pattern'], commit=False) cnt_changed += 1 changed = True log.info( f"face {face['face_id']} in file '{ff['filename']}' " + f"changed '{face['oldname']}' -> '{face['name']}'") if debug_out_folder and (changed or save_all_faces): media = tools.load_media(filename, self.__max_size, self.__max_video_frames, self.__video_frames_step) debug_out_file_name = self.__extract_filename(filename) self.__save_debug_images( (face,), media, debug_out_folder, debug_out_file_name, is_video=is_video, skip_face_gen=skip_face_gen) self.__end_stage() log.info(f'match done: count: {cnt_all}, changed: {cnt_changed}')