树莓派 + Docker - 轻松实现人脸识别应用

本文涉及的产品
容器镜像服务 ACR,镜像仓库100个 不限时长
容器服务 Serverless 版 ACK Serverless,952元额度 多规格
容器服务 Serverless 版 ACK Serverless,317元额度 多规格
简介: 人脸识别技术已经被广泛应用在众多场景中。今天我们将利用Docker容器在树莓派上快速打造一个人脸识别应用。

15153134217709

人脸识别技术已经被广泛应用在众多场景中。今天我们将利用Docker容器在树莓派上快速打造一个人脸识别应用。

本文使用 https://github.com/ageitgey/face_recognition 开源框架,基于 dlib (Deep Metric Learning) 支持人脸识别功能。dlib 在Labeled Faces in the Wild 测试基准上的准确率达到 99.38%。face_recognition的应用开发极为简单,只用几行 Python 命令行就可以轻松实现人脸识别应用,而且也提供了树莓派的支持。

在Raspberry Pi 2+ 平台安装face_recognition的指南如下
https://gist.github.com/ageitgey/1ac8dbe8572f3f533df6269dab35df65

树莓派是Geek们最爱的开发板,其原因就在于成熟的软件生态和丰富的I/O接口,然而在树莓派上搞深度学习应用开发并非易事

  1. 很多包需要下载编译,以孱弱的Raspberry Pi编译应用,需要极大的耐心。
  2. 然而开源的深度学习框架很多,不同类库的依赖不同,有些会互相冲突,比如有些需要Python 2.7,有些则依赖 3.x。虽然我们可以用virtualenv对Python环境进行隔离,但是对于一些系统级的依赖冲突就不好办了。在漫长构建中遇到依赖导致编译失败,让人非常有挫败感。
  3. 如果需要在另外一块板上部署相同应用,整个过程需要重新来过。

下面我们将利用Docker来构建打包应用镜像,这样可以一次构建到处运行,也可以充分利用Dockerfile自带的分层能力,可以方便地调整依赖包,这样在开发部署过程中格外高效。

树莓派上部署人脸识别应用

得益于树莓派和Docker安装部署人脸识别开发环境非常简单

  • 在 Raspberry PI 3 安装最新的 Raspbian
  • 执行如下命令安装最新的 Docker Engine 社区版
# Install Docker
curl -sSL https://get.docker.com | sh

# Add pi to Docker group
sudo usermod pi -aG docker

# config cgroup for Docker
echo Adding " cgroup_enable=cpuset cgroup_enable=memory" to /boot/cmdline.txt
sudo cp /boot/cmdline.txt /boot/cmdline_backup.txt
# if you encounter problems, try changing cgroup_memory=1 to cgroup_enable=memory.
orig="$(head -n1 /boot/cmdline.txt) cgroup_enable=cpuset cgroup_memory=1"
echo $orig | sudo tee /boot/cmdline.txt

sudo reboot
  • 安装 Raspberry Camera ,我用的是Camera Module2 注意蓝色胶带对着以太网接口方向。并通过 raspi-config 命令来开启 camera 模块
  • 在容器中开发、运行face_recognition应用,我们可以利用如下的命令来启动容器。其包含了face_recognition 的完整开发环境和示例应用。下文会介绍镜像的具体信息
docker run -it \
    --name face_recognition \
    --device /dev/vchiq \
      registry.cn-hangzhou.aliyuncs.com/denverdino/face_recognition \
      bash

其中关键之处就在于将摄像头设备/dev/vchiq挂载到容器内部,这样就可以让容器中的应用来拍摄照片和视频。

大家可以利用 docker cp 命令,向容器中拷贝文件,比如照片,或者在容器中利用 nano 等命令来编辑代码.

人脸识别应用解析

基于 examples/facerec_on_raspberry_pi.py 我修改了一个面部识别应用供参考,其实现如下:

# This is a demo of running face recognition on a Raspberry Pi.
# This program will print out the names of anyone it recognizes to the console.

# To run this, you need a Raspberry Pi 2 (or greater) with face_recognition and
# the picamera[array] module installed.
# You can follow this installation instructions to get your RPi set up:
# https://gist.github.com/ageitgey/1ac8dbe8572f3f533df6269dab35df65

import face_recognition
import picamera
import numpy as np

known_face_encodings = []
names = []

def load_face_encoding(name, file_name):
    image = face_recognition.load_image_file(file_name)
    face_encoding = face_recognition.face_encodings(image)[0]
    known_face_encodings.append(face_encoding)
    names.append(name)

# Get a reference to the Raspberry Pi camera.
# If this fails, make sure you have a camera connected to the RPi and that you
# enabled your camera in raspi-config and rebooted first.
camera = picamera.PiCamera()
camera.resolution = (320, 240)
output = np.empty((240, 320, 3), dtype=np.uint8)

# Load a sample picture and learn how to recognize it.
print("Loading known face image(s)")
load_face_encoding("Yi Li", "yili.jpg")
load_face_encoding("Zhang Kai", "zhangkai.jpg")
load_face_encoding("Che Yang", "cheyang.jpg")

# Initialize some variables
face_locations = []
face_encodings = []

while True:
    print("Capturing image.")
    # Grab a single frame of video from the RPi camera as a numpy array
    camera.capture(output, format="rgb")

    # Find all the faces and face encodings in the current frame of video
    face_locations = face_recognition.face_locations(output)
    print("Found {} faces in image.".format(len(face_locations)))
    face_encodings = face_recognition.face_encodings(output, face_locations)

    # Loop over each face found in the frame to see if it's someone we know.
    for face_encoding in face_encodings:
        # See if the face is a match for the known face(s)
        matches = face_recognition.face_distance(known_face_encodings, face_encoding)
        name = "<Unknown Person>"
        
        min_distance = min(matches)
        if min_distance < 0.6:
            i = matches.argmin()
            name = names[i]
            
        
        print("I see someone named {}!".format(name))

首先,代码中通过如下方法,加载指定人名的头像照片,您可以把自己、好基友的照片加入人脸库。

load_face_encoding("Yi Li", "yili.jpg")

然后,摄像头持续拍摄照片,如下方法会检测到照片中的面部信息

face_locations = face_recognition.face_locations(output)
...
face_encodings = face_recognition.face_encodings(output, face_locations)

然后,对比面部信息和已知人脸信息的相似度,如果超过一个阈值,返回最为相近的同学名称,这样一个简单的人脸识别应用就完成了,是不是非常简单?

matches = face_recognition.face_distance(known_face_encodings, face_encoding)

运行的结果如下,

# python3 facerec_on_raspberry_pi.py 
Loading known face image(s)
Found 0 faces in image.
Capturing image.
Found 0 faces in image.
Capturing image.
Found 1 faces in image.
I see someone named Yi Li!
...

效果符合预期,但是受限于树莓派的处理能力,还远远达不到实时的效果,识别出人脸需要几秒的延迟。但是已经可以应用于一些简单的场景了,大家自己去开脑洞自己开发吧。

大家如果需要定制自己的人脸识别应用,可以从 https://github.com/denverdino/face_recognition_pi 获得相关的Dockerfile,来根据自己的需要构建一个完整的应用

FROM resin/raspberry-pi-python:3
COPY pip.conf /root/.pip/pip.conf
RUN apt-get -y update
RUN apt-get install -y --fix-missing \
    build-essential \
    cmake \
    gfortran \
    git \
    wget \
    curl \
    graphicsmagick \
    libgraphicsmagick1-dev \
    libatlas-dev \
    libavcodec-dev \
    libavformat-dev \
    libboost-all-dev \
    libgtk2.0-dev \
    libjpeg-dev \
    liblapack-dev \
    libswscale-dev \
    pkg-config \
    python3-dev \
    zip \
    && apt-get clean && rm -rf /tmp/* /var/tmp/*
RUN python3 -m ensurepip --upgrade && pip3 install --upgrade picamera[array] dlib

# The rest of this file just runs an example script.

# If you wanted to use this Dockerfile to run your own app instead, maybe you would do this:
# COPY . /root/your_app_or_whatever
# RUN cd /root/your_app_or_whatever && \
#     pip3 install -r requirements.txt
# RUN whatever_command_you_run_to_start_your_app

RUN git clone --single-branch https://github.com/ageitgey/face_recognition.git
RUN cd /face_recognition && \
    pip3 install -r requirements.txt && \
    python3 setup.py install

CMD cd /face_recognition/examples && \
    python3 recognize_faces_in_pictures.py

大家如果希望将自己应用打包到Docker镜像中,可以添加修改Dockerfile,我就不多说了。

最后来晒一下我的树莓派3配置,除了Camera之外还加装了一个液晶显示屏,通过GPIO驱动,可以方便地通过编程来显示CPU/Memory/温度等各种信息。

IMG_4519

总结

容器技术已经越来越多运用于IoT、边缘计算等场景,利用容器可以极大地简化智能设备的应用生命周期管理。今天我们演示了一个运行在树莓派上的人脸识别应用。本文实例代码可以从 https://github.com/denverdino/face_recognition_pi 获取。

2017我们见证了容器技术的快速发展,Kubernetes,Containerd/OCI等容器技术标准得到了生态的共识,这也将催生更多的应用创新。2018我们不但可以看见容器在企业用户的生产环境中被广泛应用,容器技术也将无处不在,给我们更多的惊喜。

目录
相关文章
|
2月前
|
弹性计算 运维 持续交付
探索Docker容器化技术及其在生产环境中的应用
探索Docker容器化技术及其在生产环境中的应用
93 5
|
17天前
|
JSON JavaScript 测试技术
【Docker项目实战】使用Docker部署PPTist在线演示文稿应用
【10月更文挑战第9天】使用Docker部署PPTist在线演示文稿应用
30 1
【Docker项目实战】使用Docker部署PPTist在线演示文稿应用
|
22天前
|
存储 测试技术 Linux
【Docker项目实战】使用Docker部署Radicale日历和联系人应用
【10月更文挑战第4天】使用Docker部署Radicale日历和联系人应用
83 2
【Docker项目实战】使用Docker部署Radicale日历和联系人应用
|
17天前
|
运维 JavaScript 虚拟化
探索容器化技术:Docker的实践与应用
【10月更文挑战第9天】探索容器化技术:Docker的实践与应用
43 3
|
24天前
|
定位技术 文件存储 网络架构
Docker部署PhotoPrism、Immich图片管理应用,无需公网IP远程访问教程
除了Synology、QNAP、TerraMaster等品牌的NAS设备内置图库功能,市面上还有多种备受欢迎的第三方应用,如PhotoPrism、Immich、LibrePhotos、Piwigo、Photoview等。这些应用不仅提供强大的图片管理能力,还可通过Docker轻松部署。借助贝锐花生壳服务,即使没有公网IP也能实现远程访问,突破地理限制,提升数据可访问性和安全性,让用户随时随地管理私人图库。
71 1
|
20天前
|
运维 监控 Cloud Native
深入了解容器化技术:Docker 的应用与实践
【10月更文挑战第6天】深入了解容器化技术:Docker 的应用与实践
24 0
|
2月前
|
Cloud Native 持续交付 Docker
探索Docker容器化技术及其在软件开发中的应用
探索Docker容器化技术及其在软件开发中的应用
33 7
|
2月前
|
Devops jenkins 持续交付
DevOps实践:构建和部署一个Docker化的应用
【9月更文挑战第14天】在当今快节奏的软件开发领域,DevOps已经成为提升效率、加速交付的关键。本文将引导你理解DevOps的核心概念,并通过一个实际的示例—构建和部署一个Docker化的应用—来深入探讨其实践方法。我们将从简单的应用出发,逐步实现Docker容器化,并最终通过CI/CD流水线自动化部署过程。这不仅是对DevOps流程的一次实操演练,也是对现代软件开发理念的一次深刻体验。
|
2月前
|
持续交付 开发者 Docker
掌握 Docker:容器化技术在现代开发中的应用
Docker 是一个开源容器化平台,使开发者能够将应用程序及其依赖项封装在轻量级容器中,确保跨平台的一致性。本文介绍了 Docker 的基本概念、核心组件及优势,并展示了其在快速部署、一致性、可移植性和微服务架构中的应用。通过示例说明了 Docker 在本地开发环境搭建、服务依赖管理和 CI/CD 流程中的作用,以及多阶段构建、资源限制和网络模式等高级特性。掌握 Docker 可大幅提升开发效率和应用管理能力。
|
28天前
|
Shell 应用服务中间件 nginx
docker学习--最详细的docker run 各子命令解释与应用
`docker run` 是 Docker 中用于启动容器的基本命令。常用子命令包括 `-i`(交互模式)、`-t`(分配终端)、`-d`(后台运行)、`-p`(端口映射)、`--name`(指定容器名)。例如,`docker run -it nginx:1.20 /bin/bash` 可以创建并进入交互式容器。使用 `-d` 可在后台运行容器,`-p` 可将容器端口映射到主机端口,`--name` 则用于自定义容器名称以便管理。

热门文章

最新文章