def clusters(): """ Отображает AJAX-версию страницы с кластеризацией. Предназначено для замены display_clusters() после тестирования. """ person = request.values.get('filter') print(person) Face._index.refresh() total = Face.search().count() named = Face.search().filter("exists", field="person").count() status = "{:.1%} ({} out of {}) faces are named. Clusters count: {}".format( named / total, named, total, Cluster.search().count()) a = A("terms", field="person.raw", size=10000) ps = Search() ps.aggs.bucket("persons", a) psr = ps.execute() persons = [b.key for b in psr.aggs['persons']] if person: s = Cluster.search().filter("prefix", person=person).sort("-face_count") results = s[0:10000].execute() else: s = Cluster.search().exclude("exists", field="person") s.query = FunctionScore(query=s.query, functions=[SF('random_score', weight=100), SF('field_value_factor', field="face_count", weight=1)], score_mode="avg", boost_mode="replace") results = s[0:50].execute() return render_template('clusters.html', clusters=results, persons=persons, status=status)
def extract_faces(file_name, image, output_folder, named): image_np = np.array(image) locations = face_recognition.face_locations(image_np) encodings = face_recognition.face_encodings(image_np, locations) face_count = 0 for location, features in zip(locations, encodings): face = Face() face.file_name = file_name face.features = base64.b64encode(features).decode() face.position.top = location[0] face.position.right = location[1] face.position.bottom = location[2] face.position.left = location[3] if named: face.person = os.path.splitext(os.path.basename(file_name))[0] face.save() face_count += 1 if output_folder: face_image = image_np[location[0]:location[2], location[3]:location[1]] pil_image = Image.fromarray(face_image) pil_image.save(join(output_folder, face.meta.id + '.jpg'), "JPEG", quality=90, optimize=True, progressive=True) return face_count
def shuffle(): print_faces_stats() faces = [face for face in Face.search().scan()] clst = approximate_rank_order_clustering(faces) generate_clusters_index(clst) clusters_with_person = Cluster.search().filter("exists", field="person").scan() for cls in clusters_with_person: cls.update_faces_index() print_faces_stats()
def generate_images_index(): Photo._index.delete(ignore=404) Photo.init() results = Face.search().filter("exists", field="person").exclude('terms', person=['ignored']).scan() groups = defaultdict(list) for face in results: groups[face.file_name].append(face.person) bulk(Elasticsearch(args.elastic), (Photo(group[0], group[1]).to_dict(True) for group in groups.items()))
def display_faces(person): Face._index.refresh() s = Face.search().filter("term", person__raw=person) status = "{}: {}".format(person, s.count()) results = s[0:1000].execute() return render_template('faces.html', faces=results, status=status)
def display_image(face_id): face = Face().get(face_id) img_src = os.path.splitdrive(face.file_name)[1] status = "" return render_template('image.html', img_src=img_src, status=status)
def print_faces_stats(): Face._index.refresh() total = Face.search().count() named = Face.search().filter("exists", field="person").count() print("{:.1%} ({} out of {}) faces are named.".format(named / total, named, total))
"--user", dest="user", help="RabbitMQ user name", metavar="USER", default='guest') parser.add_argument("-p", "--password", dest="password", help="RabbitMQ user password", metavar="PASSWORD", default='guest') args = parser.parse_args() connections.create_connection(hosts=[args.elastic]) Face.init() print(' [*] Waiting for messages. To exit press CTRL+BREAK') credentials = PlainCredentials(args.user, args.password) connection = pika.BlockingConnection( pika.ConnectionParameters(host=args.host, credentials=credentials)) channel = connection.channel() channel.queue_declare(queue='img_queue', durable=True) def callback(ch, method, properties, body): file_name = body.decode() try: image = Image.open(file_name) faces_extracted = extract_faces( file_name, image, args.folder,