Skip to content

Commit b3fd0aa

Browse files
authored
Merge pull request #73 from HyperInspire/dev/attribute
Dev/attribute Former-commit-id: dcc4d87
2 parents 7a87e82 + bb69176 commit b3fd0aa

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

62 files changed

+868
-314
lines changed
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
# This GitHub Actions workflow is designed for a CMake project running on a single platform (Ubuntu-x86).
2+
# For multi-platform testing, see the link provided.
3+
# Refer to: https://github.com/actions/starter-workflows/blob/main/ci/cmake-multi-platform.yml
4+
name: Run Ubuntu-x86 Test Pikachu from Python Native
5+
6+
# Trigger this workflow on push or pull request to the "feature/sub" branch
7+
on:
8+
push:
9+
branches: ["master"]
10+
pull_request:
11+
branches: ["master"]
12+
13+
# Define environment variables shared across jobs
14+
env:
15+
# Set the CMake build type (e.g., Release, Debug, RelWithDebInfo, etc.)
16+
BUILD_TYPE: Release
17+
18+
# Jobs section defines all individual tasks for the CI workflow
19+
jobs:
20+
build:
21+
# Specify that this job should run on the latest Ubuntu environment provided by GitHub
22+
runs-on: ubuntu-latest
23+
24+
# Define steps for this job
25+
steps:
26+
# Step 1: Check out the code from the repository
27+
- uses: actions/checkout@v4
28+
29+
# Step 2: Update Git submodules recursively
30+
- name: Update submodules
31+
run: |
32+
git clone --recurse-submodules https://github.com/HyperInspire/3rdparty.git
33+
34+
# Step 3: Install necessary dependencies for building the CMake project
35+
- name: Install dependencies
36+
run: |
37+
sudo apt-get update # Update package lists
38+
# Install build tools and required libraries for video processing
39+
sudo apt-get install -y build-essential libgtk-3-dev libavcodec-dev libavformat-dev libjpeg-dev libswscale-dev
40+
41+
# Step 4: Run a separate script for CMake configuration and building
42+
- name: Download Dataset And Configure CMake
43+
# Execute a pre-existing script to handle CMake configuration and building
44+
# The script is assumed to be located at `ci/quick_test_linux_x86_usual.sh`
45+
run: bash ci/quick_test_linux_x86_usual_python_native_interface.sh

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3")
99
# Current version
1010
set(INSPIRE_FACE_VERSION_MAJOR 1)
1111
set(INSPIRE_FACE_VERSION_MINOR 1)
12-
set(INSPIRE_FACE_VERSION_PATCH 3)
12+
set(INSPIRE_FACE_VERSION_PATCH 4)
1313

1414
# Converts the version number to a string
1515
string(CONCAT INSPIRE_FACE_VERSION_MAJOR_STR ${INSPIRE_FACE_VERSION_MAJOR})

README.md

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# InspireFace
22
[![GitHub release](https://img.shields.io/github/v/release/HyperInspire/InspireFace.svg?style=for-the-badge&color=blue)](https://github.com/HyperInspire/InspireFace/releases/latest)
33
[![build](https://img.shields.io/github/actions/workflow/status/HyperInspire/InspireFace/release-sdks.yaml?&style=for-the-badge&label=build)](https://img.shields.io/github/actions/workflow/status/HyperInspire/InspireFace/release-sdks.yaml?&style=for-the-badge&label=build)
4+
[![test](https://img.shields.io/github/actions/workflow/status/HyperInspire/InspireFace/release-sdks.yaml?&style=for-the-badge&label=test)](https://img.shields.io/github/actions/workflow/status/HyperInspire/InspireFace/test_ubuntu_x86_Pikachu.yaml?&style=for-the-badge&label=test)
45

56
InspireFace is a cross-platform face recognition SDK developed in C/C++, supporting multiple operating systems and various backend types for inference, such as CPU, GPU, and NPU.
67

@@ -10,6 +11,10 @@ Please contact [contact@insightface.ai](mailto:contact@insightface.ai?subject=In
1011

1112
## Change Logs
1213

14+
**`2024-07-05`** Fixed some bugs in the python ctypes interface.
15+
16+
**`2024-07-03`** Add the blink detection algorithm of face interaction module.
17+
1318
**`2024-07-02`** Fixed several bugs in the face detector with multi-level input.
1419

1520
**`2024-06-27`** Verified iOS usability and fixed some bugs.
@@ -52,7 +57,7 @@ You can download the model package files containing models and configurations ne
5257
If you intend to use the SDK locally or on a server, ensure that OpenCV is installed on the host device beforehand to enable successful linking during the compilation process. For cross-compilation targets like Android or ARM embedded boards, you can use the pre-compiled OpenCV libraries provided by **3rdparty/inspireface-precompile/opencv/**.
5358

5459
### 1.4. Installing MNN
55-
The '3rdparty' directory already includes the MNN library and specifies a particular version as the stable version. If you need to enable or disable additional configuration options during compilation, you can refer to the CMake Options provided by MNN. If you need to use your own precompiled version, feel free to replace it.
60+
The '**3rdparty**' directory already includes the MNN library and specifies a particular version as the stable version. If you need to enable or disable additional configuration options during compilation, you can refer to the CMake Options provided by MNN. If you need to use your own precompiled version, feel free to replace it.
5661

5762
### 1.5. Requirements
5863

@@ -298,14 +303,14 @@ In the project, there is a subproject called cpp/test. To compile it, you need t
298303
```bash
299304
cmake -DISF_BUILD_WITH_TEST=ON ..
300305
```
301-
If you need to run test cases, you will need to download the required [resource files](https://drive.google.com/file/d/1i4uC-dZTQxdVgn2rP0ZdfJTMkJIXgYY4/view?usp=sharing), which are **test_res** and **Model Package** respectively. Unzip the pack file into the test_res folder. The directory structure of test_res should be prepared as follows before testing:
306+
If you need to run test cases, you will need to download the required [resource files](https://drive.google.com/file/d/1i4uC-dZTQxdVgn2rP0ZdfJTMkJIXgYY4/view?usp=sharing): **test_res**. Unzip the test_res folder. The directory structure of test_res should be prepared as follows before testing:
302307

303308
```bash
304309

305310
test_res
306311
├── data
307312
├── images
308-
├── pack <- unzip pack.zip
313+
├── pack <-- The model package files are here
309314
├── save
310315
├── valid_lfw_funneled.txt
311316
├── video
@@ -352,17 +357,17 @@ The following functionalities and technologies are currently supported.
352357
| 6 | Silent Liveness Detection | ![Static Badge](https://img.shields.io/badge/STABLE-blue?style=for-the-badge) | MiniVision |
353358
| 7 | Face Quality Detection | ![Static Badge](https://img.shields.io/badge/STABLE-blue?style=for-the-badge) | |
354359
| 8 | Face Pose Estimation | ![Static Badge](https://img.shields.io/badge/STABLE-blue?style=for-the-badge) | |
355-
| 9 | Age Prediction | ![Static Badge](https://img.shields.io/badge/PENDING-yellow?style=for-the-badge) | |
356-
| 10 | Cooperative Liveness Detection | ![Static Badge](https://img.shields.io/badge/PENDING-yellow?style=for-the-badge) | |
360+
| 9 | Face Attribute Prediction | ![Static Badge](https://img.shields.io/badge/STABLE-blue?style=for-the-badge) | Age, Race, Gender |
361+
| 10 | Cooperative Liveness Detection | ![Static Badge](https://img.shields.io/badge/DEVELOP-green?style=for-the-badge) | Blink |
357362

358363

359364
## 6. Models Package List
360365

361-
For different scenarios, we currently provide several Packs, each containing multiple models and configurations.
366+
For different scenarios, we currently provide several Packs, each containing multiple models and configurations.The package file is placed in the **pack** subdirectory under the **test_res** directory.
362367

363368
| Name | Supported Devices | Note | Link |
364369
| --- | --- | --- | --- |
365-
| Pikachu | CPU | Lightweight edge-side model | [GDrive](https://drive.google.com/drive/folders/1krmv9Pj0XEZXR1GRPHjW_Sl7t4l0dNSS?usp=sharing) |
366-
| Megatron | CPU, GPU | Local or server-side model | [GDrive](https://drive.google.com/drive/folders/1krmv9Pj0XEZXR1GRPHjW_Sl7t4l0dNSS?usp=sharing) |
370+
| Pikachu | CPU | Lightweight edge-side models | [GDrive](https://drive.google.com/drive/folders/1krmv9Pj0XEZXR1GRPHjW_Sl7t4l0dNSS?usp=sharing) |
371+
| Megatron | CPU, GPU | Mobile and server models | [GDrive](https://drive.google.com/drive/folders/1krmv9Pj0XEZXR1GRPHjW_Sl7t4l0dNSS?usp=sharing) |
367372
| Gundam-RV1109 | RKNPU | Supports RK1109 and RK1126 | [GDrive](https://drive.google.com/drive/folders/1krmv9Pj0XEZXR1GRPHjW_Sl7t4l0dNSS?usp=sharing) |
368373

ci/quick_test_linux_x86_usual.sh

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,14 @@ cmake -DCMAKE_BUILD_TYPE=Release \
5454
# Compile the project using 4 parallel jobs
5555
make -j4
5656

57-
# Create a symbolic link to the extracted test data directory
58-
ln -s ${FULL_TEST_DIR} .
57+
# Check if the symbolic link or directory already exists
58+
if [ ! -e "$(basename ${FULL_TEST_DIR})" ]; then
59+
# Create a symbolic link to the extracted test data directory
60+
ln -s ${FULL_TEST_DIR} .
61+
echo "Symbolic link to '${TARGET_DIR}' created."
62+
else
63+
echo "Symbolic link or directory '$(basename ${FULL_TEST_DIR})' already exists. Skipping creation."
64+
fi
5965

6066
# Check if the test executable file exists
6167
if [ ! -f "$TEST_EXECUTABLE" ]; then
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
#!/bin/bash
2+
3+
# Exit immediately if any command exits with a non-zero status
4+
set -e
5+
6+
ROOT_DIR="$(pwd)"
7+
TARGET_DIR="test_res"
8+
DOWNLOAD_URL="https://github.com/tunmx/inspireface-store/raw/main/resource/test_res-lite.zip"
9+
ZIP_FILE="test_res-lite.zip"
10+
BUILD_DIRNAME="ubuntu18_shared"
11+
12+
# Check if the target directory already exists
13+
if [ ! -d "$TARGET_DIR" ]; then
14+
echo "Directory '$TARGET_DIR' does not exist. Downloading..."
15+
16+
# Download the dataset zip file
17+
wget -q "$DOWNLOAD_URL" -O "$ZIP_FILE"
18+
19+
echo "Extracting '$ZIP_FILE' to '$TARGET_DIR'..."
20+
# Unzip the downloaded file
21+
unzip "$ZIP_FILE"
22+
23+
# Remove the downloaded zip file and unnecessary folders
24+
rm "$ZIP_FILE"
25+
rm -rf "__MACOSX"
26+
27+
echo "Download and extraction complete."
28+
else
29+
echo "Directory '$TARGET_DIR' already exists. Skipping download."
30+
fi
31+
32+
# Get the absolute path of the target directory
33+
FULL_TEST_DIR="$(realpath ${TARGET_DIR})"
34+
35+
# Create the build directory if it doesn't exist
36+
mkdir -p build/${BUILD_DIRNAME}/
37+
38+
# Change directory to the build directory
39+
# Disable the shellcheck warning for potential directory changes
40+
# shellcheck disable=SC2164
41+
cd build/${BUILD_DIRNAME}/
42+
43+
# Configure the CMake build system
44+
cmake -DCMAKE_BUILD_TYPE=Release \
45+
-DISF_BUILD_WITH_SAMPLE=OFF \
46+
-DISF_BUILD_WITH_TEST=OFF \
47+
-DISF_ENABLE_BENCHMARK=OFF \
48+
-DISF_ENABLE_USE_LFW_DATA=OFF \
49+
-DISF_ENABLE_TEST_EVALUATION=OFF \
50+
-DOpenCV_DIR=3rdparty/inspireface-precompile/opencv/4.5.1/opencv-ubuntu18-x86/lib/cmake/opencv4 \
51+
-DISF_BUILD_SHARED_LIBS=ON ../../
52+
53+
# Compile the project using 4 parallel jobs
54+
make -j4
55+
56+
# Come back to project root dir
57+
cd ${ROOT_DIR}
58+
59+
# Important: You must copy the compiled dynamic library to this path!
60+
cp build/${BUILD_DIRNAME}/lib/libInspireFace.so python/inspireface/modules/core/
61+
62+
# Install dependency
63+
pip install opencv-python
64+
pip install click
65+
pip install loguru
66+
67+
cd python/
68+
69+
# Run sample
70+
python sample_face_detection.py ../test_res/pack/Pikachu ../test_res/data/bulk/woman.png
71+

ci/quick_test_local.sh

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,3 +66,5 @@ else
6666
echo "Test executable found. Running tests..."
6767
"$TEST_EXECUTABLE"
6868
fi
69+
70+
# Executing python scripts

cpp/inspireface/c_api/inspireface.cc

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -100,13 +100,13 @@ HResult HFReleaseInspireFaceSession(HFSession handle) {
100100
HResult HFCreateInspireFaceSession(HFSessionCustomParameter parameter, HFDetectMode detectMode, HInt32 maxDetectFaceNum, HInt32 detectPixelLevel, HInt32 trackByDetectModeFPS, HFSession *handle) {
101101
inspire::ContextCustomParameter param;
102102
param.enable_mask_detect = parameter.enable_mask_detect;
103-
param.enable_age = parameter.enable_age;
103+
param.enable_face_attribute = parameter.enable_face_quality;
104104
param.enable_liveness = parameter.enable_liveness;
105105
param.enable_face_quality = parameter.enable_face_quality;
106-
param.enable_gender = parameter.enable_gender;
107106
param.enable_interaction_liveness = parameter.enable_interaction_liveness;
108107
param.enable_ir_liveness = parameter.enable_ir_liveness;
109108
param.enable_recognition = parameter.enable_recognition;
109+
param.enable_face_attribute = parameter.enable_face_attribute;
110110
inspire::DetectMode detMode = inspire::DETECT_MODE_ALWAYS_DETECT;
111111
if (detectMode == HF_DETECT_MODE_LIGHT_TRACK) {
112112
detMode = inspire::DETECT_MODE_LIGHT_TRACK;
@@ -138,11 +138,8 @@ HResult HFCreateInspireFaceSessionOptional(HOption customOption, HFDetectMode de
138138
if (customOption & HF_ENABLE_IR_LIVENESS) {
139139
param.enable_ir_liveness = true;
140140
}
141-
if (customOption & HF_ENABLE_AGE_PREDICT) {
142-
param.enable_age = true;
143-
}
144-
if (customOption & HF_ENABLE_GENDER_PREDICT) {
145-
param.enable_gender = true;
141+
if (customOption & HF_ENABLE_FACE_ATTRIBUTE) {
142+
param.enable_face_attribute = true;
146143
}
147144
if (customOption & HF_ENABLE_MASK_DETECT) {
148145
param.enable_mask_detect = true;
@@ -508,13 +505,13 @@ HResult HFMultipleFacePipelineProcess(HFSession session, HFImageStream streamHan
508505
}
509506
inspire::ContextCustomParameter param;
510507
param.enable_mask_detect = parameter.enable_mask_detect;
511-
param.enable_age = parameter.enable_age;
508+
param.enable_face_attribute = parameter.enable_face_quality;
512509
param.enable_liveness = parameter.enable_liveness;
513510
param.enable_face_quality = parameter.enable_face_quality;
514-
param.enable_gender = parameter.enable_gender;
515511
param.enable_interaction_liveness = parameter.enable_interaction_liveness;
516512
param.enable_ir_liveness = parameter.enable_ir_liveness;
517513
param.enable_recognition = parameter.enable_recognition;
514+
param.enable_face_attribute = parameter.enable_face_attribute;
518515

519516
HResult ret;
520517
std::vector<inspire::HyperFaceData> data;
@@ -562,11 +559,8 @@ HResult HFMultipleFacePipelineProcessOptional(HFSession session, HFImageStream s
562559
if (customOption & HF_ENABLE_IR_LIVENESS) {
563560
param.enable_ir_liveness = true;
564561
}
565-
if (customOption & HF_ENABLE_AGE_PREDICT) {
566-
param.enable_age = true;
567-
}
568-
if (customOption & HF_ENABLE_GENDER_PREDICT) {
569-
param.enable_gender = true;
562+
if (customOption & HF_ENABLE_FACE_ATTRIBUTE) {
563+
param.enable_face_attribute = true;
570564
}
571565
if (customOption & HF_ENABLE_MASK_DETECT) {
572566
param.enable_mask_detect = true;
@@ -675,6 +669,23 @@ HResult HFGetFaceIntereactionResult(HFSession session, PHFFaceIntereactionResult
675669
return HSUCCEED;
676670
}
677671

672+
HResult HFGetFaceAttributeResult(HFSession session, PHFFaceAttributeResult results) {
673+
if (session == nullptr) {
674+
return HERR_INVALID_CONTEXT_HANDLE;
675+
}
676+
HF_FaceAlgorithmSession *ctx = (HF_FaceAlgorithmSession* ) session;
677+
if (ctx == nullptr) {
678+
return HERR_INVALID_CONTEXT_HANDLE;
679+
}
680+
681+
results->num = ctx->impl.GetFaceAgeBracketResultsCache().size();
682+
results->race = (HPInt32 )ctx->impl.GetFaceRaceResultsCache().data();
683+
results->gender = (HPInt32 )ctx->impl.GetFaceGenderResultsCache().data();
684+
results->ageBracket = (HPInt32 )ctx->impl.GetFaceAgeBracketResultsCache().data();
685+
686+
return HSUCCEED;
687+
}
688+
678689
HResult HFFeatureHubGetFaceCount(HInt32* count) {
679690
*count = FEATURE_HUB->GetFaceFeatureCount();
680691
return HSUCCEED;

cpp/inspireface/c_api/inspireface.h

Lines changed: 45 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@ extern "C" {
2929
#define HF_ENABLE_LIVENESS 0x00000004 ///< Flag to enable RGB liveness detection feature.
3030
#define HF_ENABLE_IR_LIVENESS 0x00000008 ///< Flag to enable IR (Infrared) liveness detection feature.
3131
#define HF_ENABLE_MASK_DETECT 0x00000010 ///< Flag to enable mask detection feature.
32-
#define HF_ENABLE_AGE_PREDICT 0x00000020 ///< Flag to enable age prediction feature.
33-
#define HF_ENABLE_GENDER_PREDICT 0x00000040 ///< Flag to enable gender prediction feature.
32+
#define HF_ENABLE_FACE_ATTRIBUTE 0x00000020 ///< Flag to enable face attribute prediction feature.
33+
#define HF_ENABLE_PLACEHOLDER_ 0x00000040 ///< -
3434
#define HF_ENABLE_QUALITY 0x00000080 ///< Flag to enable face quality assessment feature.
3535
#define HF_ENABLE_INTERACTION 0x00000100 ///< Flag to enable interaction feature.
3636

@@ -125,9 +125,8 @@ typedef struct HFSessionCustomParameter {
125125
HInt32 enable_liveness; ///< Enable RGB liveness detection feature.
126126
HInt32 enable_ir_liveness; ///< Enable IR liveness detection feature.
127127
HInt32 enable_mask_detect; ///< Enable mask detection feature.
128-
HInt32 enable_age; ///< Enable age prediction feature.
129-
HInt32 enable_gender; ///< Enable gender prediction feature.
130128
HInt32 enable_face_quality; ///< Enable face quality detection feature.
129+
HInt32 enable_face_attribute; ///< Enable face attribute prediction feature.
131130
HInt32 enable_interaction_liveness; ///< Enable interaction for liveness detection feature.
132131
} HFSessionCustomParameter, *PHFSessionCustomParameter;
133132

@@ -149,7 +148,7 @@ typedef enum HFDetectMode {
149148
* @param detectMode Detection mode to be used.
150149
* @param maxDetectFaceNum Maximum number of faces to detect.
151150
* @param detectPixelLevel Modify the input resolution level of the detector, the larger the better,
152-
* the need to input a multiple of 160, such as 160, 320, 640, the default value -1 is 160.
151+
* the need to input a multiple of 160, such as 160, 320, 640, the default value -1 is 320.
153152
* @param trackByDetectModeFPS If you are using the MODE_TRACK_BY_DETECTION tracking mode,
154153
* this value is used to set the fps frame rate of your current incoming video stream, which defaults to -1 at 30fps.
155154
* @param handle Pointer to the context handle that will be returned.
@@ -647,6 +646,47 @@ typedef struct HFFaceIntereactionResult {
647646

648647
HYPER_CAPI_EXPORT extern HResult HFGetFaceIntereactionResult(HFSession session, PHFFaceIntereactionResult result);
649648

649+
/**
650+
* @brief Struct representing face attribute results.
651+
*
652+
* This struct holds the race, gender, and age bracket attributes for a detected face.
653+
*/
654+
typedef struct HFFaceAttributeResult {
655+
HInt32 num; ///< Number of faces detected.
656+
HPInt32 race; ///< Race of the detected face.
657+
///< 0: Black;
658+
///< 1: Asian;
659+
///< 2: Latino/Hispanic;
660+
///< 3: Middle Eastern;
661+
///< 4: White;
662+
HPInt32 gender; ///< Gender of the detected face.
663+
///< 0: Female;
664+
///< 1: Male;
665+
HPInt32 ageBracket; ///< Age bracket of the detected face.
666+
///< 0: 0-2 years old;
667+
///< 1: 3-9 years old;
668+
///< 2: 10-19 years old;
669+
///< 3: 20-29 years old;
670+
///< 4: 30-39 years old;
671+
///< 5: 40-49 years old;
672+
///< 6: 50-59 years old;
673+
///< 7: 60-69 years old;
674+
///< 8: more than 70 years old;
675+
} HFFaceAttributeResult, *PHFFaceAttributeResult;
676+
677+
/**
678+
* @brief Get the face attribute results.
679+
*
680+
* This function retrieves the attribute results such as race, gender, and age bracket
681+
* for faces detected in the current context.
682+
*
683+
* @param session Handle to the session.
684+
* @param results Pointer to the structure where face attribute results will be stored.
685+
* @return HResult indicating the success or failure of the operation.
686+
*/
687+
HYPER_CAPI_EXPORT extern HResult HFGetFaceAttributeResult(HFSession session, PHFFaceAttributeResult results);
688+
689+
650690
/************************************************************************
651691
* System Function
652692
************************************************************************/

0 commit comments

Comments
 (0)