Skip to content

labvisio/is-face-detector

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

80 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Face Detector Service

Docker image tag Docker image size Docker pulls

Example Image

In a simplified manner, a service within the Intelligent Space is essentially a Python (or C++, and so on) application running within a Docker container, seamlessly orchestrated across a cluster of hosts using Kubernetes. This service detects faces in images, providing these detections in different ways.

About 😄

YuNet is a light-weight, fast and accurate face detection model, which achieves 0.834(AP_easy), 0.824(AP_medium), 0.708(AP_hard) on the WIDER Face validation set. See more

The model is downloaded using the script etc/model/download_models.sh.

Streams 📷

A stream is a program that consumes messages with a specific topic, processes them, and publishes messages in other topics, so if another service wants to use the informations provided by this service, it can simply subscribe to receive messages with the topic of interest. The python script responsible for the stream in the table below can be found in src/is_face_detector/stream.py.

Name ⇒ Input Output ⇒ Description
Face.Detection 📨 topic: CameraGateway.(camera_id).Frame
💎 schema: Image
📨 topic: FaceDetector.(camera_id).Detection
💎 schema: ObjectAnnotations
Detects face on images published by cameras and publishes an ObjectAnnotations message containing all the detected faces.
Face.Detection 📨 topic: CameraGateway.(camera_id).Frame
💎 schema: Image
📨 topic: FaceDetector.(camera_id).Rendered
💎 schema: Image
After detection, faces are drew on input image and published for visualization.
  • Note: run the is-face-detector-stream in container to use this function.

RPCs 📸

The RPC, or Remote Procedure Call, provided here acts as a remote server that binds a specific function to a topic. You can process an Image by sending the message to the topic of this service. It will be processed and you will receive a response, which can be the faces detected in an ObjectAnnotations, error, timeout, etc... The python script responsible for the RPC in the table below can be found in src/is_face_detector/rpc.py.

Service Request Reply Description
📨 topic: FaceDetector.Detect 💎 schema: Image 💎 schema: ObjectAnnotations Same purpose of stream shown above, but offered with a RPC server.
  • Note: run the is-face-detector-rpc in container to use this function.

Configuration ⚙️

The behavior of the service can be customized by passing a JSON configuration file as the first argument, e.g: is-face-detector-stream config.json. The schema for this file can be found in is_face_detector/conf/options.proto.

An example configuration file can be found in etc/conf/options.json.

Developing 🛠️

The project structure follows as:

.
├── etc
│   ├── conf
│   │   └── options.json
│   ├── docker
│   │   └── Dockerfile
│   ├── images
│   │   └── face.png
│   ├── k8s
│   │   └── deployment.yaml
│   └── model
│       └── download_models.sh
├── examples
│   └── request.py
├── is_face_detector
│   ├── conf
│   │   ├── __init__.py
│   │   ├── options_pb2.py
│   │   ├── options_pb2.pyi
│   │   └── options.proto
│   ├── detector.py
│   ├── __init__.py
│   ├── py.typed
│   ├── rpc.py
│   ├── stream_channel.py
│   ├── stream.py
│   └── utils.py
├── README.md
├── setup.cfg
└── setup.py

is-wire-py 📨

For a service to communicate with another, it uses a message-based protocol (AMQP) which depends of a broker to receive and deliver all messages (RabbitMQ).

A python package was developed to abstract the communication layer implementing a publish/subscribe middleware, know as is-wire-py. There you can find basic examples of message sending and receiving, or creating an RPC server, tracing messages, etc.

Protocol Buffer 💎

Every message on IS is standardized using Protocol Buffer. The schemas are defined at is-msgs.

In this project, Procol Buffers are also used to define the options that are going to be loaded during runtime. The program will parse a json into a Protocol Buffer Object and guarantee that it has a specific structure. You don't need do it this way if you don't want to, you can simply load the json as a dictionary during runtime.

Docker docker

To run the application into kubernetes platform, it must be packaged in the right format which is a docker container. A docker container can be initialized from a docker image, the instructions to build the docker image are at etc/docker/Dockerfile.

To be available to the kubernetes cluster, the docker image must be stored on dockerhub, to build the image locally and push to dockerhub:

docker build -f etc/docker/Dockerfile -t <user>/is-face-detector:<version> .
docker push <user>/is-face-detector:<version>

The docker image used here supports any application in python that uses OpenCV. Your application may not run because the image docker doesn't contain some library, in this case it will be necessary to edit the etc/docker/Dockerfile and rebuild it to install what you need or to use another base image.

Kubernetes k8s

Make sure you have kubectl installed and the right ~/.kube/config file to be able to interact with the cluster.

Deploy the stream application:

kubectl apply -f etc/k8s/deployment.yaml

The .yaml file describes two things:

  • a deployment;
  • a configmap;

A deployment is a way to run our application and guarantee that an N number of replicas will be running. The configmap allows load the options you desires when deploying into the kubernetes platform. See more about deployment and confimap.