face-rknn/README.md

547 lines
10 KiB
Markdown

# Face Recognition on Rockchip RK3588
Native C++ face detection and face recognition pipeline for Rockchip RK3588 devices using RKNN Runtime.
Validated on an Orange Pi 5 Plus with Rockchip RK3588.
## Pipeline
The pipeline combines:
- SCRFD 500M KPS face detector at 640x640
- 5-point facial landmarks
- SFace 2021 face recognition model
- RKNN Runtime 2.3.2
- Native C++ inference
- stb_image for image loading
- Cosine similarity for face comparison
The complete pipeline is:
```text
Image
|
v
stb_image
|
v
SCRFD 500M KPS 640
|
+--> face bounding boxes
|
+--> 5 facial landmarks
|
v
SFace alignment
112x112
|
v
SFace recognition
|
v
128-D embedding
|
v
L2 normalization
|
v
cosine similarity
```
## Repository Layout
```text
face-rknn-repo/
├── src/
│ └── face_recognition.cc
├── include/
│ ├── rknn_api.h
│ └── stb_image.h
├── models/
│ ├── onnx/
│ │ ├── SCRFD_500M_KPS_640.onnx
│ │ └── face_recognition_sface_2021dec.onnx
│ ├── rknn/
│ │ ├── SCRFD_500M_KPS_640.rknn
│ │ └── face_recognition_sface_2021dec.rknn
│ └── SHA256SUMS
├── tools/
│ └── conversion/
│ ├── convert_scrfd_rknn.py
│ └── convert_legacy.py
├── scripts/
│ ├── build.sh
│ └── test.sh
├── test/
│ └── test3f.jpg
├── runtime/
├── .gitignore
└── README.md
```
The runtime directory is intentionally empty in Git. The Rockchip vendor runtime library is installed separately on the target device.
## Tested Environment
### Target Device
- Orange Pi 5 Plus
- Rockchip RK3588
- ARM64 / aarch64
- Linux
- RKNN Runtime 2.3.2
Runtime version:
```text
librknnrt version: 2.3.2
```
Validated runtime library:
- version: 2.3.2
- size: 7,726,232 bytes
- MD5: a37ee1d5d664c79836bf6e35b7ef6289
The runtime library is not committed to this repository.
## Conversion Environment
Model conversion was performed on a Debian x86 system using:
```text
Python 3.11.2
RKNN Toolkit2 2.3.2
RKNN Toolkit2 commit: bd980be9
```
The Python virtual environment used for conversion was:
```text
/home/fabio/photo-ai/rknn-env
```
The virtual environment is not included in the repository.
# Models
## SCRFD 500M KPS
SCRFD is used for face detection and extraction of five facial landmarks.
ONNX model:
```text
models/onnx/SCRFD_500M_KPS_640.onnx
```
RKNN model:
```text
models/rknn/SCRFD_500M_KPS_640.rknn
```
Target platform:
```text
rk3588
```
Quantization:
```text
disabled
```
Conversion script:
```text
tools/conversion/convert_scrfd_rknn.py
```
## SFace
SFace is used to generate a 128-dimensional face embedding.
ONNX model:
```text
models/onnx/face_recognition_sface_2021dec.onnx
```
RKNN model:
```text
models/rknn/face_recognition_sface_2021dec.rknn
```
The RKNN model stored in this repository is the verified model used by the C++ application.
The exact historical conversion recipe for the SFace RKNN model was not completely preserved, therefore this repository does not claim that the SFace conversion is fully reproducible byte-for-byte.
# SCRFD Configuration
The SCRFD input is:
- 640x640
- RGB
- FP16
- NHWC
Image preprocessing:
- top-left letterbox
- aspect ratio preserved
- padding added to reach 640x640
- RGB channel order
Normalization:
```text
(pixel - 127.5) / 128
```
Detector configuration:
- strides: 8, 16, 32
- anchors per location: 2
- detection threshold: 0.50
- NMS IoU threshold: 0.45
The detector produces:
- bounding boxes
- confidence scores
- five facial landmarks
# SFace Configuration
The five canonical SFace landmarks are:
```text
(38.2946, 51.6963)
(73.5318, 51.5014)
(56.0252, 71.7366)
(41.5493, 92.3655)
(70.7299, 92.2041)
```
The detected face is aligned using these landmarks and warped to:
```text
112x112
```
SFace input:
- RGB
- uint8 image values represented as FP16 NHWC
- range 0..255
- pass_through=1
The output embedding has 128 dimensions.
The embedding is L2-normalized before comparison.
# C++ Application
The main application is:
```text
src/face_recognition.cc
```
The executable is:
```text
bin/face_recognition
```
The application expects two image paths:
```text
./bin/face_recognition image1.jpg image2.jpg
```
It detects faces in both images, extracts the corresponding embeddings and computes cosine similarity.
The current test application compares the first detected face in each image.
# Face Comparison
Face similarity is computed using cosine similarity between the two L2-normalized 128-dimensional embeddings.
The comparison threshold used by the current application is:
```text
0.363
```
A similarity above this threshold is considered a match by the current test application.
This threshold is part of the validated application configuration and should not be interpreted as a universal SFace threshold for every deployment or dataset.
## Self-Comparison Test
Comparing an image with itself produces:
```text
cosine similarity = 1.0
```
The reference test image:
```text
test/test3f.jpg
```
contains exactly three detected faces in the validated test.
# Build
The application is intended to be compiled on the ARM64/RK3588 target.
Build script:
```text
scripts/build.sh
```
Run:
```bash
./scripts/build.sh
```
The resulting executable is:
```text
bin/face_recognition
```
The executable is linked against the runtime library located in:
```text
runtime/librknnrt.so
```
The build uses an rpath relative to the executable:
```text
$ORIGIN/../runtime
```
This allows the application to use a repository-local runtime without requiring a system-wide installation.
# Test
The test script is:
```text
scripts/test.sh
```
Run the default self-comparison:
```bash
./scripts/test.sh
```
This uses:
```text
test/test3f.jpg
```
for both inputs.
Two explicit images can also be supplied:
```bash
./scripts/test.sh image1.jpg image2.jpg
```
# Model Integrity
SHA256 checksums for all committed models are stored in:
```text
models/SHA256SUMS
```
Verify the models with:
```bash
cd models
sha256sum -c SHA256SUMS
```
Expected result:
```text
face_recognition_sface_2021dec.onnx: OK
SCRFD_500M_KPS_640.onnx: OK
face_recognition_sface_2021dec.rknn: OK
SCRFD_500M_KPS_640.rknn: OK
```
Current SHA256 values:
```text
face_recognition_sface_2021dec.onnx
0ba9fbfa01b5270c96627c4ef784da859931e02f04419c829e83484087c34e79
SCRFD_500M_KPS_640.onnx
857efab2e0a5184ec86ffa7d0bf33ac94da92591e7650d5353622ce367218faf
face_recognition_sface_2021dec.rknn
5f36840c6fea8a4772a45fe5eb3456b7bd2031e2986947154fcbd165f918f2ec
SCRFD_500M_KPS_640.rknn
7d74abdedebc5fe25c98195db75cc915df74dd58d941be60c1c260186ac764e2
```
# Conversion
Model conversion was performed separately from the target runtime.
The repository contains the conversion scripts used for the validated SCRFD conversion and the historical generic conversion tooling.
## SCRFD Conversion
The SCRFD conversion script is:
```text
tools/conversion/convert_scrfd_rknn.py
```
Its essential configuration is:
```python
from rknn.api import RKNN
ONNX_MODEL = "SCRFD_500M_KPS_640.onnx"
RKNN_MODEL = "SCRFD_500M_KPS_640.rknn"
rknn = RKNN(verbose=True)
rknn.config(target_platform="rk3588")
rknn.load_onnx(model=ONNX_MODEL)
rknn.build(do_quantization=False)
rknn.export_rknn(RKNN_MODEL)
rknn.release()
```
The script expects the ONNX model in the current working directory.
## SFace Conversion
The repository includes:
```text
tools/conversion/convert_legacy.py
```
This is historical generic ONNX-to-RKNN conversion tooling.
The validated SFace RKNN model is committed to the repository, but the complete original conversion procedure, including all intermediate optimization steps and exact conversion inputs, was not fully preserved.
Therefore:
- the committed SFace RKNN model is reproducible as an artifact
- its SHA256 checksum is verified
- the exact original byte-for-byte conversion process is not claimed to be reproducible
# Reproducibility
The repository is intended to preserve the working state of the validated pipeline.
The following are versioned:
- C++ source
- RKNN API header
- stb_image header
- ONNX models
- RKNN models
- conversion scripts
- build script
- test script
- test image
- SHA256 checksums
- documentation
The following are intentionally not versioned:
- Python virtual environments
- build artifacts
- compiled executables
- shared libraries
- vendor runtime binaries
- temporary conversion files
- editor configuration
The target application can therefore be rebuilt on an ARM64/RK3588 system while keeping the validated model artifacts and source code under version control.
# Runtime Library
The Rockchip RKNN runtime is a vendor-provided binary.
The validated version is:
```text
2.3.2
```
The repository deliberately does not commit:
```text
librknnrt.so
```
The target device must provide a compatible RKNN Runtime installation or the runtime library must be placed locally in:
```text
runtime/librknnrt.so
```
The build system uses that local library when compiling.
# Third-Party Components
This project uses third-party components including:
- Rockchip RKNN Runtime
- Rockchip RKNN Toolkit2
- SCRFD
- SFace
- stb_image
Their respective licenses and redistribution terms remain applicable.
This repository does not claim ownership of those third-party components.
# License
The application source in this repository should be considered project-specific code.
Third-party components, models, headers and runtime libraries remain subject to their original licenses and terms.
Before redistributing the complete repository or its models, verify the applicable licenses and redistribution permissions for each third-party component.
# Status
Current validated status:
- SCRFD RKNN inference: working
- SFace RKNN inference: working
- Face landmark extraction: working
- Face alignment: working
- 128-D embedding generation: working
- L2 normalization: working
- Cosine similarity: working
- Self-comparison: cosine similarity 1.0
- Three-face test image: validated
- ARM64/RK3588 native C++ application: working
- Local RKNN runtime loading: working
- Model SHA256 verification: working
The repository represents the validated working baseline of the RK3588 face-recognition pipeline.