当前位置:   article > 正文

Elasticsearch:如何使用 Elasticsearch 和 Python 构建面部识别系统_elasticsearch 可以搜索人脸特征

elasticsearch 可以搜索人脸特征

你是否曾经尝试在图像中搜索目标? Elasticsearch 可以帮助你存储,分析和搜索图像或视频中的目标。

在本快速教程中,我们将向你展示如何构建一个使用 Python 进行面部识别的系统。 了解有关如何检测和编码面部信息的更多信息-并在搜索中找到匹配项。

在今天的练习中,我们将参照代码:GitHub - liu-xiao-guo/face_detection_elasticsearch。你可以把这个代码下载到本地的电脑:

  1. $ pwd
  2. /Users/liuxg/python/face_detection
  3. $ tree -L 2
  4. .
  5. ├── README.md
  6. ├── getVectorFromPicture.py
  7. ├── images
  8. │   ├── shay.png
  9. │   ├── simon.png
  10. │   ├── steven.png
  11. │   └── uri.png
  12. ├── images_to_be_recognized
  13. │   └── facial-recognition-blog-elastic-founders-match.png
  14. └── recognizeFaces.py

在上面的代码中,有如下的两个 python 文件:

  • getVectorFromPicture.py:导入在 images 目录下的图像。这些图像将被导入到 Elasticsearch 中
  • recognizeFaces.py:识别位于 images_to_be_recognized 目录下的图像文件

快速基础知识

需要复习吗? 让我们简要回顾一些基本概念的一些基础知识。

面部识别

面部识别是使用面部特征来识别用户的过程,例如,为了实现身份验证机制(例如解锁智能手机)。 它根据人的面部细节捕获,分析和比较模式。 此过程可以分为三个步骤:

  • 人脸检测:识别数字图像中的人脸
  • 人脸数据编码:将人脸特征转换为数字表示
  • 脸部比对:搜寻和比较脸部特征

在示例中,我们将引导你完成每个步骤。

128 维向量

可以将面部特征转换为一组数字信息,以便进行存储和分析。

Vector data type

Elasticsearch 提供了 dense_vector 数据类型来存储浮点值的 dense vectors。 向量中的最大尺寸数不应超过2048,这足以存储面部特征表示。

现在,让我们实现所有这些概念。关于 dense_vector,你可以阅读我之前的文章 “Elasticsearch:基于 Vector 的打分”。

你需要的一切

要检测面部并编码信息,你需要执行以下操作:

请注意,我们已经在 Ubuntu 20.04 LTS 和 Ubuntu 18.04 LTS 上测试了以下说明。 根据你的操作系统,可能需要进行一些更改。尽管下面的安装步骤是针对 Ubuntu 操作系统的,但是我们可以按照同样的步骤在 Mac OS 上进行同样的顺序进行安装(部分指令会有所不同)。

安装 Python 和 Python 库

随 Python 3 的安装一起提供了 Ubuntu 20.04 和其他版本的 Debian Linux。如果你的系统不是这种情况,则可以使用此链接下载并安装 Python。

要确认你的版本是最新版本,可以运行以下命令:

  1. sudo apt update
  2. sudo apt upgrade

确认 Python 版本为 3.x:

python3 -V

或者:

 python --version

安装 pip3 来管理 Python 库:

sudo apt install -y python3-pip

安装 face_recognition 库所需的 cmake:

pip3 install CMake

将 cmake bin 文件夹添加到 $PATH 目录中:

export PATH=$CMake_bin_folder:$PATH

在我的测试中,上述步骤可以不需要。你只要在任何一个  terminal 中打入 cmake 命令,如果能看到被执行,那么就可以不用上面的命令了。

最后,在开始编写主程序脚本之前,安装以下库:

  1. pip3 install dlib
  2. pip3 install numpy
  3. pip3 install face_recognition
  4. pip3 install elasticsearch

从图像中检测和编码面部信息

使用 face_recognition 库,我们可以从图像中检测人脸,并将人脸特征转换为 128 维向量。

为此,我们创建一个叫做 getVectorFromPicture.py:

getVectorFromPicture.py

  1. import face_recognition
  2. import numpy as np
  3. import sys
  4. import os
  5. from pathlib import Path
  6. from elasticsearch import Elasticsearch
  7. es = Elasticsearch([{'host':'localhost','port':9200}])
  8. cwd = os.getcwd()
  9. print("cwd: " + cwd)
  10. # Get the images directory
  11. rootdir = cwd + "/images"
  12. print("rootdir: " + rootdir)
  13. for subdir, dirs, files in os.walk(rootdir):
  14. for file in files:
  15. print(os.path.join(subdir, file))
  16. file_path = os.path.join(subdir, file)
  17. image = face_recognition.load_image_file(file_path)
  18. # detect the faces from the images
  19. face_locations = face_recognition.face_locations(image)
  20. # encode the 128-dimension face encoding for each face in the image
  21. face_encodings = face_recognition.face_encodings(image, face_locations)
  22. # Display the 128-dimension for each face detected
  23. for face_encoding in face_encodings:
  24. print("Face found ==> ", face_encoding.tolist())
  25. print("name: " + Path(file_path).stem)
  26. name = Path(file_path).stem
  27. face_encoding = face_encoding.tolist()
  28. # format a dictionary to be indexed
  29. e = {
  30. "face_name": name,
  31. "face_encoding": face_encoding
  32. }
  33. res = es.index(index = 'faces', doc_type ='_doc', body = e)

首先,我们需要声明的是:你需要修改上面的 Elasticsearch 的地址,如果你的 Elasticsearch 不是运行于 localhost:9200。上面的代码非常之简单。它把当前目录下的子目录 images 下的所有文件都扫描一遍,并针对每个文件进行编码。我们使用 Python client API 接口把数据导入到 Elasticsearch 中去。在我们的 images 文件夹中,有四个文件。

在导入数据之前,我们需要在 Kibana 中创建一个叫做 faces 的索引:

  1. PUT faces
  2. {
  3. "mappings": {
  4. "properties": {
  5. "face_name": {
  6. "type": "keyword"
  7. },
  8. "face_encoding": {
  9. "type": "dense_vector",
  10. "dims": 128
  11. }
  12. }
  13. }
  14. }

让我们执行 getVectorFromPicture.py 以获取 Elastic 创始人图像的面部特征表示。 

python3 getVectorFromPicture.py

现在,我们可以将面部特征表示存储到 Elasticsearch 中。

我们可以在 Elasticsearch 中看到四个文档:

GET faces/_count
  1. {
  2. "count" : 4,
  3. "_shards" : {
  4. "total" : 1,
  5. "successful" : 1,
  6. "skipped" : 0,
  7. "failed" : 0
  8. }
  9. }

我们也可以查看 faces 索引的文档:

GET faces/_search

匹配面孔

假设我们在 Elasticsearch 中索引了四个文档,其中包含 Elastic 创始人的每个面部表情。 现在,我们可以使用创始人的其他图像来匹配各个图像。

为此,我们需要创建一个叫做 recognizeFaces.py  的文件。

recognizeFaces.py 

  1. import face_recognition
  2. import numpy as np
  3. from elasticsearch import Elasticsearch
  4. import sys
  5. import os
  6. from elasticsearch import Elasticsearch
  7. es = Elasticsearch([{'host': 'localhost', 'port': 9200}])
  8. cwd = os.getcwd()
  9. # print("cwd: " + cwd)
  10. # Get the images directory
  11. rootdir = cwd + "/images_to_be_recognized"
  12. # print("rootdir: {0}".format(rootdir))
  13. for subdir, dirs, files in os.walk(rootdir):
  14. for file in files:
  15. print(os.path.join(subdir, file))
  16. file_path = os.path.join(subdir, file)
  17. image = face_recognition.load_image_file(file_path)
  18. # detect the faces from the images
  19. face_locations = face_recognition.face_locations(image)
  20. # encode the 128-dimension face encoding for each face in the image
  21. face_encodings = face_recognition.face_encodings(image, face_locations)
  22. # Display the 128-dimension for each face detected
  23. i = 0
  24. for face_encoding in face_encodings:
  25. i += 1
  26. print("Face", i)
  27. response = es.search(
  28. index="faces",
  29. body={
  30. "size": 1,
  31. "_source": "face_name",
  32. "query": {
  33. "script_score": {
  34. "query": {
  35. "match_all": {}
  36. },
  37. "script": {
  38. "source": "cosineSimilarity(params.query_vector, 'face_encoding')",
  39. "params": {
  40. "query_vector": face_encoding.tolist()
  41. }
  42. }
  43. }
  44. }
  45. }
  46. )
  47. # print(response)
  48. for hit in response['hits']['hits']:
  49. # double score=float(hit['_score'])
  50. print("score: {}".format(hit['_score']))
  51. if float(hit['_score']) > 0.92:
  52. print("==> This face match with ", hit['_source']['face_name'], ",the score is", hit['_score'])
  53. else:
  54. print("==> Unknown face")

这个文件的写法也非常简单。它从目录 images_to_be_recognized 中获取需要识别的文件,并对这个图片进行识别。我们使用 cosineSimilarity 函数来计算给定查询向量和存储在Elasticsearch 中的文档向量之间的余弦相似度。

  1. # Display the 128-dimension for each face detected
  2. i = 0
  3. for face_encoding in face_encodings:
  4. i += 1
  5. print("Face", i)
  6. response = es.search(
  7. index="faces",
  8. body={
  9. "size": 1,
  10. "_source": "face_name",
  11. "query": {
  12. "script_score": {
  13. "query": {
  14. "match_all": {}
  15. },
  16. "script": {
  17. "source": "cosineSimilarity(params.query_vector, 'face_encoding')",
  18. "params": {
  19. "query_vector": face_encoding.tolist()
  20. }
  21. }
  22. }
  23. }
  24. }
  25. )

假设分数低于 0.92  被认为是未知面孔:

  1. for hit in response['hits']['hits']:
  2. # double score=float(hit['_score'])
  3. print("score: {}".format(hit['_score']))
  4. if float(hit['_score']) > 0.92:
  5. print("==> This face match with ", hit['_source']['face_name'], ",the score is", hit['_score'])
  6. else:
  7. print("==> Unknown face")

执行上面的 Python 代码:

该脚本能够检测出得分匹配度高于 0.92 的所有面孔

搜寻进阶更进一步

面部识别和搜索可以结合使用,以用于高级用例。 你可以使用 Elasticsearch 构建更复杂的查询,例如 geo_queriesquery-dsl-bool-querysearch-aggregations

例如,以下查询将 cosineSimilarity 搜索应用于200公里半径内的特定位置:

  1. GET /_search
  2. {
  3. "query": {
  4. "script_score": {
  5. "query": {
  6. "bool": {
  7. "must": {
  8. "match_all": {}
  9. },
  10. "filter": {
  11. "geo_distance": {
  12. "distance": "200km",
  13. "pin.location": {
  14. "lat": 40,
  15. "lon": -70
  16. }
  17. }
  18. }
  19. }
  20. },
  21. "script": {
  22. "source": "cosineSimilarity(params.query_vector, 'face_encoding')",
  23. "params": {
  24. "query_vector":[
  25. -0.14664565,
  26. 0.07806452,
  27. 0.03944433,
  28. ...
  29. ...
  30. ...
  31. -0.03167224,
  32. -0.13942884
  33. ]
  34. }
  35. }
  36. }
  37. }
  38. }

将 cosineSimilarity 与其他 Elasticsearch 查询结合使用,可以无限地实现更复杂的用例。

结论

面部识别可能与许多用例相关,并且你可能已经在日常生活中使用了它。 上面描述的概念可以推广到图像或视频中的任何对象检测,因此你可以将用例扩展到非常大的应用场景。

参考:

【1】How to Build a Facial Recognition System Using Elasticsearch and Python | Elastic Blog

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/爱喝兽奶帝天荒/article/detail/1004705
推荐阅读
相关标签
  

闽ICP备14008679号