《Elastic Stack 实战手册》——四、应用实践——4.2 可观测性应用场景 ——4.2.4.Elasticsearch和Python构建面部识别系统(中) https://developer.aliyun.com/article/1225805
匹配面孔
假设我们在 Elasticsearch 中索引了四个文档,其中包含 Elastic 创始人的每个面部表情。 现在,我们可以使用创始人的其他图像来匹配各个图像。
为此,我们需要创建一个叫做 recognizeFaces.py 的文件。
recognizeFaces.py
import face_recognition import numpy as np from elasticsearch import Elasticsearch import sys import os from elasticsearch import Elasticsearch es = Elasticsearch([{'host': 'localhost', 'port': 9200}]) cwd = os.getcwd() # print("cwd: " + cwd)
# Get the images directory rootdir = cwd + "/images_to_be_recognized" # print("rootdir: {0}".format(rootdir)) for subdir, dirs, files in os.walk(rootdir): for file in files: print(os.path.join(subdir, file)) file_path = os.path.join(subdir, file) image = face_recognition.load_image_file(file_path) # detect the faces from the images face_locations = face_recognition.face_locations(image) # encode the 128-dimension face encoding for each face in the image face_encodings = face_recognition.face_encodings(image, face_locations) # Display the 128-dimension for each face detected i = 0 for face_encoding in face_encodings: i += 1 print("Face", i) response = es.search( index="faces", body={ "size": 1, "_source": "face_name", "query": { "script_score": { "query": { "match_all": {} }, "script": { "source": "cosineSimilarity(params.query_vector, 'face_encoding')", "params": { "query_vector": face_encoding.tolist() } } } } } ) # print(response) for hit in response['hits']['hits']: # double score=float(hit['_score']) print("score: {}".format(hit['_score'])) if float(hit['_score']) > 0.92: print("==> This face match with ", hit['_source']['face_name'], ",the score is", hit['_score']) else: print("==> Unknown face")
这个文件的写法也非常简单。它从目录 images_to_be_recognized 中获取需要识别的文件,并对这个图片进行识别。我们使用 cosineSimilarity 函数来计算给定查询向量和存储在 Elasticsearch 中的文档向量之间的余弦相似度。
# Display the 128-dimension for each face detected i = 0 for face_encoding in face_encodings: i += 1 print("Face", i) response = es.search( index="faces", body={ "size": 1, "_source": "face_name", "query": { "script_score": { "query": { "match_all": {} }, "script": { "source": "cosineSimilarity(params.query_vector, 'face_encoding')", "params": { "query_vector": face_encoding.tolist() } } } } } )
假设分数低于 0.92 被认为是未知面孔:
for hit in response['hits']['hits']: # double score=float(hit['_score']) print("score: {}".format(hit['_score'])) if float(hit['_score']) > 0.92: print("==> This face match with ", hit['_source']['face_name'], ",the score is", hit['_score']) else: print("==> Unknown face")
执行上面的 Python 代码:
该脚本能够检测出得分匹配度高于 0.92 的所有面孔
搜寻进阶
面部识别和搜索可以结合使用,以用于高级用例。 你可以使用 Elasticsearch 构建更复杂的查询,例如 geo_queries,query-dsl-bool-query 和 search-aggregations。
例如,以下查询将 cosineSimilarity 搜索应用于200公里半径内的特定位置:
GET /_search { "query": { "script_score": { "query": { "bool": { "must": { "match_all": {} }, "filter": { "geo_distance": { "distance": "200km", "pin.location": { "lat": 40, "lon": -70 } } } } }, "script": { "source": "cosineSimilarity(params.query_vector, 'face_encoding')", "params": { "query_vector":[ -0.14664565, 0.07806452, 0.03944433, ... ... ... -0.03167224, -0.13942884 ] } } } } }
将 cosineSimilarity 与其他 Elasticsearch 查询结合使用,可以无限地实现更复杂的用例。
结论
面部识别可能与许多用例相关,并且你可能已经在日常生活中使用了它。 上面描述的概念可以推广到图像或视频中的任何对象检测,因此你可以将用例扩展到非常大的应用场景。
参考
l https://www.elastic.co/blog/how-to-build-a-facial-recognition-system-using-elasticsearch-and-python
创作人简介:
刘晓国,现为 Elastic 社区资深布道师。新加坡国立大学硕士,西北工业大学本硕。曾就职于新加坡科技,康柏电脑,通用汽车,爱立信,诺基亚,Linaro 非营利组织(Linux for ARM),
Ubuntu,LinkMotion,Vantiq等企业。从事过通信,电脑设计,计算机操作系统,物联网,汽车电子,云实时事件处理,大数据搜索等行业。从爱立信开始,到后来的诺基亚,Ubuntu从事社区工作有超过 15 年以上经历。喜欢分享自己所学到的知识,希望和大家一起分享及学习。