diff --git a/cpp-package/inspireface/.gitignore b/cpp-package/inspireface/.gitignore
index 0f997e9..1619271 100644
--- a/cpp-package/inspireface/.gitignore
+++ b/cpp-package/inspireface/.gitignore
@@ -19,7 +19,7 @@ pack/*
.vscode/*
build_local/*
local_build/*
-cpp/inspireface/information.h
+cpp/inspireface/include/inspireface/information.h
cpp/inspireface/version.txt
.DS_Store
._.DS_Store
diff --git a/cpp-package/inspireface/CMakeLists.txt b/cpp-package/inspireface/CMakeLists.txt
index 567069e..fd01d09 100644
--- a/cpp-package/inspireface/CMakeLists.txt
+++ b/cpp-package/inspireface/CMakeLists.txt
@@ -1,4 +1,4 @@
-cmake_minimum_required(VERSION 3.10)
+cmake_minimum_required(VERSION 3.20)
project(InspireFace)
set(CMAKE_CXX_STANDARD 14)
@@ -7,16 +7,30 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3")
+# Hide symbols
+option(ISF_ENABLE_SYMBOL_HIDING "Enable symbol hiding." ON)
+if(ISF_ENABLE_SYMBOL_HIDING)
+ if(NOT WIN32)
+ set(CMAKE_C_VISIBILITY_PRESET hidden)
+ set(CMAKE_CXX_VISIBILITY_PRESET hidden)
+ set(CMAKE_VISIBILITY_INLINES_HIDDEN YES)
+ endif()
+else()
+ set(CMAKE_C_VISIBILITY_PRESET default)
+ set(CMAKE_CXX_VISIBILITY_PRESET default)
+ set(CMAKE_VISIBILITY_INLINES_HIDDEN NO)
+endif()
+
# Current version
set(INSPIRE_FACE_VERSION_MAJOR 1)
set(INSPIRE_FACE_VERSION_MINOR 2)
-set(INSPIRE_FACE_VERSION_PATCH 0)
+set(INSPIRE_FACE_VERSION_PATCH 1)
# Converts the version number to a string
string(CONCAT INSPIRE_FACE_VERSION_MAJOR_STR ${INSPIRE_FACE_VERSION_MAJOR})
string(CONCAT INSPIRE_FACE_VERSION_MINOR_STR ${INSPIRE_FACE_VERSION_MINOR})
string(CONCAT INSPIRE_FACE_VERSION_PATCH_STR ${INSPIRE_FACE_VERSION_PATCH})
-configure_file(${CMAKE_CURRENT_SOURCE_DIR}/cpp/inspireface/information.h.in ${CMAKE_CURRENT_SOURCE_DIR}/cpp/inspireface/information.h)
+configure_file(${CMAKE_CURRENT_SOURCE_DIR}/cpp/inspireface/information.h.in ${CMAKE_CURRENT_SOURCE_DIR}/cpp/inspireface/include/inspireface/information.h)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/cpp/inspireface/version.txt.in ${CMAKE_CURRENT_SOURCE_DIR}/cpp/inspireface/version.txt)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/python/version.txt.in ${CMAKE_CURRENT_SOURCE_DIR}/python/version.txt)
@@ -40,6 +54,9 @@ else()
message(STATUS "3rdparty directory already exists")
endif()
+# Install cpp api header file
+option(ISF_INSTALL_CPP_HEADER "Install cpp api header file." ON)
+
# Set the ISF_THIRD_PARTY_DIR variable to allow it to be set externally from the command line, or use the default path if it is not set
set(ISF_THIRD_PARTY_DIR "${CMAKE_CURRENT_SOURCE_DIR}/3rdparty" CACHE PATH "Path to the third-party libraries directory")
@@ -214,13 +231,11 @@ if(ISF_ENABLE_OPENCV)
if (ISF_BUILD_LINUX_ARM7 OR ISF_BUILD_LINUX_AARCH64)
set(DISABLE_GUI ON)
add_definitions("-DDISABLE_GUI")
- # set(OpenCV_DIR ${ISF_THIRD_PARTY_DIR}/opencv/opencv-linux-armhf/share/OpenCV)
- # set(OpenCV_STATIC_INCLUDE_DIR ${PATH_3RDPARTY}/opencv/opencv-linux-armhf/include/)
if (ISF_RK_DEVICE_TYPE STREQUAL "RV1109RV1126" AND ISF_ENABLE_RKNN)
# In special cases, specialize for that version
message("The OpenCV that builds the RV1109RV1126 version depends on is specialized!")
- set(OpenCV_DIR ${ISF_THIRD_PARTY_DIR}/inspireface-precompile/opencv/3.4.5/opencv-linux-armhf/share/OpenCV)
- set(OpenCV_STATIC_INCLUDE_DIR ${PATH_3RDPARTY}/inspireface-precompile/opencv/3.4.5/opencv-linux-armhf/include/)
+ set(OpenCV_DIR ${OPENCV_PRECOMPILED_DIR}/opencv/3.4.5/opencv-linux-armhf/share/OpenCV)
+ set(OpenCV_STATIC_INCLUDE_DIR ${OPENCV_PRECOMPILED_DIR}/opencv/3.4.5/opencv-linux-armhf/include/)
set(PLAT linux-arm7)
else()
if (VERSION_MAJOR STREQUAL "3")
@@ -231,13 +246,13 @@ if(ISF_ENABLE_OPENCV)
if(ISF_BUILD_LINUX_ARM7)
set(PLAT linux-arm7)
message("The OpenCV that builds the gnueabihf version depends on is specialized!")
- set(OpenCV_DIR ${ISF_THIRD_PARTY_DIR}/inspireface-precompile/opencv/3.4.5/opencv-linux-armhf/share/OpenCV)
- set(OpenCV_STATIC_INCLUDE_DIR ${PATH_3RDPARTY}/inspireface-precompile/opencv/3.4.5/opencv-linux-armhf/include/)
+ set(OpenCV_DIR ${OPENCV_PRECOMPILED_DIR}/opencv/3.4.5/opencv-linux-armhf/share/OpenCV)
+ set(OpenCV_STATIC_INCLUDE_DIR ${OPENCV_PRECOMPILED_DIR}/opencv/3.4.5/opencv-linux-armhf/include/)
elseif(ISF_BUILD_LINUX_AARCH64)
set(PLAT linux-aarch64)
message("The OpenCV that builds the aarch64 version depends on is specialized!")
- set(OpenCV_DIR ${ISF_THIRD_PARTY_DIR}/inspireface-precompile/opencv/3.4.5/opencv-linux-aarch64/share/OpenCV)
- set(OpenCV_STATIC_INCLUDE_DIR ${PATH_3RDPARTY}/inspireface-precompile/opencv/3.4.5/opencv-linux-aarch64/include/)
+ set(OpenCV_DIR ${OPENCV_PRECOMPILED_DIR}/opencv/3.4.5/opencv-linux-aarch64/share/OpenCV)
+ set(OpenCV_STATIC_INCLUDE_DIR ${OPENCV_PRECOMPILED_DIR}/opencv/3.4.5/opencv-linux-aarch64/include/)
endif()
endif()
else ()
@@ -350,4 +365,10 @@ if(ISF_ENABLE_APPLE_EXTENSION)
message(STATUS "\t ISF_ENABLE_APPLE_EXTENSION: ${ISF_ENABLE_APPLE_EXTENSION}")
endif()
+# Install cpp api header file
+if(ISF_INSTALL_CPP_HEADER)
+ message(STATUS "\t ISF_INSTALL_CPP_HEADER: ${ISF_INSTALL_CPP_HEADER}")
+endif()
+
+
message(STATUS "\t CMAKE_INSTALL_PREFIX: ${CMAKE_INSTALL_PREFIX}")
diff --git a/cpp-package/inspireface/README.md b/cpp-package/inspireface/README.md
index 37990c9..6405b0f 100644
--- a/cpp-package/inspireface/README.md
+++ b/cpp-package/inspireface/README.md
@@ -5,6 +5,8 @@
[](https://jitpack.io/#HyperInspire/inspireface-android-sdk)
[](https://github.com/HyperInspire/InspireFace/actions/workflows/release-sdks.yaml)
[](https://github.com/HyperInspire/InspireFace/actions/workflows/test_ubuntu_x86_Pikachu.yaml)
+[](https://doc.inspireface.online/)
+
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.
@@ -15,8 +17,15 @@ Please contact [contact@insightface.ai](mailto:contact@insightface.ai?subject=In
+---
+
+📘 [Documentation](https://doc.inspireface.online/) is a **work in progress**.
+We welcome your questions💬, they help guide and accelerate its development.
+
## Change Logs
+**`2025-04-27`** Optimize some issues and provide a stable version.
+
**`2025-03-16`** Acceleration using NVIDIA-GPU (**CUDA**) devices is already supported.
**`2025-03-09`** Release of android sdk in JitPack.
@@ -49,26 +58,18 @@ Please contact [contact@insightface.ai](mailto:contact@insightface.ai?subject=In
**`2024-07-02`** Fixed several bugs in the face detector with multi-level input.
-**`2024-06-27`** Verified iOS usability and fixed some bugs.
-
-**`2024-06-18`** Added face detection feature with tracking-by-detection mode.
-
-
## License
The licensing of the open-source models employed by InspireFace adheres to the same requirements as InsightFace, specifying their use solely for academic purposes and explicitly prohibiting commercial applications.
-
## Quick Start
-For Python users on Linux and MacOS, InspireFace can be quickly installed via pip:
+For Python users on **Linux and MacOS**, InspireFace can be quickly installed via pip:
```bash
pip install inspireface
```
-_⚠️Windows support is **not available yet**, but will be coming soon!_
-
After installation, you can use inspireface like this:
```Python
@@ -176,7 +177,7 @@ The '**3rdparty**' directory already includes the MNN library and specifies a pa
### Requirements
-- CMake (version 3.10 or higher)
+- CMake (version 3.20 or higher)
- NDK (version 16 or higher, only required for Android) [**Optional**]
- MNN (version 1.4.0 or higher)
- C++ Compiler
@@ -210,7 +211,10 @@ After compilation, you can find the local file in the build directory, which con
inspireface-linux
├── include
│ ├── herror.h
- │ └── inspireface.h
+ │ ├── intypedef.h
+ │ ├── inspireface.h
+ │ ├── inspirecv/
+ │ └── inspireface/
└── lib
└── libInspireFace.so
```
@@ -218,6 +222,9 @@ inspireface-linux
- **libInspireFace.so**:Compiled dynamic linking library.
- **inspireface.h**:Header file definition.
- **herror.h**:Reference error number definition.
+- **intypedef.h**: Type definition file.
+- **inspirecv**: Simple cv library CPP header file folder.
+- **inspireface**: inspireface cpp header folder.
### Cross Compilation
Cross compilation requires you to prepare the target platform's cross-compilation toolchain on the host machine in advance. Here, compiling for Rockchip's embedded devices RV1106 is used as an example:
```bash
@@ -272,6 +279,10 @@ docker-compose up build-tensorrt-cuda12-ubuntu22
If you want to use pre-compiled libraries, you can use **[FindTensorRT.cmake](toolchain/FindTensorRT.cmake)** to create links to CUDA and TensorRT.
+### React Native
+
+For Android and iOS, in addition to the native interface, you can use the React Native library powered by Nitro Modules and JSI—providing ultra-fast, seamless bindings to the InspireFace SDK. For more details, check out the [react-native-nitro-inspire-face](https://github.com/ronickg/react-native-nitro-inspire-face) repository or the [documentation](https://ronickg.github.io/react-native-nitro-inspire-face). Author: ronickg.
+
### Supported Platforms and Architectures
We have completed the adaptation and testing of the software across various operating systems and CPU architectures. This includes compatibility verification for platforms such as Linux, macOS, iOS, and Android, as well as testing for specific hardware support to ensure stable operation in diverse environments.
@@ -292,10 +303,11 @@ We have completed the adaptation and testing of the software across various oper
| 12 | **iOS** | ARM | CPU/Metal/**ANE** | [](#) | [](#) | [](https://github.com/HyperInspire/InspireFace/actions/workflows/release-sdks.yaml) |
| 13 | **Android** | ARMv7 | - | [](#) | [](#) | [](https://github.com/HyperInspire/InspireFace/actions/workflows/release-sdks.yaml) |
| 14 | | ARMv8 | - | [](#) | [](#) | [](https://github.com/HyperInspire/InspireFace/actions/workflows/release-sdks.yaml) |
-| 15 | **Android**
(Rockchip) | ARMv8 | RK3566/RK3568 | [](#) | [](#) | [](https://github.com/HyperInspire/InspireFace/actions/workflows/release-sdks.yaml) |
-| 16 | | ARMv8 | RK3588 | [](#) | [](#) | [](https://github.com/HyperInspire/InspireFace/actions/workflows/release-sdks.yaml) |
-| 17 | **HarmonyOS** | ARMv8 | - | - | - | - |
-| 18 | **Linux**
(Jetson series) | ARMv8 | Jetson series | - | - | - |
+| 15 | | x86_64 | - | [](#) | [](#) | [](https://github.com/HyperInspire/InspireFace/actions/workflows/release-sdks.yaml) |
+| 16 | **Android**
(Rockchip) | ARMv8 | RK3566/RK3568 | [](#) | [](#) | [](https://github.com/HyperInspire/InspireFace/actions/workflows/release-sdks.yaml) |
+| 17 | | ARMv8 | RK3588 | [](#) | [](#) | [](https://github.com/HyperInspire/InspireFace/actions/workflows/release-sdks.yaml) |
+| 18 | **HarmonyOS** | ARMv8 | - | - | - | - |
+| 19 | **Linux**
(Jetson series) | ARMv8 | Jetson series | - | - | - |
- **Device**: Some special device support, primarily focused on computing power devices.
- **Supported**: The solution has been fully developed and successfully verified on offline devices.
@@ -332,15 +344,20 @@ docker-compose up
```
## Example
-### C/C++ Sample
-To integrate InspireFace into a C/C++ project, you simply need to link the InspireFace library and include the appropriate header files. Below is a basic example demonstrating face detection:
+### C/C++ Sample: Use the recommended CAPI interface
+To integrate InspireFace into a C/C++ project, you simply need to link the InspireFace library and include the appropriate header files(We recommend using the more compatible **CAPI** headers). Below is a basic example demonstrating face detection:
```c
+#include
+#include
+
+...
+
HResult ret;
// The resource file must be loaded before it can be used
ret = HFLaunchInspireFace(packPath);
if (ret != HSUCCEED) {
- std::cout << "Load Resource error: " << ret << std::endl;
+ HFLogPrint(HF_LOG_ERROR, "Load Resource error: %d", ret);
return ret;
}
@@ -358,10 +375,11 @@ HInt32 detectPixelLevel = 160;
HFSession session = {0};
ret = HFCreateInspireFaceSessionOptional(option, detMode, maxDetectNum, detectPixelLevel, -1, &session);
if (ret != HSUCCEED) {
- std::cout << "Create FaceContext error: " << ret << std::endl;
+ HFLogPrint(HF_LOG_ERROR, "Create FaceContext error: %d", ret);
return ret;
}
+// Configure some detection parameters
HFSessionSetTrackPreviewSize(session, detectPixelLevel);
HFSessionSetFilterMinimumFacePixelSize(session, 4);
@@ -369,14 +387,14 @@ HFSessionSetFilterMinimumFacePixelSize(session, 4);
HFImageBitmap image;
ret = HFCreateImageBitmapFromFilePath(sourcePath, 3, &image);
if (ret != HSUCCEED) {
- std::cout << "The source entered is not a picture or read error." << std::endl;
+ HFLogPrint(HF_LOG_ERROR, "The source entered is not a picture or read error.");
return ret;
}
// Prepare an image parameter structure for configuration
HFImageStream imageHandle = {0};
ret = HFCreateImageStreamFromImageBitmap(image, rotation_enum, &imageHandle);
if (ret != HSUCCEED) {
- std::cout << "Create ImageStream error: " << ret << std::endl;
+ HFLogPrint(HF_LOG_ERROR, "Create ImageStream error: %d", ret);
return ret;
}
@@ -384,36 +402,117 @@ if (ret != HSUCCEED) {
HFMultipleFaceData multipleFaceData = {0};
ret = HFExecuteFaceTrack(session, imageHandle, &multipleFaceData);
if (ret != HSUCCEED) {
- std::cout << "Execute HFExecuteFaceTrack error: " << ret << std::endl;
+ HFLogPrint(HF_LOG_ERROR, "Execute HFExecuteFaceTrack error: %d", ret);
return ret;
}
+
// Print the number of faces detected
auto faceNum = multipleFaceData.detectedNum;
-std::cout << "Num of face: " << faceNum << std::endl;
+HFLogPrint(HF_LOG_INFO, "Num of face: %d", faceNum);
// The memory must be freed at the end of the program
ret = HFReleaseImageBitmap(image);
if (ret != HSUCCEED) {
- printf("Release image bitmap error: %lu\n", ret);
+ HFLogPrint(HF_LOG_ERROR, "Release image bitmap error: %d", ret);
return ret;
}
ret = HFReleaseImageStream(imageHandle);
if (ret != HSUCCEED) {
- printf("Release image stream error: %lu\n", ret);
+ HFLogPrint(HF_LOG_ERROR, "Release image stream error: %d", ret);
}
+
ret = HFReleaseInspireFaceSession(session);
if (ret != HSUCCEED) {
- printf("Release session error: %lu\n", ret);
+ HFLogPrint(HF_LOG_ERROR, "Release session error: %d", ret);
return ret;
}
+
+...
```
For more examples, you can refer to the `cpp/sample` sub-project located in the root directory. You can compile these sample executables by enabling the `ISF_BUILD_WITH_SAMPLE` option during the compilation process.
-- **More detailed cases**: [C/C++ Sample](cpp/sample/api/)
-
**Note**: For each error code feedback, you can click on this [link](doc/Error-Feedback-Codes.md) to view detailed explanations.
+### C++ Sample: Use the C++ version of the header files
+
+If you want to use C++ header files, then you need to enable **ISF_INSTALL_CPP_HEADER** during compilation. Executing the install command will add the C++ header files.
+
+```c++
+#include
+#include
+#include
+
+...
+
+// Set log level to info
+INSPIRE_SET_LOG_LEVEL(inspire::LogLevel::ISF_LOG_INFO);
+
+int32_t ret = 0;
+// Global init(you only need to call once)
+ret = INSPIREFACE_CONTEXT->Load("Pikachu");
+INSPIREFACE_CHECK_MSG(ret == HSUCCEED, "Load model failed");
+
+// Create face algorithm session
+inspire::ContextCustomParameter custom_param;
+custom_param.enable_recognition = true;
+auto max_detect_face = 5;
+auto detect_level_px = 320; // 160, 320, 640
+
+// Create a face algorithm session
+std::shared_ptr session(
+ inspire::Session::CreatePtr(inspire::DETECT_MODE_ALWAYS_DETECT, max_detect_face, custom_param, detect_level_px));
+
+// Load image(default format is BGR)
+inspirecv::Image image = inspirecv::Image::Create("face.jpg");
+
+// Create frame process
+inspirecv::FrameProcess process =
+ inspirecv::FrameProcess::Create(image, inspirecv::BGR, inspirecv::ROTATION_0);
+
+// Detect face
+std::vector detect_results;
+ret = session->FaceDetectAndTrack(process, detect_results);
+INSPIRE_LOGI("Number of faces detected: %d", detect_results.size());
+if (detect_results.size() == 0)
+{
+ INSPIRE_LOGW("No face detected");
+ return -1;
+}
+
+// Copy image
+inspirecv::Image image_copy = image.Clone();
+// Draw face
+auto thickness = 2;
+for (auto &face : detect_results)
+{
+ auto rect = session->GetFaceBoundingBox(face);
+ auto lmk = session->GetNumOfFaceDenseLandmark(face);
+ image_copy.DrawRect(rect, inspirecv::Color::Red, thickness);
+ for (auto &point : lmk)
+ {
+ image_copy.DrawCircle(point.As(), 0, inspirecv::Color::Orange, thickness);
+ }
+}
+// Save draw image
+image_copy.Write("result.jpg");
+
+// Face Embedding extract
+inspire::FaceEmbedding face_embedding;
+// Extract the first face feature
+ret = session->FaceFeatureExtract(process, detect_results[0], face_embedding);
+INSPIRE_LOGI("Length of face embedding: %d", face_embedding.embedding.size());
+
+...
+```
+
+Please note that the C++ interface has not been fully tested. It is recommended to use the **CAPI** interface as the primary option.
+
+**More detailed cases**:
+
+- [C Sample](cpp/sample/api/)
+- [C/C++ Sample](cpp/sample/cpp_api/)
+
### Python Native Sample
The Python implementation is compiled based on InspireFace source code, and is integrated using a native interface approach.
@@ -453,7 +552,7 @@ ret = isf.reload()
assert ret, "Launch failure. Please ensure the resource path is correct."
# Optional features, loaded during session creation based on the modules specified.
-opt = isf.HF_ENABLE_NONE
+opt = isf.HF_ENABLE_FACE_POSE
session = isf.InspireFaceSession(opt, isf.HF_DETECT_MODE_ALWAYS_DETECT)
# Load the image using OpenCV.
@@ -488,6 +587,7 @@ We have an [Android SDK project](https://github.com/HyperInspire/inspireface-and
Precompiled library support:
- arm64-v8a
- armeabi-v7a
+- x86_64
#### a. Quick to use in Android
@@ -652,7 +752,7 @@ For different scenarios, we currently provide several Packs, each containing mul
| --- | --- | --- | --- | --- |
| Pikachu | CPU | Lightweight edge-side models | Feb 20, 2025 | [Download](https://github.com/HyperInspire/InspireFace/releases/download/v1.x/Pikachu) |
| Megatron | CPU, GPU | Mobile and server models | Feb 20, 2025 | [Download](https://github.com/HyperInspire/InspireFace/releases/download/v1.x/Megatron) |
-| Megatron_TRT | GPU | Cuda-based server models | Mar 16, 2025 | [Download](https://github.com/HyperInspire/InspireFace/releases/download/v1.x/Megatron_TRT) |
+| Megatron_TRT | GPU | CUDA-based server models | Mar 16, 2025 | [Download](https://github.com/HyperInspire/InspireFace/releases/download/v1.x/Megatron_TRT) |
| Gundam-RV1109 | RKNPU | Supports RK1109 and RK1126 | Feb 20, 2025 | [Download](https://github.com/HyperInspire/InspireFace/releases/download/v1.x/Gundam_RV1109) |
| Gundam-RV1106 | RKNPU | Supports RV1103 and RV1106 | Feb 20, 2025 | [Download](https://github.com/HyperInspire/InspireFace/releases/download/v1.x/Gundam_RV1106) |
| Gundam-RK356X | RKNPU | Supports RK3566 and RK3568 | Feb 20, 2025 | [Download](https://github.com/HyperInspire/InspireFace/releases/download/v1.x/Gundam_RK356X) |
@@ -661,7 +761,8 @@ For different scenarios, we currently provide several Packs, each containing mul
## Short-Term Plan
- [x] Add TensorRT backend support.
-- [ ] Add the RKNPU backend support for Android .
+- [x] Add Add c++ style header files.
+- [x] Add the RKNPU backend support for Android .
- [ ] Example app project for Android and iOS samples.
- [ ] Add the batch forward feature.
diff --git a/cpp-package/inspireface/android/InspireFaceExample/app/src/main/java/com/example/inspireface_example/MainActivity.java b/cpp-package/inspireface/android/InspireFaceExample/app/src/main/java/com/example/inspireface_example/MainActivity.java
index efaac12..1414fcd 100644
--- a/cpp-package/inspireface/android/InspireFaceExample/app/src/main/java/com/example/inspireface_example/MainActivity.java
+++ b/cpp-package/inspireface/android/InspireFaceExample/app/src/main/java/com/example/inspireface_example/MainActivity.java
@@ -25,7 +25,7 @@ public class MainActivity extends AppCompatActivity {
void test() {
InspireFaceVersion version = InspireFace.QueryInspireFaceVersion();
- Log.i(TAG, "InspireFace Version: " + version.major + "." + version.minor + "." + version.patch + " " + version.information);
+ Log.i(TAG, "InspireFace Version: " + version.major + "." + version.minor + "." + version.patch);
String dbPath = "/storage/emulated/0/Android/data/com.example.inspireface_example/files/f.db";
FeatureHubConfiguration configuration = InspireFace.CreateFeatureHubConfiguration()
.setEnablePersistence(false)
diff --git a/cpp-package/inspireface/ci/quick_test_linux_x86_usual.sh b/cpp-package/inspireface/ci/quick_test_linux_x86_usual.sh
index 6ff58cc..d82e908 100644
--- a/cpp-package/inspireface/ci/quick_test_linux_x86_usual.sh
+++ b/cpp-package/inspireface/ci/quick_test_linux_x86_usual.sh
@@ -27,6 +27,7 @@ cd build/${BUILD_DIRNAME}/
# Configure the CMake build system
cmake -DCMAKE_BUILD_TYPE=Release \
+ -DCMAKE_POLICY_VERSION_MINIMUM=3.5 \
-DISF_BUILD_WITH_SAMPLE=OFF \
-DISF_BUILD_WITH_TEST=ON \
-DISF_ENABLE_BENCHMARK=ON \
diff --git a/cpp-package/inspireface/ci/quick_test_linux_x86_usual_python_native_interface.sh b/cpp-package/inspireface/ci/quick_test_linux_x86_usual_python_native_interface.sh
index 140c6c2..aeb2ef2 100644
--- a/cpp-package/inspireface/ci/quick_test_linux_x86_usual_python_native_interface.sh
+++ b/cpp-package/inspireface/ci/quick_test_linux_x86_usual_python_native_interface.sh
@@ -16,6 +16,7 @@ cd build/${BUILD_DIRNAME}/
# Configure the CMake build system
cmake -DCMAKE_BUILD_TYPE=Release \
+ -DCMAKE_POLICY_VERSION_MINIMUM=3.5 \
-DISF_BUILD_WITH_SAMPLE=OFF \
-DISF_BUILD_WITH_TEST=OFF \
-DISF_ENABLE_BENCHMARK=OFF \
diff --git a/cpp-package/inspireface/ci/quick_test_local.sh b/cpp-package/inspireface/ci/quick_test_local.sh
index d167d05..8b975df 100644
--- a/cpp-package/inspireface/ci/quick_test_local.sh
+++ b/cpp-package/inspireface/ci/quick_test_local.sh
@@ -43,6 +43,7 @@ cd build/${BUILD_DIRNAME}/
# Configure the CMake build system
cmake -DCMAKE_BUILD_TYPE=Release \
+ -DCMAKE_POLICY_VERSION_MINIMUM=3.5 \
-DISF_BUILD_WITH_SAMPLE=OFF \
-DISF_BUILD_WITH_TEST=ON \
-DISF_ENABLE_BENCHMARK=ON \
diff --git a/cpp-package/inspireface/command/build.sh b/cpp-package/inspireface/command/build.sh
index 45b9e15..f55c724 100644
--- a/cpp-package/inspireface/command/build.sh
+++ b/cpp-package/inspireface/command/build.sh
@@ -75,12 +75,15 @@ cd "$BUILD_DIR" || exit 1
# Run CMake configuration (adjust the options as needed)
cmake -DCMAKE_BUILD_TYPE=Release \
+ -DCMAKE_POLICY_VERSION_MINIMUM=3.5 \
-DISF_BUILD_WITH_SAMPLE=ON \
-DISF_BUILD_WITH_TEST=OFF \
-DISF_ENABLE_BENCHMARK=OFF \
-DISF_ENABLE_USE_LFW_DATA=OFF \
-DISF_ENABLE_TEST_EVALUATION=OFF \
- -DISF_BUILD_SHARED_LIBS=ON "$SCRIPT_DIR"
+ -DISF_BUILD_SHARED_LIBS=ON \
+ -Wno-dev \
+ "$SCRIPT_DIR"
# Compile and install
make -j4
diff --git a/cpp-package/inspireface/command/build_android.sh b/cpp-package/inspireface/command/build_android.sh
index 7fa961b..3dbf507 100644
--- a/cpp-package/inspireface/command/build_android.sh
+++ b/cpp-package/inspireface/command/build_android.sh
@@ -18,7 +18,14 @@ reorganize_structure() {
done
# Find all architecture directories (e.g., arm64-v8a, armeabi-v7a)
- local arch_dirs=($(find "$base_path" -maxdepth 1 -type d -name "arm*"))
+ local arch_dirs=()
+ for d in "$base_path"/*; do
+ [[ -d "$d" ]] || continue
+ name=$(basename "$d")
+ if [[ "$name" != "lib" && "$name" != "sample" && "$name" != "test" && "$name" != "." && "$name" != ".." ]]; then
+ arch_dirs+=("$d")
+ fi
+ done
for arch_dir in "${arch_dirs[@]}"; do
# Get the architecture name (e.g., arm64-v8a)
@@ -58,11 +65,22 @@ reorganize_structure() {
fi
done
+ # Copy include once from a valid arch
+ for arch_dir in "${arch_dirs[@]}"; do
+ if [ -d "$arch_dir/InspireFace/include" ]; then
+ mkdir -p "$base_path/include"
+ cp -r "$arch_dir/InspireFace/include/"* "$base_path/include/"
+ echo "Copied include from $arch_dir"
+ break
+ fi
+ done
+
# Delete the original architecture directories
for arch_dir in "${arch_dirs[@]}"; do
rm -rf "$arch_dir"
done
+
echo "Reorganization complete."
}
@@ -98,6 +116,7 @@ build() {
cmake ${SCRIPT_DIR} \
-G "Unix Makefiles" \
-DCMAKE_BUILD_TYPE=Release \
+ -DCMAKE_POLICY_VERSION_MINIMUM=3.5 \
-DCMAKE_C_FLAGS="-g0 ${CMAKE_C_FLAGS}" \
-DCMAKE_CXX_FLAGS="-g0 ${CMAKE_CXX_FLAGS}" \
-DCMAKE_TOOLCHAIN_FILE=${ANDROID_NDK}/build/cmake/android.toolchain.cmake \
@@ -111,7 +130,8 @@ build() {
-DISF_ENABLE_BENCHMARK=OFF \
-DISF_ENABLE_USE_LFW_DATA=OFF \
-DISF_ENABLE_TEST_EVALUATION=OFF \
- -DISF_BUILD_SHARED_LIBS=ON
+ -DISF_BUILD_SHARED_LIBS=ON \
+ -Wno-dev
make -j4
make install
popd
@@ -129,6 +149,7 @@ BUILD_FOLDER_PATH="build/inspireface-android${TAG}"
build arm64-v8a 21
build armeabi-v7a 21
+build x86_64 21
reorganize_structure "${BUILD_FOLDER_PATH}"
diff --git a/cpp-package/inspireface/command/build_android_rk356x_rk3588.sh b/cpp-package/inspireface/command/build_android_rk356x_rk3588.sh
index 91f4e73..98726e6 100644
--- a/cpp-package/inspireface/command/build_android_rk356x_rk3588.sh
+++ b/cpp-package/inspireface/command/build_android_rk356x_rk3588.sh
@@ -99,6 +99,7 @@ build() {
cmake ${SCRIPT_DIR} \
-G "Unix Makefiles" \
-DCMAKE_BUILD_TYPE=Release \
+ -DCMAKE_POLICY_VERSION_MINIMUM=3.5 \
-DCMAKE_C_FLAGS="-g0 ${CMAKE_C_FLAGS}" \
-DCMAKE_CXX_FLAGS="-g0 ${CMAKE_CXX_FLAGS}" \
-DCMAKE_TOOLCHAIN_FILE=${ANDROID_NDK}/build/cmake/android.toolchain.cmake \
@@ -117,7 +118,8 @@ build() {
-DISF_ENABLE_BENCHMARK=OFF \
-DISF_ENABLE_USE_LFW_DATA=OFF \
-DISF_ENABLE_TEST_EVALUATION=OFF \
- -DISF_BUILD_SHARED_LIBS=ON
+ -DISF_BUILD_SHARED_LIBS=ON \
+ -Wno-dev
make -j4
make install
popd
diff --git a/cpp-package/inspireface/command/build_cross_aarch64.sh b/cpp-package/inspireface/command/build_cross_aarch64.sh
index 8889f70..014e3e0 100644
--- a/cpp-package/inspireface/command/build_cross_aarch64.sh
+++ b/cpp-package/inspireface/command/build_cross_aarch64.sh
@@ -38,6 +38,7 @@ cd ${BUILD_FOLDER_PATH}
# export cross_compile_toolchain=/home/jingyuyan/software/gcc-linaro-6.3.1-2017.05-x86_64_aarch64-linux-gnu
cmake -DCMAKE_SYSTEM_NAME=Linux \
-DCMAKE_BUILD_TYPE=Release \
+ -DCMAKE_POLICY_VERSION_MINIMUM=3.5 \
-DCMAKE_SYSTEM_VERSION=1 \
-DCMAKE_SYSTEM_PROCESSOR=aarch64 \
-DCMAKE_C_COMPILER=$ARM_CROSS_COMPILE_TOOLCHAIN/bin/aarch64-linux-gnu-gcc \
@@ -51,6 +52,7 @@ cmake -DCMAKE_SYSTEM_NAME=Linux \
-DISF_ENABLE_BENCHMARK=OFF \
-DISF_ENABLE_USE_LFW_DATA=OFF \
-DISF_ENABLE_TEST_EVALUATION=OFF \
+ -Wno-dev \
-DISF_BUILD_SHARED_LIBS=ON ${SCRIPT_DIR}
make -j4
diff --git a/cpp-package/inspireface/command/build_cross_armv7_armhf.sh b/cpp-package/inspireface/command/build_cross_armv7_armhf.sh
index 3cbf97b..c6d75ca 100644
--- a/cpp-package/inspireface/command/build_cross_armv7_armhf.sh
+++ b/cpp-package/inspireface/command/build_cross_armv7_armhf.sh
@@ -38,6 +38,7 @@ cd ${BUILD_FOLDER_PATH}
# export cross_compile_toolchain=/home/jingyuyan/software/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf
cmake -DCMAKE_SYSTEM_NAME=Linux \
-DCMAKE_BUILD_TYPE=Release \
+ -DCMAKE_POLICY_VERSION_MINIMUM=3.5 \
-DCMAKE_SYSTEM_VERSION=1 \
-DCMAKE_SYSTEM_PROCESSOR=armv7 \
-DCMAKE_C_COMPILER=$ARM_CROSS_COMPILE_TOOLCHAIN/bin/arm-linux-gnueabihf-gcc \
@@ -50,6 +51,7 @@ cmake -DCMAKE_SYSTEM_NAME=Linux \
-DISF_ENABLE_BENCHMARK=OFF \
-DISF_ENABLE_USE_LFW_DATA=OFF \
-DISF_ENABLE_TEST_EVALUATION=OFF \
+ -Wno-dev \
-DISF_BUILD_SHARED_LIBS=ON ${SCRIPT_DIR}
make -j4
diff --git a/cpp-package/inspireface/command/build_cross_rk356x_rk3588_aarch64.sh b/cpp-package/inspireface/command/build_cross_rk356x_rk3588_aarch64.sh
index 13241bc..aa01bb1 100644
--- a/cpp-package/inspireface/command/build_cross_rk356x_rk3588_aarch64.sh
+++ b/cpp-package/inspireface/command/build_cross_rk356x_rk3588_aarch64.sh
@@ -46,6 +46,7 @@ cd ${BUILD_FOLDER_PATH}
cmake -DCMAKE_SYSTEM_NAME=Linux \
-DCMAKE_BUILD_TYPE=Release \
+ -DCMAKE_POLICY_VERSION_MINIMUM=3.5 \
-DCMAKE_SYSTEM_VERSION=1 \
-DCMAKE_SYSTEM_PROCESSOR=aarch64 \
-DCMAKE_C_COMPILER=$ARM_CROSS_COMPILE_TOOLCHAIN/bin/aarch64-linux-gnu-gcc \
@@ -66,7 +67,8 @@ cmake -DCMAKE_SYSTEM_NAME=Linux \
-DISF_ENABLE_BENCHMARK=OFF \
-DISF_ENABLE_USE_LFW_DATA=OFF \
-DISF_ENABLE_TEST_EVALUATION=OFF \
- -DISF_BUILD_SHARED_LIBS=OFF ${SCRIPT_DIR}
+ -Wno-dev \
+ -DISF_BUILD_SHARED_LIBS=ON ${SCRIPT_DIR}
make -j4
make install
diff --git a/cpp-package/inspireface/command/build_cross_rv1106_armhf_uclibc.sh b/cpp-package/inspireface/command/build_cross_rv1106_armhf_uclibc.sh
index 6b71495..db858a7 100644
--- a/cpp-package/inspireface/command/build_cross_rv1106_armhf_uclibc.sh
+++ b/cpp-package/inspireface/command/build_cross_rv1106_armhf_uclibc.sh
@@ -78,6 +78,7 @@ cd ${BUILD_FOLDER_PATH}
cmake -DCMAKE_SYSTEM_NAME=Linux \
-DCMAKE_BUILD_TYPE=Release \
+ -DCMAKE_POLICY_VERSION_MINIMUM=3.5 \
-DCMAKE_SYSTEM_VERSION=1 \
-DCMAKE_SYSTEM_PROCESSOR=armv7 \
-DCMAKE_C_COMPILER=$ARM_CROSS_COMPILE_TOOLCHAIN/bin/arm-rockchip830-linux-uclibcgnueabihf-gcc \
@@ -98,9 +99,10 @@ cmake -DCMAKE_SYSTEM_NAME=Linux \
-DISF_ENABLE_BENCHMARK=OFF \
-DISF_ENABLE_USE_LFW_DATA=OFF \
-DISF_ENABLE_TEST_EVALUATION=OFF \
- -DISF_BUILD_SHARED_LIBS=OFF ${SCRIPT_DIR}
+ -Wno-dev \
+ -DISF_BUILD_SHARED_LIBS=ON ${SCRIPT_DIR}
make -j4
-# make install
+make install
-# move_install_files "$(pwd)"
\ No newline at end of file
+move_install_files "$(pwd)"
\ No newline at end of file
diff --git a/cpp-package/inspireface/command/build_cross_rv1109rv1126_armhf.sh b/cpp-package/inspireface/command/build_cross_rv1109rv1126_armhf.sh
index 5a201c4..6f7973e 100644
--- a/cpp-package/inspireface/command/build_cross_rv1109rv1126_armhf.sh
+++ b/cpp-package/inspireface/command/build_cross_rv1109rv1126_armhf.sh
@@ -39,6 +39,7 @@ cd ${BUILD_FOLDER_PATH}
# export cross_compile_toolchain=/home/jingyuyan/software/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf
cmake -DCMAKE_SYSTEM_NAME=Linux \
-DCMAKE_BUILD_TYPE=Release \
+ -DCMAKE_POLICY_VERSION_MINIMUM=3.5 \
-DCMAKE_SYSTEM_VERSION=1 \
-DCMAKE_SYSTEM_PROCESSOR=armv7 \
-DCMAKE_C_COMPILER=$ARM_CROSS_COMPILE_TOOLCHAIN/bin/arm-linux-gnueabihf-gcc \
@@ -53,6 +54,7 @@ cmake -DCMAKE_SYSTEM_NAME=Linux \
-DISF_ENABLE_BENCHMARK=OFF \
-DISF_ENABLE_USE_LFW_DATA=OFF \
-DISF_ENABLE_TEST_EVALUATION=OFF \
+ -Wno-dev \
-DISF_BUILD_SHARED_LIBS=ON ${SCRIPT_DIR}
make -j4
diff --git a/cpp-package/inspireface/command/build_ios_coreml.sh b/cpp-package/inspireface/command/build_ios_coreml.sh
new file mode 100644
index 0000000..601615d
--- /dev/null
+++ b/cpp-package/inspireface/command/build_ios_coreml.sh
@@ -0,0 +1,157 @@
+#!/bin/bash
+
+# Reusable function to handle 'install' directory operations
+move_install_files() {
+ local root_dir="$1"
+ local install_dir="$root_dir/install"
+
+ # Step 1: Check if the 'install' directory exists
+ if [ ! -d "$install_dir" ]; then
+ echo "Error: 'install' directory does not exist in $root_dir"
+ exit 1
+ fi
+
+ # Step 2: Delete all other files/folders except 'install'
+ find "$root_dir" -mindepth 1 -maxdepth 1 -not -name "install" -exec rm -rf {} +
+
+ # Step 3: Move all files from 'install' to the root directory
+ mv "$install_dir"/* "$root_dir" 2>/dev/null
+
+ # Step 4: Remove the empty 'install' directory
+ rmdir "$install_dir"
+
+ echo "Files from 'install' moved to $root_dir, and 'install' directory deleted."
+}
+
+# Define download URLs
+MNN_IOS_URL="https://github.com/alibaba/MNN/releases/download/2.8.1/mnn_2.8.1_ios_armv82_cpu_metal_coreml.zip"
+
+# Set the cache directory
+MACOS_CACHE="$PWD/.macos_cache/"
+
+# Create the directory if it does not exist
+mkdir -p "${MACOS_CACHE}"
+
+# Function to download and unzip a file if the required framework does not exist
+download_and_unzip() {
+ local url=$1
+ local dir=$2
+ local framework_name=$3 # Name of the framework directory to check
+
+ # Check if the framework already exists
+ if [ ! -d "${dir}${framework_name}" ]; then
+ local file_name=$(basename "$url")
+ local full_path="${dir}${file_name}"
+
+ # Check if the zip file already exists
+ if [ ! -f "$full_path" ]; then
+ echo "Downloading ${file_name}..."
+ # Download the file
+ curl -sL "$url" -o "$full_path"
+ else
+ echo "${file_name} already downloaded. Proceeding to unzip."
+ fi
+
+ # Unzip the file to a temporary directory
+ echo "Unzipping ${file_name}..."
+ unzip -q "$full_path" -d "${dir}"
+ rm "$full_path"
+
+ # Move the framework if it's in a subdirectory specific to the iOS build
+ if [ "${framework_name}" == "MNN.framework" ]; then
+ mv "${dir}ios_build/Release-iphoneos/${framework_name}" "${dir}"
+ rm -rf "${dir}ios_build" # Clean up the subdirectory
+ fi
+
+ echo "${framework_name} has been set up."
+ else
+ echo "${framework_name} already exists in ${dir}. Skipping download and unzip."
+ fi
+}
+
+# Download and unzip MNN iOS package
+download_and_unzip "$MNN_IOS_URL" "$MACOS_CACHE" "MNN.framework"
+
+# Download and unzip OpenCV iOS package
+
+if [ -n "$VERSION" ]; then
+ TAG="-$VERSION"
+else
+ TAG=""
+fi
+
+
+TOOLCHAIN="$PWD/toolchain/ios.toolchain.cmake"
+
+BUILD_DIR="build/inspireface-ios-coreml-arm64$TAG"
+
+mkdir -p "$BUILD_DIR"
+
+cd "$BUILD_DIR"
+
+cmake \
+ -DIOS_3RDPARTY="${MACOS_CACHE}" \
+ -DCMAKE_TOOLCHAIN_FILE=${TOOLCHAIN} \
+ -DCMAKE_OSX_ARCHITECTURES=arm64 \
+ -DENABLE_BITCODE=0 \
+ -DIOS_DEPLOYMENT_TARGET=11.0 \
+ -DISF_ENABLE_APPLE_EXTENSION=ON \
+ -DISF_BUILD_WITH_SAMPLE=OFF \
+ -DISF_BUILD_WITH_TEST=OFF \
+ -DISF_BUILD_SHARED_LIBS=OFF \
+ ../..
+
+make -j8
+
+make install
+
+move_install_files "$(pwd)"
+
+# Set the framework name
+FRAMEWORK_NAME=InspireFace
+
+# Specify the version of the framework
+FRAMEWORK_VERSION=1.0.0
+
+# Root build directory
+BUILD_DIR="$(pwd)"
+
+BUILD_LIB_DIR="$BUILD_DIR/InspireFace"
+
+# Create the framework structure
+FRAMEWORK_DIR=$BUILD_DIR/$FRAMEWORK_NAME.framework
+mkdir -p $FRAMEWORK_DIR
+mkdir -p $FRAMEWORK_DIR/Headers
+mkdir -p $FRAMEWORK_DIR/Resources
+
+# Copy the static library to the framework directory
+cp $BUILD_LIB_DIR/lib/libInspireFace.a $FRAMEWORK_DIR/$FRAMEWORK_NAME
+
+# Copy header files to the framework's Headers directory
+cp $BUILD_LIB_DIR/include/*.h $FRAMEWORK_DIR/Headers/
+
+# Create Info.plist
+cat <$FRAMEWORK_DIR/Resources/Info.plist
+
+
+
+
+ CFBundleExecutable
+ $FRAMEWORK_NAME
+ CFBundleIdentifier
+ com.example.$FRAMEWORK_NAME
+ CFBundleName
+ $FRAMEWORK_NAME
+ CFBundleVersion
+ $FRAMEWORK_VERSION
+ CFBundleShortVersionString
+ $FRAMEWORK_VERSION
+ CFBundlePackageType
+ FMWK
+
+
+EOF
+
+echo "Framework $FRAMEWORK_NAME.framework has been created at $FRAMEWORK_DIR"
+
+cp -r $MACOS_CACHE/MNN.framework $BUILD_DIR/
diff --git a/cpp-package/inspireface/command/build_linux_cuda.sh b/cpp-package/inspireface/command/build_linux_cuda.sh
index 6526fd9..fd030f2 100644
--- a/cpp-package/inspireface/command/build_linux_cuda.sh
+++ b/cpp-package/inspireface/command/build_linux_cuda.sh
@@ -38,6 +38,7 @@ cd ${BUILD_FOLDER_PATH}
cmake -DCMAKE_SYSTEM_NAME=Linux \
-DCMAKE_BUILD_TYPE=Release \
+ -DCMAKE_POLICY_VERSION_MINIMUM=3.5 \
-DISF_BUILD_WITH_SAMPLE=ON \
-DISF_BUILD_WITH_TEST=ON \
-DISF_ENABLE_BENCHMARK=ON \
@@ -45,6 +46,7 @@ cmake -DCMAKE_SYSTEM_NAME=Linux \
-DISF_ENABLE_TEST_EVALUATION=OFF \
-DMNN_CUDA=ON \
-DISF_GLOBAL_INFERENCE_BACKEND_USE_MNN_CUDA=ON \
+ -Wno-dev \
-DISF_LINUX_MNN_CUDA=/home/tunm/softwate/MNN-2.7.2/build_cuda ${SCRIPT_DIR}
make -j4
diff --git a/cpp-package/inspireface/command/build_linux_cuda_dev.sh b/cpp-package/inspireface/command/build_linux_cuda_dev.sh
index 4e8820e..0295bb8 100644
--- a/cpp-package/inspireface/command/build_linux_cuda_dev.sh
+++ b/cpp-package/inspireface/command/build_linux_cuda_dev.sh
@@ -38,6 +38,7 @@ cd ${BUILD_FOLDER_PATH}
cmake -DCMAKE_SYSTEM_NAME=Linux \
-DCMAKE_BUILD_TYPE=Release \
+ -DCMAKE_POLICY_VERSION_MINIMUM=3.5 \
-DISF_BUILD_WITH_SAMPLE=ON \
-DISF_BUILD_WITH_TEST=ON \
-DISF_ENABLE_BENCHMARK=ON \
@@ -45,6 +46,7 @@ cmake -DCMAKE_SYSTEM_NAME=Linux \
-DISF_ENABLE_TEST_EVALUATION=ON \
-DMNN_CUDA=ON \
-DISF_GLOBAL_INFERENCE_BACKEND_USE_MNN_CUDA=ON \
+ -Wno-dev \
-DISF_LINUX_MNN_CUDA=/host/softwate/MNN-2.7.2/build_cuda ${SCRIPT_DIR}
make -j4
diff --git a/cpp-package/inspireface/command/build_linux_manylinux2014.sh b/cpp-package/inspireface/command/build_linux_manylinux2014.sh
index c6ec090..c4ac8d6 100644
--- a/cpp-package/inspireface/command/build_linux_manylinux2014.sh
+++ b/cpp-package/inspireface/command/build_linux_manylinux2014.sh
@@ -39,10 +39,12 @@ cd ${BUILD_FOLDER_PATH}
cmake -DCMAKE_BUILD_TYPE=Release \
-DISF_BUILD_WITH_SAMPLE=OFF \
+ -DCMAKE_POLICY_VERSION_MINIMUM=3.5 \
-DISF_BUILD_WITH_TEST=OFF \
-DISF_ENABLE_BENCHMARK=OFF \
-DISF_ENABLE_USE_LFW_DATA=OFF \
-DISF_ENABLE_TEST_EVALUATION=OFF \
+ -Wno-dev \
-DISF_BUILD_SHARED_LIBS=ON ${SCRIPT_DIR}
make -j4
diff --git a/cpp-package/inspireface/command/build_linux_tensorrt.sh b/cpp-package/inspireface/command/build_linux_tensorrt.sh
index 741b4a0..3c30e73 100644
--- a/cpp-package/inspireface/command/build_linux_tensorrt.sh
+++ b/cpp-package/inspireface/command/build_linux_tensorrt.sh
@@ -99,12 +99,15 @@ echo "TENSORRT_ROOT: ${TENSORRT_ROOT}"
cmake \
-DCMAKE_BUILD_TYPE=Release \
-DISF_BUILD_WITH_SAMPLE=ON \
+ -DCMAKE_POLICY_VERSION_MINIMUM=3.5 \
-DISF_BUILD_WITH_TEST=ON \
-DISF_ENABLE_BENCHMARK=ON \
-DISF_ENABLE_USE_LFW_DATA=OFF \
-DISF_ENABLE_TEST_EVALUATION=OFF \
-DTENSORRT_ROOT=${TENSORRT_ROOT} \
- -DISF_ENABLE_TENSORRT=ON ../..
+ -DISF_ENABLE_TENSORRT=ON \
+ -Wno-dev \
+ ../..
make -j4
diff --git a/cpp-package/inspireface/command/build_linux_ubuntu18.sh b/cpp-package/inspireface/command/build_linux_ubuntu18.sh
index 9827a0f..88862b8 100644
--- a/cpp-package/inspireface/command/build_linux_ubuntu18.sh
+++ b/cpp-package/inspireface/command/build_linux_ubuntu18.sh
@@ -36,13 +36,18 @@ mkdir -p ${BUILD_FOLDER_PATH}
# shellcheck disable=SC2164
cd ${BUILD_FOLDER_PATH}
+cmake --version
+
cmake -DCMAKE_BUILD_TYPE=Release \
+ -DCMAKE_POLICY_VERSION_MINIMUM=3.5 \
-DISF_BUILD_WITH_SAMPLE=OFF \
-DISF_BUILD_WITH_TEST=OFF \
-DISF_ENABLE_BENCHMARK=OFF \
-DISF_ENABLE_USE_LFW_DATA=OFF \
-DISF_ENABLE_TEST_EVALUATION=OFF \
- -DISF_BUILD_SHARED_LIBS=ON ${SCRIPT_DIR}
+ -DISF_BUILD_SHARED_LIBS=ON \
+ -Wno-dev \
+ ${SCRIPT_DIR}
make -j4
make install
diff --git a/cpp-package/inspireface/command/build_macos_arm64.sh b/cpp-package/inspireface/command/build_macos_arm64.sh
index 840bfae..b5734d1 100644
--- a/cpp-package/inspireface/command/build_macos_arm64.sh
+++ b/cpp-package/inspireface/command/build_macos_arm64.sh
@@ -37,12 +37,15 @@ mkdir -p ${BUILD_FOLDER_PATH}
cd ${BUILD_FOLDER_PATH}
cmake -DCMAKE_BUILD_TYPE=Release \
+ -DCMAKE_POLICY_VERSION_MINIMUM=3.5 \
-DISF_BUILD_WITH_SAMPLE=OFF \
-DISF_BUILD_WITH_TEST=OFF \
-DISF_ENABLE_BENCHMARK=OFF \
-DISF_ENABLE_USE_LFW_DATA=OFF \
-DISF_ENABLE_TEST_EVALUATION=OFF \
- -DISF_BUILD_SHARED_LIBS=ON ${SCRIPT_DIR}
+ -DISF_BUILD_SHARED_LIBS=ON \
+ -Wno-dev \
+ ${SCRIPT_DIR}
make -j4
make install
diff --git a/cpp-package/inspireface/command/build_macos_coreml_arm64.sh b/cpp-package/inspireface/command/build_macos_coreml_arm64.sh
new file mode 100644
index 0000000..87491d4
--- /dev/null
+++ b/cpp-package/inspireface/command/build_macos_coreml_arm64.sh
@@ -0,0 +1,54 @@
+#!/bin/bash
+
+# Reusable function to handle 'install' directory operations
+move_install_files() {
+ local root_dir="$1"
+ local install_dir="$root_dir/install"
+
+ # Step 1: Check if the 'install' directory exists
+ if [ ! -d "$install_dir" ]; then
+ echo "Error: 'install' directory does not exist in $root_dir"
+ exit 1
+ fi
+
+ # Step 2: Delete all other files/folders except 'install'
+ find "$root_dir" -mindepth 1 -maxdepth 1 -not -name "install" -exec rm -rf {} +
+
+ # Step 3: Move all files from 'install' to the root directory
+ mv "$install_dir"/* "$root_dir" 2>/dev/null
+
+ # Step 4: Remove the empty 'install' directory
+ rmdir "$install_dir"
+
+ echo "Files from 'install' moved to $root_dir, and 'install' directory deleted."
+}
+
+if [ -n "$VERSION" ]; then
+ TAG="-$VERSION"
+else
+ TAG=""
+fi
+
+BUILD_FOLDER_PATH="build/inspireface-macos-coreml-apple-silicon-arm64${TAG}/"
+SCRIPT_DIR=$(pwd) # Project dir
+
+mkdir -p ${BUILD_FOLDER_PATH}
+# shellcheck disable=SC2164
+cd ${BUILD_FOLDER_PATH}
+
+cmake -DCMAKE_BUILD_TYPE=Release \
+ -DCMAKE_POLICY_VERSION_MINIMUM=3.5 \
+ -DISF_ENABLE_APPLE_EXTENSION=ON \
+ -DISF_BUILD_WITH_SAMPLE=OFF \
+ -DISF_BUILD_WITH_TEST=OFF \
+ -DISF_ENABLE_BENCHMARK=OFF \
+ -DISF_ENABLE_USE_LFW_DATA=OFF \
+ -DISF_ENABLE_TEST_EVALUATION=OFF \
+ -DISF_BUILD_SHARED_LIBS=OFF \
+ -Wno-dev \
+ ${SCRIPT_DIR}
+
+make -j4
+make install
+
+move_install_files "$(pwd)"
\ No newline at end of file
diff --git a/cpp-package/inspireface/command/build_macos_coreml_x86.sh b/cpp-package/inspireface/command/build_macos_coreml_x86.sh
new file mode 100644
index 0000000..675bfef
--- /dev/null
+++ b/cpp-package/inspireface/command/build_macos_coreml_x86.sh
@@ -0,0 +1,54 @@
+#!/bin/bash
+
+# Reusable function to handle 'install' directory operations
+move_install_files() {
+ local root_dir="$1"
+ local install_dir="$root_dir/install"
+
+ # Step 1: Check if the 'install' directory exists
+ if [ ! -d "$install_dir" ]; then
+ echo "Error: 'install' directory does not exist in $root_dir"
+ exit 1
+ fi
+
+ # Step 2: Delete all other files/folders except 'install'
+ find "$root_dir" -mindepth 1 -maxdepth 1 -not -name "install" -exec rm -rf {} +
+
+ # Step 3: Move all files from 'install' to the root directory
+ mv "$install_dir"/* "$root_dir" 2>/dev/null
+
+ # Step 4: Remove the empty 'install' directory
+ rmdir "$install_dir"
+
+ echo "Files from 'install' moved to $root_dir, and 'install' directory deleted."
+}
+
+if [ -n "$VERSION" ]; then
+ TAG="-$VERSION"
+else
+ TAG=""
+fi
+
+BUILD_FOLDER_PATH="build/inspireface-macos-coreml-intel-x86-64${TAG}/"
+SCRIPT_DIR=$(pwd) # Project dir
+
+mkdir -p ${BUILD_FOLDER_PATH}
+# shellcheck disable=SC2164
+cd ${BUILD_FOLDER_PATH}
+
+cmake -DCMAKE_BUILD_TYPE=Release \
+ -DCMAKE_POLICY_VERSION_MINIMUM=3.5 \
+ -DISF_ENABLE_APPLE_EXTENSION=ON \
+ -DISF_BUILD_WITH_SAMPLE=OFF \
+ -DISF_BUILD_WITH_TEST=OFF \
+ -DISF_ENABLE_BENCHMARK=OFF \
+ -DISF_ENABLE_USE_LFW_DATA=OFF \
+ -DISF_ENABLE_TEST_EVALUATION=OFF \
+ -DISF_BUILD_SHARED_LIBS=ON \
+ -Wno-dev \
+ ${SCRIPT_DIR}
+
+make -j4
+make install
+
+move_install_files "$(pwd)"
\ No newline at end of file
diff --git a/cpp-package/inspireface/command/build_macos_x86.sh b/cpp-package/inspireface/command/build_macos_x86.sh
index e009e56..d6215b1 100644
--- a/cpp-package/inspireface/command/build_macos_x86.sh
+++ b/cpp-package/inspireface/command/build_macos_x86.sh
@@ -37,12 +37,15 @@ mkdir -p ${BUILD_FOLDER_PATH}
cd ${BUILD_FOLDER_PATH}
cmake -DCMAKE_BUILD_TYPE=Release \
+ -DCMAKE_POLICY_VERSION_MINIMUM=3.5 \
-DISF_BUILD_WITH_SAMPLE=OFF \
-DISF_BUILD_WITH_TEST=OFF \
-DISF_ENABLE_BENCHMARK=OFF \
-DISF_ENABLE_USE_LFW_DATA=OFF \
-DISF_ENABLE_TEST_EVALUATION=OFF \
- -DISF_BUILD_SHARED_LIBS=ON ${SCRIPT_DIR}
+ -DISF_BUILD_SHARED_LIBS=ON \
+ -Wno-dev \
+ ${SCRIPT_DIR}
make -j4
make install
diff --git a/cpp-package/inspireface/command/build_wheel_macos_arm64.sh b/cpp-package/inspireface/command/build_wheel_macos_arm64.sh
index 1b6ef7b..ccbea36 100644
--- a/cpp-package/inspireface/command/build_wheel_macos_arm64.sh
+++ b/cpp-package/inspireface/command/build_wheel_macos_arm64.sh
@@ -37,12 +37,15 @@ mkdir -p ${BUILD_FOLDER_PATH}
cd ${BUILD_FOLDER_PATH}
cmake -DCMAKE_BUILD_TYPE=Release \
+ -DCMAKE_POLICY_VERSION_MINIMUM=3.5 \
-DISF_BUILD_WITH_SAMPLE=OFF \
-DISF_BUILD_WITH_TEST=OFF \
-DISF_ENABLE_BENCHMARK=OFF \
-DISF_ENABLE_USE_LFW_DATA=OFF \
-DISF_ENABLE_TEST_EVALUATION=OFF \
- -DISF_BUILD_SHARED_LIBS=ON ${SCRIPT_DIR}
+ -DISF_BUILD_SHARED_LIBS=ON \
+ -Wno-dev \
+ ${SCRIPT_DIR}
make -j4
make install
diff --git a/cpp-package/inspireface/command/build_wheel_macos_x86.sh b/cpp-package/inspireface/command/build_wheel_macos_x86.sh
index 27e4460..ae13d1b 100644
--- a/cpp-package/inspireface/command/build_wheel_macos_x86.sh
+++ b/cpp-package/inspireface/command/build_wheel_macos_x86.sh
@@ -37,12 +37,15 @@ mkdir -p ${BUILD_FOLDER_PATH}
cd ${BUILD_FOLDER_PATH}
cmake -DCMAKE_BUILD_TYPE=Release \
+ -DCMAKE_POLICY_VERSION_MINIMUM=3.5 \
-DISF_BUILD_WITH_SAMPLE=OFF \
-DISF_BUILD_WITH_TEST=OFF \
-DISF_ENABLE_BENCHMARK=OFF \
-DISF_ENABLE_USE_LFW_DATA=OFF \
-DISF_ENABLE_TEST_EVALUATION=OFF \
- -DISF_BUILD_SHARED_LIBS=ON ${SCRIPT_DIR}
+ -DISF_BUILD_SHARED_LIBS=ON \
+ -Wno-dev \
+ ${SCRIPT_DIR}
make -j4
make install
diff --git a/cpp-package/inspireface/command/build_wheel_manylinux2014_x86.sh b/cpp-package/inspireface/command/build_wheel_manylinux2014_x86.sh
index ce6f14b..a19b659 100644
--- a/cpp-package/inspireface/command/build_wheel_manylinux2014_x86.sh
+++ b/cpp-package/inspireface/command/build_wheel_manylinux2014_x86.sh
@@ -37,12 +37,15 @@ mkdir -p ${BUILD_FOLDER_PATH}
cd ${BUILD_FOLDER_PATH}
cmake -DCMAKE_BUILD_TYPE=Release \
+ -DCMAKE_POLICY_VERSION_MINIMUM=3.5 \
-DISF_BUILD_WITH_SAMPLE=OFF \
-DISF_BUILD_WITH_TEST=OFF \
-DISF_ENABLE_BENCHMARK=OFF \
-DISF_ENABLE_USE_LFW_DATA=OFF \
-DISF_ENABLE_TEST_EVALUATION=OFF \
- -DISF_BUILD_SHARED_LIBS=ON ${SCRIPT_DIR}
+ -DISF_BUILD_SHARED_LIBS=ON \
+ -Wno-dev \
+ ${SCRIPT_DIR}
make -j4
make install
diff --git a/cpp-package/inspireface/command/test.sh b/cpp-package/inspireface/command/test.sh
deleted file mode 100644
index 097b1c9..0000000
--- a/cpp-package/inspireface/command/test.sh
+++ /dev/null
@@ -1,66 +0,0 @@
-#!/bin/bash
-
-# 函数:获取CUDA和Ubuntu版本标签
-# 如果CUDA_TAG环境变量已设置,则使用该值
-# 否则自动检测CUDA和Ubuntu版本并生成标签
-# 格式: cudaXX_ubuntuXX.XX
-# 如果检测不到某个版本,则用"none"代替
-get_cuda_ubuntu_tag() {
- # 如果CUDA_TAG已设置,则直接返回
- if [ -n "${CUDA_TAG}" ]; then
- echo "${CUDA_TAG}"
- return 0
- fi
-
- # 获取CUDA版本
- CUDA_VERSION="_none"
- if command -v nvcc &> /dev/null; then
- # 尝试从nvcc获取版本
- CUDA_VERSION=$(nvcc --version 2>/dev/null | grep "release" | awk '{print $6}' | cut -d',' -f1 | tr -d '.')
- if [ -z "${CUDA_VERSION}" ]; then
- CUDA_VERSION="_none"
- else
- CUDA_VERSION="${CUDA_VERSION}"
- fi
- elif [ -f "/usr/local/cuda/version.txt" ]; then
- # 尝试从CUDA安装目录获取版本
- CUDA_VERSION=$(cat /usr/local/cuda/version.txt 2>/dev/null | grep "CUDA Version" | awk '{print $3}' | tr -d '.')
- if [ -z "${CUDA_VERSION}" ]; then
- CUDA_VERSION="_none"
- fi
- elif [ -d "/usr/local/cuda" ] && ls -l /usr/local/cuda 2>/dev/null | grep -q "cuda-"; then
- # 尝试从符号链接获取版本
- CUDA_LINK=$(ls -l /usr/local/cuda 2>/dev/null | grep -o "cuda-[0-9.]*" | head -n 1)
- CUDA_VERSION=$(echo "${CUDA_LINK}" | cut -d'-' -f2 | tr -d '.')
- if [ -z "${CUDA_VERSION}" ]; then
- CUDA_VERSION="_none"
- fi
- fi
-
- # 获取Ubuntu版本
- UBUNTU_VERSION="_none"
- if [ -f "/etc/os-release" ]; then
- # 检查是否是Ubuntu
- if grep -q "Ubuntu" /etc/os-release 2>/dev/null; then
- UBUNTU_VERSION=$(grep "VERSION_ID" /etc/os-release 2>/dev/null | cut -d'"' -f2)
- if [ -z "${UBUNTU_VERSION}" ]; then
- UBUNTU_VERSION="_none"
- fi
- fi
- elif [ -f "/etc/lsb-release" ]; then
- # 尝试从lsb-release获取版本
- if grep -q "Ubuntu" /etc/lsb-release 2>/dev/null; then
- UBUNTU_VERSION=$(grep "DISTRIB_RELEASE" /etc/lsb-release 2>/dev/null | cut -d'=' -f2)
- if [ -z "${UBUNTU_VERSION}" ]; then
- UBUNTU_VERSION="_none"
- fi
- fi
- fi
-
- # 生成并返回标签
- echo "cuda${CUDA_VERSION}_ubuntu${UBUNTU_VERSION}"
-}
-
-# 使用示例
-CUDA_TAG=$(get_cuda_ubuntu_tag)
-echo "Generated tag: ${CUDA_TAG}"
\ No newline at end of file
diff --git a/cpp-package/inspireface/cpp/inspireface/CMakeLists.txt b/cpp-package/inspireface/cpp/inspireface/CMakeLists.txt
index 61094ff..03729c1 100644
--- a/cpp-package/inspireface/cpp/inspireface/CMakeLists.txt
+++ b/cpp-package/inspireface/cpp/inspireface/CMakeLists.txt
@@ -1,4 +1,4 @@
-cmake_minimum_required(VERSION 3.10)
+cmake_minimum_required(VERSION 3.20)
project(InspireFaceSDK)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS}")
@@ -15,7 +15,7 @@ else()
set(EXTENDED_INFORMATION "${EXTENDED_INFORMATION}@General")
endif()
set(EXTENDED_INFORMATION "${EXTENDED_INFORMATION} - Build Time: ${BUILD_TIMESTAMP}")
-configure_file(${CMAKE_CURRENT_SOURCE_DIR}/information.h.in ${CMAKE_CURRENT_SOURCE_DIR}/information.h)
+configure_file(${CMAKE_CURRENT_SOURCE_DIR}/information.h.in ${CMAKE_CURRENT_SOURCE_DIR}/include/inspireface/information.h)
file(GLOB_RECURSE SOURCE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp)
set(SOURCE_FILES ${SOURCE_FILES} ${CMAKE_CURRENT_SOURCE_DIR}/c_api/inspireface.cc) # Add C_API file
@@ -97,7 +97,6 @@ if(ISF_ENABLE_APPLE_EXTENSION)
find_library(FOUNDATION_LIBRARY Foundation)
find_library(COREML_LIBRARY CoreML)
find_library(ACCELERATE_LIBRARY Accelerate)
- find_package(OpenCV REQUIRED)
set(LINK_THIRD_LIBS ${LINK_THIRD_LIBS} ${FOUNDATION_LIBRARY} ${COREML_LIBRARY} ${ACCELERATE_LIBRARY})
# Add objective-c files
@@ -128,6 +127,9 @@ if (ISF_ENABLE_RKNN)
endif()
endif ()
+# Add include directory
+set(NEED_INCLUDE ${NEED_INCLUDE} ${CMAKE_CURRENT_SOURCE_DIR}/include/inspireface)
+
if (ISF_BUILD_LINUX_ARM7 OR ANDROID)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mfpu=neon")
endif()
@@ -221,7 +223,6 @@ if (ISF_ENABLE_TENSORRT)
message(STATUS "\t CUDA_RUNTIME_LIBRARY: ${CUDA_RUNTIME_LIBRARY}")
endif()
-
# Install lib
install(TARGETS InspireFace
LIBRARY DESTINATION ${CMAKE_INSTALL_PREFIX}/InspireFace/lib
@@ -233,10 +234,17 @@ install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/c_api/inspireface.h DESTINATION ${CMAK
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/c_api/intypedef.h DESTINATION ${CMAKE_INSTALL_PREFIX}/InspireFace/include)
-install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/herror.h DESTINATION ${CMAKE_INSTALL_PREFIX}/InspireFace/include)
+install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/include/inspireface/herror.h DESTINATION ${CMAKE_INSTALL_PREFIX}/InspireFace/include)
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/version.txt DESTINATION ${CMAKE_INSTALL_PREFIX}/)
+if(ISF_INSTALL_CPP_HEADER)
+ # Install cpp api header file
+ install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/inspireface/ DESTINATION ${CMAKE_INSTALL_PREFIX}/InspireFace/include/inspireface/)
+
+ install(DIRECTORY ${INSPIRECV_INCLUDE_PATH}/inspirecv DESTINATION ${CMAKE_INSTALL_PREFIX}/InspireFace/include/)
+endif()
+
if (ISF_ENABLE_RKNN AND ISF_RKNPU_MAJOR STREQUAL "rknpu1")
# Install rknn 3rd lib
install(FILES ${ISF_RKNN_API_LIB}/librknn_api.so DESTINATION ${CMAKE_INSTALL_PREFIX}/InspireFace/lib)
diff --git a/cpp-package/inspireface/cpp/inspireface/Initialization_module/launch.cpp b/cpp-package/inspireface/cpp/inspireface/Initialization_module/launch.cpp
deleted file mode 100644
index 9a1dad6..0000000
--- a/cpp-package/inspireface/cpp/inspireface/Initialization_module/launch.cpp
+++ /dev/null
@@ -1,179 +0,0 @@
-/**
- * Created by Jingyu Yan
- * @date 2024-10-01
- */
-
-#include "launch.h"
-#include "log.h"
-#include "herror.h"
-#include "isf_check.h"
-#include "middleware/cuda_toolkit.h"
-#if defined(ISF_ENABLE_TENSORRT)
-#include "middleware/cuda_toolkit.h"
-#endif
-
-#define APPLE_EXTENSION_SUFFIX ".bundle"
-
-namespace inspire {
-
-std::mutex Launch::mutex_;
-std::shared_ptr Launch::instance_ = nullptr;
-
-InspireArchive& Launch::getMArchive() {
- std::lock_guard lock(mutex_);
- if (!m_archive_) {
- throw std::runtime_error("Archive not initialized");
- }
- return *m_archive_;
-}
-
-std::shared_ptr Launch::GetInstance() {
- std::lock_guard lock(mutex_);
- if (!instance_) {
- instance_ = std::shared_ptr(new Launch());
- }
- return instance_;
-}
-
-int32_t Launch::Load(const std::string& path) {
- std::lock_guard lock(mutex_);
-#if defined(ISF_ENABLE_TENSORRT)
- int32_t support_cuda;
- auto ret = CheckCudaUsability(&support_cuda);
- if (ret != HSUCCEED) {
- INSPIRE_LOGE("An error occurred while checking CUDA device support. Please ensure that your environment supports CUDA!");
- return ret;
- }
- if (!support_cuda) {
- INSPIRE_LOGE("Your environment does not support CUDA! Please ensure that your environment supports CUDA!");
- return HERR_DEVICE_CUDA_NOT_SUPPORT;
- }
-#endif
- INSPIREFACE_CHECK_MSG(os::IsExists(path), "The package path does not exist because the launch failed.");
-#if defined(ISF_ENABLE_APPLE_EXTENSION)
- BuildAppleExtensionPath(path);
-#endif
- if (!m_load_) {
- try {
- m_archive_ = std::make_unique();
- m_archive_->ReLoad(path);
-
- if (m_archive_->QueryStatus() == SARC_SUCCESS) {
- m_load_ = true;
- INSPIRE_LOGI("Successfully loaded resources");
- return HSUCCEED;
- } else {
- m_archive_.reset();
- INSPIRE_LOGE("Failed to load resources");
- return HERR_ARCHIVE_LOAD_MODEL_FAILURE;
- }
- } catch (const std::exception& e) {
- m_archive_.reset();
- INSPIRE_LOGE("Exception during resource loading: %s", e.what());
- return HERR_ARCHIVE_LOAD_MODEL_FAILURE;
- }
- } else {
- INSPIRE_LOGW("There is no need to call launch more than once, as subsequent calls will not affect the initialization.");
- return HSUCCEED;
- }
-}
-
-int32_t Launch::Reload(const std::string& path) {
- std::lock_guard lock(mutex_);
- INSPIREFACE_CHECK_MSG(os::IsExists(path), "The package path does not exist because the launch failed.");
-#if defined(ISF_ENABLE_APPLE_EXTENSION)
- BuildAppleExtensionPath(path);
-#endif
- try {
- // Clean up existing archive if it exists
- if (m_archive_) {
- m_archive_.reset();
- m_load_ = false;
- }
-
- // Create and load new archive
- m_archive_ = std::make_unique();
- m_archive_->ReLoad(path);
-
- if (m_archive_->QueryStatus() == SARC_SUCCESS) {
- m_load_ = true;
- INSPIRE_LOGI("Successfully reloaded resources");
- return HSUCCEED;
- } else {
- m_archive_.reset();
- INSPIRE_LOGE("Failed to reload resources");
- return HERR_ARCHIVE_LOAD_MODEL_FAILURE;
- }
- } catch (const std::exception& e) {
- m_archive_.reset();
- INSPIRE_LOGE("Exception during resource reloading: %s", e.what());
- return HERR_ARCHIVE_LOAD_MODEL_FAILURE;
- }
-}
-
-bool Launch::isMLoad() const {
- return m_load_;
-}
-
-void Launch::Unload() {
- std::lock_guard lock(mutex_);
- if (m_load_) {
- m_archive_.reset();
- m_load_ = false;
- INSPIRE_LOGI("All resources have been successfully unloaded and system is reset.");
- } else {
- INSPIRE_LOGW("Unload called but system was not loaded.");
- }
-}
-
-void Launch::SetRockchipDmaHeapPath(const std::string& path) {
- m_rockchip_dma_heap_path_ = path;
-}
-
-std::string Launch::GetRockchipDmaHeapPath() const {
- return m_rockchip_dma_heap_path_;
-}
-
-void Launch::ConfigurationExtensionPath(const std::string& path) {
-#if defined(ISF_ENABLE_APPLE_EXTENSION)
- INSPIREFACE_CHECK_MSG(os::IsDir(path), "The apple extension path is not a directory, please check.");
-#endif
- INSPIREFACE_CHECK_MSG(os::IsExists(path), "The extension path is not exists, please check.");
- m_extension_path_ = path;
-}
-
-std::string Launch::GetExtensionPath() const {
- return m_extension_path_;
-}
-
-void Launch::SetGlobalCoreMLInferenceMode(InferenceWrapper::SpecialBackend mode) {
- m_global_coreml_inference_mode_ = mode;
- if (m_global_coreml_inference_mode_ == InferenceWrapper::COREML_CPU) {
- INSPIRE_LOGW("Global CoreML Compute Units set to CPU Only.");
- } else if (m_global_coreml_inference_mode_ == InferenceWrapper::COREML_GPU) {
- INSPIRE_LOGW("Global CoreML Compute Units set to CPU and GPU.");
- } else if (m_global_coreml_inference_mode_ == InferenceWrapper::COREML_ANE) {
- INSPIRE_LOGW("Global CoreML Compute Units set to Auto Switch (ANE, GPU, CPU).");
- }
-}
-
-InferenceWrapper::SpecialBackend Launch::GetGlobalCoreMLInferenceMode() const {
- return m_global_coreml_inference_mode_;
-}
-
-void Launch::BuildAppleExtensionPath(const std::string& resource_path) {
- std::string basename = os::Basename(resource_path);
- m_extension_path_ = os::PathJoin(os::Dirname(resource_path), basename + APPLE_EXTENSION_SUFFIX);
- INSPIREFACE_CHECK_MSG(os::IsExists(m_extension_path_), "The apple extension path is not exists, please check.");
- INSPIREFACE_CHECK_MSG(os::IsDir(m_extension_path_), "The apple extension path is not a directory, please check.");
-}
-
-void Launch::SetCudaDeviceId(int32_t device_id) {
- m_cuda_device_id_ = device_id;
-}
-
-int32_t Launch::GetCudaDeviceId() const {
- return m_cuda_device_id_;
-}
-
-} // namespace inspire
\ No newline at end of file
diff --git a/cpp-package/inspireface/cpp/inspireface/c_api/inspireface.cc b/cpp-package/inspireface/cpp/inspireface/c_api/inspireface.cc
index eec6af6..8f9db46 100644
--- a/cpp-package/inspireface/cpp/inspireface/c_api/inspireface.cc
+++ b/cpp-package/inspireface/cpp/inspireface/c_api/inspireface.cc
@@ -7,14 +7,17 @@
#include "intypedef.h"
#include "inspireface_internal.h"
#include "information.h"
-#include "feature_hub/feature_hub_db.h"
-#include "initialization_module/launch.h"
-#include "initialization_module/resource_manage.h"
-#include "recognition_module/similarity_converter.h"
+#include "feature_hub_db.h"
+#include
+#include "runtime_module/resource_manage.h"
+#include "similarity_converter.h"
#include "middleware/inference_wrapper/inference_wrapper.h"
#if defined(ISF_ENABLE_TENSORRT)
-#include "middleware/cuda_toolkit.h"
+#include "cuda_toolkit.h"
#endif
+#include
+
+#define FACE_FEATURE_SIZE 512 ///< Temporary setup
using namespace inspire;
@@ -345,6 +348,31 @@ HResult HFReleaseInspireFaceSession(HFSession handle) {
return HSUCCEED;
}
+HResult HFSwitchLandmarkEngine(HFSessionLandmarkEngine engine) {
+ inspire::Launch::LandmarkEngine type;
+ if (engine == HF_LANDMARK_HYPLMV2_0_25) {
+ type = inspire::Launch::LANDMARK_HYPLMV2_0_25;
+ } else if (engine == HF_LANDMARK_HYPLMV2_0_50) {
+ type = inspire::Launch::LANDMARK_HYPLMV2_0_50;
+ } else if (engine == HF_LANDMARK_INSIGHTFACE_2D106_TRACK) {
+ type = inspire::Launch::LANDMARK_INSIGHTFACE_2D106_TRACK;
+ } else {
+ INSPIRE_LOGE("Unsupported Landmark engine.");
+ return HERR_INVALID_PARAM;
+ }
+ INSPIREFACE_CONTEXT->SwitchLandmarkEngine(type);
+ return HSUCCEED;
+}
+
+HResult HFQuerySupportedPixelLevelsForFaceDetection(PHFFaceDetectPixelList pixel_levels) {
+ auto ret = INSPIREFACE_CONTEXT->GetFaceDetectPixelList();
+ pixel_levels->size = ret.size();
+ for (int i = 0; i < ret.size(); i++) {
+ pixel_levels->pixel_level[i] = ret[i];
+ }
+ return HSUCCEED;
+}
+
HResult HFCreateInspireFaceSession(HFSessionCustomParameter parameter, HFDetectMode detectMode, HInt32 maxDetectFaceNum, HInt32 detectPixelLevel,
HInt32 trackByDetectModeFPS, HFSession *handle) {
inspire::ContextCustomParameter param;
@@ -355,7 +383,7 @@ HResult HFCreateInspireFaceSession(HFSessionCustomParameter parameter, HFDetectM
param.enable_ir_liveness = parameter.enable_ir_liveness;
param.enable_recognition = parameter.enable_recognition;
param.enable_face_attribute = parameter.enable_face_attribute;
- param.enable_detect_mode_landmark = parameter.enable_detect_mode_landmark;
+ param.enable_face_pose = parameter.enable_face_pose;
inspire::DetectModuleMode detMode = inspire::DETECT_MODE_ALWAYS_DETECT;
if (detectMode == HF_DETECT_MODE_LIGHT_TRACK) {
detMode = inspire::DETECT_MODE_LIGHT_TRACK;
@@ -401,8 +429,8 @@ HResult HFCreateInspireFaceSessionOptional(HOption customOption, HFDetectMode de
if (customOption & HF_ENABLE_INTERACTION) {
param.enable_interaction_liveness = true;
}
- if (customOption & HF_ENABLE_DETECT_MODE_LANDMARK) {
- param.enable_detect_mode_landmark = true;
+ if (customOption & HF_ENABLE_FACE_POSE) {
+ param.enable_face_pose = true;
}
inspire::DetectModuleMode detMode = inspire::DETECT_MODE_ALWAYS_DETECT;
if (detectMode == HF_DETECT_MODE_LIGHT_TRACK) {
@@ -427,56 +455,59 @@ HResult HFCreateInspireFaceSessionOptional(HOption customOption, HFDetectMode de
HResult HFLaunchInspireFace(HPath resourcePath) {
std::string path(resourcePath);
- return INSPIRE_LAUNCH->Load(resourcePath);
+ return INSPIREFACE_CONTEXT->Load(resourcePath);
}
HResult HFReloadInspireFace(HPath resourcePath) {
std::string path(resourcePath);
- return INSPIRE_LAUNCH->Reload(resourcePath);
+ return INSPIREFACE_CONTEXT->Reload(resourcePath);
}
HResult HFTerminateInspireFace() {
- INSPIRE_LAUNCH->Unload();
+ INSPIREFACE_CONTEXT->Unload();
return HSUCCEED;
}
HResult HFQueryInspireFaceLaunchStatus(HInt32 *status) {
- *status = INSPIRE_LAUNCH->isMLoad();
+ *status = INSPIREFACE_CONTEXT->isMLoad();
return HSUCCEED;
}
HResult HFFeatureHubDataDisable() {
- return FEATURE_HUB_DB->DisableHub();
+ return INSPIREFACE_FEATURE_HUB->DisableHub();
}
HResult HFSetExpansiveHardwareRockchipDmaHeapPath(HPath path) {
- INSPIRE_LAUNCH->SetRockchipDmaHeapPath(path);
+ INSPIREFACE_CONTEXT->SetRockchipDmaHeapPath(path);
return HSUCCEED;
}
HResult HFQueryExpansiveHardwareRockchipDmaHeapPath(HString path) {
- strcpy(path, INSPIRE_LAUNCH->GetRockchipDmaHeapPath().c_str());
+ strcpy(path, INSPIREFACE_CONTEXT->GetRockchipDmaHeapPath().c_str());
return HSUCCEED;
}
HResult HFSetAppleCoreMLInferenceMode(HFAppleCoreMLInferenceMode mode) {
if (mode == HF_APPLE_COREML_INFERENCE_MODE_CPU) {
- INSPIRE_LAUNCH->SetGlobalCoreMLInferenceMode(InferenceWrapper::COREML_CPU);
+ INSPIREFACE_CONTEXT->SetGlobalCoreMLInferenceMode(inspire::Launch::NN_INFERENCE_CPU);
} else if (mode == HF_APPLE_COREML_INFERENCE_MODE_GPU) {
- INSPIRE_LAUNCH->SetGlobalCoreMLInferenceMode(InferenceWrapper::COREML_GPU);
+ INSPIREFACE_CONTEXT->SetGlobalCoreMLInferenceMode(inspire::Launch::NN_INFERENCE_COREML_GPU);
} else if (mode == HF_APPLE_COREML_INFERENCE_MODE_ANE) {
- INSPIRE_LAUNCH->SetGlobalCoreMLInferenceMode(InferenceWrapper::COREML_ANE);
+ INSPIREFACE_CONTEXT->SetGlobalCoreMLInferenceMode(inspire::Launch::NN_INFERENCE_COREML_ANE);
+ } else {
+ INSPIRE_LOGE("Unsupported Apple CoreML inference mode.");
+ return HERR_INVALID_PARAM;
}
return HSUCCEED;
}
HResult HFSetCudaDeviceId(int32_t device_id) {
- INSPIRE_LAUNCH->SetCudaDeviceId(device_id);
+ INSPIREFACE_CONTEXT->SetCudaDeviceId(device_id);
return HSUCCEED;
}
HResult HFGetCudaDeviceId(int32_t *device_id) {
- *device_id = INSPIRE_LAUNCH->GetCudaDeviceId();
+ *device_id = INSPIREFACE_CONTEXT->GetCudaDeviceId();
return HSUCCEED;
}
@@ -530,7 +561,7 @@ HResult HFFeatureHubDataEnable(HFFeatureHubConfiguration configuration) {
param.enable_persistence = configuration.enablePersistence;
param.recognition_threshold = configuration.searchThreshold;
param.search_mode = (inspire::SearchMode)configuration.searchMode;
- auto ret = FEATURE_HUB_DB->EnableHub(param);
+ auto ret = INSPIREFACE_FEATURE_HUB->EnableHub(param);
return ret;
}
@@ -545,6 +576,20 @@ HResult HFSessionSetTrackPreviewSize(HFSession session, HInt32 previewSize) {
return ctx->impl.SetTrackPreviewSize(previewSize);
}
+HResult HFSessionGetTrackPreviewSize(HFSession session, HInt32 *previewSize) {
+ if (session == nullptr) {
+ return HERR_INVALID_CONTEXT_HANDLE;
+ }
+ HF_FaceAlgorithmSession *ctx = (HF_FaceAlgorithmSession *)session;
+ if (ctx == nullptr) {
+ return HERR_INVALID_CONTEXT_HANDLE;
+ }
+ *previewSize = ctx->impl.GetTrackPreviewSize();
+ return HSUCCEED;
+}
+
+
+
HResult HFSessionSetFilterMinimumFacePixelSize(HFSession session, HInt32 minSize) {
if (session == nullptr) {
return HERR_INVALID_CONTEXT_HANDLE;
@@ -615,6 +660,8 @@ HResult HFSessionSetTrackModeDetectInterval(HFSession session, HInt32 num) {
return ctx->impl.SetTrackModeDetectInterval(num);
}
+
+
HResult HFExecuteFaceTrack(HFSession session, HFImageStream streamHandle, PHFMultipleFaceData results) {
if (session == nullptr) {
return HERR_INVALID_CONTEXT_HANDLE;
@@ -643,16 +690,28 @@ HResult HFExecuteFaceTrack(HFSession session, HFImageStream streamHandle, PHFMul
return ret;
}
+HResult HFSessionLastFaceDetectionGetDebugPreviewImageSize(HFSession session, HInt32 *size) {
+ if (session == nullptr) {
+ return HERR_INVALID_CONTEXT_HANDLE;
+ }
+ HF_FaceAlgorithmSession *ctx = (HF_FaceAlgorithmSession *)session;
+ if (ctx == nullptr) {
+ return HERR_INVALID_CONTEXT_HANDLE;
+ }
+ *size = ctx->impl.GetDebugPreviewImageSize();
+ return HSUCCEED;
+}
+
HResult HFCopyFaceBasicToken(HFFaceBasicToken token, HPBuffer buffer, HInt32 bufferSize) {
- if (bufferSize < sizeof(inspire::HyperFaceData)) {
+ if (bufferSize < sizeof(inspire::FaceTrackWrap)) {
return HERR_INVALID_BUFFER_SIZE;
}
- std::memcpy(buffer, token.data, sizeof(inspire::HyperFaceData));
+ std::memcpy(buffer, token.data, sizeof(inspire::FaceTrackWrap));
return HSUCCEED;
}
HResult HFGetFaceBasicTokenSize(HPInt32 bufferSize) {
- *bufferSize = sizeof(inspire::HyperFaceData);
+ *bufferSize = sizeof(inspire::FaceTrackWrap);
return HSUCCEED;
}
@@ -668,7 +727,7 @@ HResult HFGetFaceDenseLandmarkFromFaceToken(HFFaceBasicToken singleFace, HPoint2
inspire::FaceBasicData data;
data.dataSize = singleFace.size;
data.data = singleFace.data;
- HyperFaceData face = {0};
+ FaceTrackWrap face = {0};
HInt32 ret;
ret = RunDeserializeHyperFaceData((char *)data.data, data.dataSize, face);
if (ret != HSUCCEED) {
@@ -692,7 +751,7 @@ HResult HFGetFaceFiveKeyPointsFromFaceToken(HFFaceBasicToken singleFace, HPoint2
inspire::FaceBasicData data;
data.dataSize = singleFace.size;
data.data = singleFace.data;
- HyperFaceData face = {0};
+ FaceTrackWrap face = {0};
HInt32 ret;
ret = RunDeserializeHyperFaceData((char *)data.data, data.dataSize, face);
if (ret != HSUCCEED) {
@@ -730,7 +789,7 @@ HResult HFSessionPrintTrackCostSpend(HFSession session) {
}
HResult HFFeatureHubFaceSearchThresholdSetting(float threshold) {
- FEATURE_HUB_DB->SetRecognitionThreshold(threshold);
+ INSPIREFACE_FEATURE_HUB->SetRecognitionThreshold(threshold);
return HSUCCEED;
}
@@ -762,6 +821,35 @@ HResult HFFaceFeatureExtract(HFSession session, HFImageStream streamHandle, HFFa
return ret;
}
+HResult HFFaceFeatureExtractTo(HFSession session, HFImageStream streamHandle, HFFaceBasicToken singleFace, HFFaceFeature feature) {
+ if (session == nullptr) {
+ return HERR_INVALID_CONTEXT_HANDLE;
+ }
+ if (streamHandle == nullptr) {
+ return HERR_INVALID_IMAGE_STREAM_HANDLE;
+ }
+ HF_FaceAlgorithmSession *ctx = (HF_FaceAlgorithmSession *)session;
+ if (ctx == nullptr) {
+ return HERR_INVALID_CONTEXT_HANDLE;
+ }
+ HF_CameraStream *stream = (HF_CameraStream *)streamHandle;
+ if (stream == nullptr) {
+ return HERR_INVALID_IMAGE_STREAM_HANDLE;
+ }
+ if (singleFace.data == nullptr || singleFace.size <= 0) {
+ return HERR_INVALID_FACE_TOKEN;
+ }
+ inspire::FaceBasicData data;
+ data.dataSize = singleFace.size;
+ data.data = singleFace.data;
+ auto ret = ctx->impl.FaceFeatureExtract(stream->impl, data);
+ for (int i = 0; i < ctx->impl.GetFaceFeatureCache().size(); ++i) {
+ feature.data[i] = ctx->impl.GetFaceFeatureCache()[i];
+ }
+
+ return HSUCCEED;
+}
+
HResult HFFaceFeatureExtractCpy(HFSession session, HFImageStream streamHandle, HFFaceBasicToken singleFace, HPFloat feature) {
if (session == nullptr) {
return HERR_INVALID_CONTEXT_HANDLE;
@@ -791,6 +879,25 @@ HResult HFFaceFeatureExtractCpy(HFSession session, HFImageStream streamHandle, H
return ret;
}
+HResult HFCreateFaceFeature(PHFFaceFeature feature) {
+ if (feature == nullptr) {
+ return HERR_INVALID_FACE_FEATURE;
+ }
+ feature->size = FACE_FEATURE_SIZE;
+ feature->data = new HFloat[FACE_FEATURE_SIZE];
+ RESOURCE_MANAGE->createFaceFeature((long)feature);
+ return HSUCCEED;
+}
+
+HResult HFReleaseFaceFeature(PHFFaceFeature feature) {
+ if (feature == nullptr) {
+ return HERR_INVALID_FACE_FEATURE;
+ }
+ delete[] feature->data;
+ RESOURCE_MANAGE->releaseFaceFeature((long)feature);
+ return HSUCCEED;
+}
+
HResult HFFaceGetFaceAlignmentImage(HFSession session, HFImageStream streamHandle, HFFaceBasicToken singleFace, HFImageBitmap *handle) {
if (session == nullptr) {
return HERR_INVALID_CONTEXT_HANDLE;
@@ -824,6 +931,30 @@ HResult HFFaceGetFaceAlignmentImage(HFSession session, HFImageStream streamHandl
return HSUCCEED;
}
+HResult HFFaceFeatureExtractWithAlignmentImage(HFSession session, HFImageStream streamHandle, HFFaceFeature feature) {
+ if (session == nullptr) {
+ return HERR_INVALID_CONTEXT_HANDLE;
+ }
+ if (streamHandle == nullptr) {
+ return HERR_INVALID_IMAGE_STREAM_HANDLE;
+ }
+ HF_FaceAlgorithmSession *ctx = (HF_FaceAlgorithmSession *)session;
+ if (ctx == nullptr) {
+ return HERR_INVALID_CONTEXT_HANDLE;
+ }
+ HF_CameraStream *stream = (HF_CameraStream *)streamHandle;
+ if (stream == nullptr) {
+ return HERR_INVALID_IMAGE_STREAM_HANDLE;
+ }
+ Embedded embedded;
+ float norm;
+ auto ret = ctx->impl.FaceRecognitionModule()->FaceExtractWithAlignmentImage(stream->impl, embedded, norm);
+ for (int i = 0; i < embedded.size(); ++i) {
+ feature.data[i] = embedded[i];
+ }
+ return ret;
+}
+
HResult HFFaceComparison(HFFaceFeature feature1, HFFaceFeature feature2, HPFloat result) {
if (feature1.data == nullptr || feature2.data == nullptr) {
return HERR_INVALID_FACE_FEATURE;
@@ -834,14 +965,14 @@ HResult HFFaceComparison(HFFaceFeature feature1, HFFaceFeature feature2, HPFloat
}
*result = 0.0f;
float res = -1.0f;
- auto ret = FEATURE_HUB_DB->CosineSimilarity(feature1.data, feature2.data, feature1.size, res);
+ auto ret = INSPIREFACE_FEATURE_HUB->CosineSimilarity(feature1.data, feature2.data, feature1.size, res);
*result = res;
return ret;
}
HResult HFGetRecommendedCosineThreshold(HPFloat threshold) {
- if (!INSPIRE_LAUNCH->isMLoad()) {
+ if (!INSPIREFACE_CONTEXT->isMLoad()) {
INSPIRE_LOGW("Inspireface is not launched, using default threshold 0.48");
}
*threshold = SIMILARITY_CONVERTER_GET_RECOMMENDED_COSINE_THRESHOLD();
@@ -849,7 +980,7 @@ HResult HFGetRecommendedCosineThreshold(HPFloat threshold) {
}
HResult HFCosineSimilarityConvertToPercentage(HFloat similarity, HPFloat result) {
- if (!INSPIRE_LAUNCH->isMLoad()) {
+ if (!INSPIREFACE_CONTEXT->isMLoad()) {
INSPIRE_LOGW("Inspireface is not launched.");
}
*result = SIMILARITY_CONVERTER_RUN(similarity);
@@ -857,7 +988,7 @@ HResult HFCosineSimilarityConvertToPercentage(HFloat similarity, HPFloat result)
}
HResult HFUpdateCosineSimilarityConverter(HFSimilarityConverterConfig config) {
- if (!INSPIRE_LAUNCH->isMLoad()) {
+ if (!INSPIREFACE_CONTEXT->isMLoad()) {
INSPIRE_LOGW("Inspireface is not launched.");
}
inspire::SimilarityConverterConfig cfg;
@@ -871,7 +1002,7 @@ HResult HFUpdateCosineSimilarityConverter(HFSimilarityConverterConfig config) {
}
HResult HFGetCosineSimilarityConverter(PHFSimilarityConverterConfig config) {
- if (!INSPIRE_LAUNCH->isMLoad()) {
+ if (!INSPIREFACE_CONTEXT->isMLoad()) {
INSPIRE_LOGW("Inspireface is not launched.");
}
inspire::SimilarityConverterConfig cfg = SIMILARITY_CONVERTER_GET_CONFIG();
@@ -884,7 +1015,7 @@ HResult HFGetCosineSimilarityConverter(PHFSimilarityConverterConfig config) {
}
HResult HFGetFeatureLength(HPInt32 num) {
- *num = 512;
+ *num = FACE_FEATURE_SIZE;
return HSUCCEED;
}
@@ -898,7 +1029,7 @@ HResult HFFeatureHubInsertFeature(HFFaceFeatureIdentity featureIdentity, HPFaceI
for (int i = 0; i < featureIdentity.feature->size; ++i) {
feat.push_back(featureIdentity.feature->data[i]);
}
- HInt32 ret = FEATURE_HUB_DB->FaceFeatureInsert(feat, featureIdentity.id, *allocId);
+ HInt32 ret = INSPIREFACE_FEATURE_HUB->FaceFeatureInsert(feat, featureIdentity.id, *allocId);
return ret;
}
@@ -914,10 +1045,10 @@ HResult HFFeatureHubFaceSearch(HFFaceFeature searchFeature, HPFloat confidence,
}
*confidence = -1.0f;
inspire::FaceSearchResult result;
- HInt32 ret = FEATURE_HUB_DB->SearchFaceFeature(feat, result);
- mostSimilar->feature = (HFFaceFeature *)FEATURE_HUB_DB->GetFaceFeaturePtrCache().get();
- mostSimilar->feature->data = (HFloat *)FEATURE_HUB_DB->GetSearchFaceFeatureCache().data();
- mostSimilar->feature->size = FEATURE_HUB_DB->GetSearchFaceFeatureCache().size();
+ HInt32 ret = INSPIREFACE_FEATURE_HUB->SearchFaceFeature(feat, result);
+ mostSimilar->feature = (HFFaceFeature *)INSPIREFACE_FEATURE_HUB->GetFaceFeaturePtrCache().get();
+ mostSimilar->feature->data = (HFloat *)INSPIREFACE_FEATURE_HUB->GetSearchFaceFeatureCache().data();
+ mostSimilar->feature->size = INSPIREFACE_FEATURE_HUB->GetSearchFaceFeatureCache().size();
mostSimilar->id = result.id;
if (mostSimilar->id != -1) {
*confidence = result.similarity;
@@ -935,18 +1066,18 @@ HResult HFFeatureHubFaceSearchTopK(HFFaceFeature searchFeature, HInt32 topK, PHF
for (int i = 0; i < searchFeature.size; ++i) {
feat.push_back(searchFeature.data[i]);
}
- HInt32 ret = FEATURE_HUB_DB->SearchFaceFeatureTopKCache(feat, topK);
+ HInt32 ret = INSPIREFACE_FEATURE_HUB->SearchFaceFeatureTopKCache(feat, topK);
if (ret == HSUCCEED) {
- results->size = FEATURE_HUB_DB->GetTopKConfidence().size();
- results->confidence = FEATURE_HUB_DB->GetTopKConfidence().data();
- results->ids = FEATURE_HUB_DB->GetTopKCustomIdsCache().data();
+ results->size = INSPIREFACE_FEATURE_HUB->GetTopKConfidence().size();
+ results->confidence = INSPIREFACE_FEATURE_HUB->GetTopKConfidence().data();
+ results->ids = INSPIREFACE_FEATURE_HUB->GetTopKCustomIdsCache().data();
}
return ret;
}
HResult HFFeatureHubFaceRemove(HFaceId id) {
- auto ret = FEATURE_HUB_DB->FaceFeatureRemove(id);
+ auto ret = INSPIREFACE_FEATURE_HUB->FaceFeatureRemove(id);
return ret;
}
@@ -960,18 +1091,18 @@ HResult HFFeatureHubFaceUpdate(HFFaceFeatureIdentity featureIdentity) {
feat.push_back(featureIdentity.feature->data[i]);
}
- auto ret = FEATURE_HUB_DB->FaceFeatureUpdate(feat, featureIdentity.id);
+ auto ret = INSPIREFACE_FEATURE_HUB->FaceFeatureUpdate(feat, featureIdentity.id);
return ret;
}
HResult HFFeatureHubGetFaceIdentity(HFaceId id, PHFFaceFeatureIdentity identity) {
- auto ret = FEATURE_HUB_DB->GetFaceFeature(id);
+ auto ret = INSPIREFACE_FEATURE_HUB->GetFaceFeature(id);
if (ret == HSUCCEED) {
identity->id = id;
- identity->feature = (HFFaceFeature *)FEATURE_HUB_DB->GetFaceFeaturePtrCache().get();
- identity->feature->data = (HFloat *)FEATURE_HUB_DB->GetFaceFeaturePtrCache()->data;
- identity->feature->size = FEATURE_HUB_DB->GetFaceFeaturePtrCache()->dataSize;
+ identity->feature = (HFFaceFeature *)INSPIREFACE_FEATURE_HUB->GetFaceFeaturePtrCache().get();
+ identity->feature->data = (HFloat *)INSPIREFACE_FEATURE_HUB->GetFaceFeaturePtrCache()->data;
+ identity->feature->size = INSPIREFACE_FEATURE_HUB->GetFaceFeaturePtrCache()->dataSize;
} else {
identity->id = -1;
}
@@ -1010,10 +1141,9 @@ HResult HFMultipleFacePipelineProcess(HFSession session, HFImageStream streamHan
param.enable_ir_liveness = parameter.enable_ir_liveness;
param.enable_recognition = parameter.enable_recognition;
param.enable_face_attribute = parameter.enable_face_attribute;
- param.enable_detect_mode_landmark = parameter.enable_detect_mode_landmark;
HResult ret;
- std::vector data;
+ std::vector data;
data.resize(faces->detectedNum);
for (int i = 0; i < faces->detectedNum; ++i) {
auto &face = data[i];
@@ -1072,12 +1202,12 @@ HResult HFMultipleFacePipelineProcessOptional(HFSession session, HFImageStream s
if (customOption & HF_ENABLE_INTERACTION) {
param.enable_interaction_liveness = true;
}
- if (customOption & HF_ENABLE_DETECT_MODE_LANDMARK) {
- param.enable_detect_mode_landmark = true;
+ if (customOption & HF_ENABLE_FACE_POSE) {
+ param.enable_face_pose = true;
}
HResult ret;
- std::vector data;
+ std::vector data;
data.resize(faces->detectedNum);
for (int i = 0; i < faces->detectedNum; ++i) {
auto &face = data[i];
@@ -1206,20 +1336,20 @@ HResult HFGetFaceAttributeResult(HFSession session, PHFFaceAttributeResult resul
}
HResult HFFeatureHubGetFaceCount(HInt32 *count) {
- *count = FEATURE_HUB_DB->GetFaceFeatureCount();
+ *count = INSPIREFACE_FEATURE_HUB->GetFaceFeatureCount();
return HSUCCEED;
}
HResult HFFeatureHubViewDBTable() {
- FEATURE_HUB_DB->ViewDBTable();
+ INSPIREFACE_FEATURE_HUB->ViewDBTable();
return HSUCCEED;
}
HResult HFFeatureHubGetExistingIds(PHFFeatureHubExistingIds ids) {
- auto ret = FEATURE_HUB_DB->GetAllIds();
+ auto ret = INSPIREFACE_FEATURE_HUB->GetAllIds();
if (ret == HSUCCEED) {
- ids->size = FEATURE_HUB_DB->GetExistingIds().size();
- ids->ids = FEATURE_HUB_DB->GetExistingIds().data();
+ ids->size = INSPIREFACE_FEATURE_HUB->GetExistingIds().size();
+ ids->ids = INSPIREFACE_FEATURE_HUB->GetExistingIds().data();
}
return ret;
}
diff --git a/cpp-package/inspireface/cpp/inspireface/c_api/inspireface.h b/cpp-package/inspireface/cpp/inspireface/c_api/inspireface.h
index 65b3432..675cf80 100644
--- a/cpp-package/inspireface/cpp/inspireface/c_api/inspireface.h
+++ b/cpp-package/inspireface/cpp/inspireface/c_api/inspireface.h
@@ -24,16 +24,19 @@
extern "C" {
#endif
-#define HF_ENABLE_NONE 0x00000000 ///< Flag to enable no features.
-#define HF_ENABLE_FACE_RECOGNITION 0x00000002 ///< Flag to enable face recognition feature.
-#define HF_ENABLE_LIVENESS 0x00000004 ///< Flag to enable RGB liveness detection feature.
-#define HF_ENABLE_IR_LIVENESS 0x00000008 ///< Flag to enable IR (Infrared) liveness detection feature.
-#define HF_ENABLE_MASK_DETECT 0x00000010 ///< Flag to enable mask detection feature.
-#define HF_ENABLE_FACE_ATTRIBUTE 0x00000020 ///< Flag to enable face attribute prediction feature.
-#define HF_ENABLE_PLACEHOLDER_ 0x00000040 ///< -
-#define HF_ENABLE_QUALITY 0x00000080 ///< Flag to enable face quality assessment feature.
-#define HF_ENABLE_INTERACTION 0x00000100 ///< Flag to enable interaction feature.
-#define HF_ENABLE_DETECT_MODE_LANDMARK 0x00000200 ///< Flag to enable landmark detection in detection mode
+#define HF_STATUS_ENABLE 1 ///< The status of the feature is enabled.
+#define HF_STATUS_DISABLE 0 ///< The status of the feature is disabled.
+
+#define HF_ENABLE_NONE 0x00000000 ///< Flag to enable no features.
+#define HF_ENABLE_FACE_RECOGNITION 0x00000002 ///< Flag to enable face recognition feature.
+#define HF_ENABLE_LIVENESS 0x00000004 ///< Flag to enable RGB liveness detection feature.
+#define HF_ENABLE_IR_LIVENESS 0x00000008 ///< Flag to enable IR (Infrared) liveness detection feature.
+#define HF_ENABLE_MASK_DETECT 0x00000010 ///< Flag to enable mask detection feature.
+#define HF_ENABLE_FACE_ATTRIBUTE 0x00000020 ///< Flag to enable face attribute prediction feature.
+#define HF_ENABLE_PLACEHOLDER_ 0x00000040 ///< -
+#define HF_ENABLE_QUALITY 0x00000080 ///< Flag to enable face quality assessment feature.
+#define HF_ENABLE_INTERACTION 0x00000100 ///< Flag to enable interaction feature.
+#define HF_ENABLE_FACE_POSE 0x00000200 ///< Flag to enable face pose estimation feature.
/**
* Camera stream format.
@@ -385,6 +388,7 @@ typedef struct HFSessionCustomParameter {
HInt32 enable_face_attribute; ///< Enable face attribute prediction feature.
HInt32 enable_interaction_liveness; ///< Enable interaction for liveness detection feature.
HInt32 enable_detect_mode_landmark; ///< Enable landmark detection in detection mode
+ HInt32 enable_face_pose; ///< Enable face pose estimation feature.
} HFSessionCustomParameter, *PHFSessionCustomParameter;
/**
@@ -400,6 +404,38 @@ typedef enum HFDetectMode {
// to use it).
} HFDetectMode;
+/**
+ * @brief Enum for landmark engine.
+ */
+typedef enum HFSessionLandmarkEngine {
+ HF_LANDMARK_HYPLMV2_0_25 = 0, ///< Hyplmkv2 0.25, default
+ HF_LANDMARK_HYPLMV2_0_50 = 1, ///< Hyplmkv2 0.50
+ HF_LANDMARK_INSIGHTFACE_2D106_TRACK = 2, ///< InsightFace 2d106 track
+} HFSessionLandmarkEngine;
+
+/**
+ * @brief Global switch the landmark engine. Set it globally before creating a session.
+ * If it is changed, a new session needs to be created for it to be effective.
+ * @param engine The landmark engine to be set.
+ * @return HResult indicating the success or failure of the operation.
+ * */
+HYPER_CAPI_EXPORT extern HResult HFSwitchLandmarkEngine(HFSessionLandmarkEngine engine);
+
+/**
+ * @brief Enum for supported pixel levels for face detection.
+ */
+typedef struct HFFaceDetectPixelList {
+ HInt32 pixel_level[20];
+ HInt32 size;
+} HFFaceDetectPixelList, *PHFFaceDetectPixelList;
+
+/**
+ * @brief Query the supported pixel levels for face detection. It must be used before starting.
+ * @param pixel_levels Pointer to the array of supported pixel levels.
+ * @return HResult indicating the success or failure of the operation.
+ * */
+HYPER_CAPI_EXPORT extern HResult HFQuerySupportedPixelLevelsForFaceDetection(PHFFaceDetectPixelList pixel_levels);
+
/**
* @brief Create a session from a resource file.
*
@@ -488,6 +524,14 @@ typedef struct HFMultipleFaceData {
*/
HYPER_CAPI_EXPORT extern HResult HFSessionSetTrackPreviewSize(HFSession session, HInt32 previewSize);
+/**
+ * @brief Get the track preview size in the session.
+ * @param session Handle to the session.
+ * @param previewSize The size of the preview for tracking.
+ * @return HResult indicating the success or failure of the operation.
+ */
+HYPER_CAPI_EXPORT extern HResult HFSessionGetTrackPreviewSize(HFSession session, HInt32 *previewSize);
+
/**
* @brief Set the minimum number of face pixels that the face detector can capture, and people below
* this number will be filtered.
@@ -534,6 +578,7 @@ HYPER_CAPI_EXPORT extern HResult HFSessionSetTrackModeNumSmoothCacheFrame(HFSess
*/
HYPER_CAPI_EXPORT extern HResult HFSessionSetTrackModeDetectInterval(HFSession session, HInt32 num);
+
/**
* @brief Run face tracking in the session.
*
@@ -544,6 +589,14 @@ HYPER_CAPI_EXPORT extern HResult HFSessionSetTrackModeDetectInterval(HFSession s
*/
HYPER_CAPI_EXPORT extern HResult HFExecuteFaceTrack(HFSession session, HFImageStream streamHandle, PHFMultipleFaceData results);
+/**
+ * @brief Gets the size of the debug preview image for the last face detection in the session.
+ * @param session Handle to the session.
+ * @param size The size of the preview for tracking.
+ * @return HResult indicating the success or failure of the operation.
+ */
+HYPER_CAPI_EXPORT extern HResult HFSessionLastFaceDetectionGetDebugPreviewImageSize(HFSession session, HInt32 *size);
+
/**
* @brief Copies the data from a HF_FaceBasicToken to a specified buffer.
*
@@ -641,6 +694,17 @@ typedef struct HFFaceFeature {
HYPER_CAPI_EXPORT extern HResult HFFaceFeatureExtract(HFSession session, HFImageStream streamHandle, HFFaceBasicToken singleFace,
PHFFaceFeature feature);
+/**
+ * @brief Extract face features to the HFFaceFeature that has applied for memory in advance.
+ * @param session Handle to the session.
+ * @param streamHandle Handle to the data buffer representing the camera stream component.
+ * @param singleFace Basic token representing a single face.
+ * @param feature Pointer to the buffer where the extracted feature will be copied.
+ * @return HResult indicating the success or failure of the operation.
+ */
+HYPER_CAPI_EXPORT extern HResult HFFaceFeatureExtractTo(HFSession session, HFImageStream streamHandle, HFFaceBasicToken singleFace,
+ HFFaceFeature feature);
+
/**
* @brief Extract a face feature from a given face and copy it to the provided feature buffer.
*
@@ -652,6 +716,20 @@ HYPER_CAPI_EXPORT extern HResult HFFaceFeatureExtract(HFSession session, HFImage
*/
HYPER_CAPI_EXPORT extern HResult HFFaceFeatureExtractCpy(HFSession session, HFImageStream streamHandle, HFFaceBasicToken singleFace, HPFloat feature);
+/**
+ * @brief Create a face feature. Will allocate memory.
+ * @param feature Pointer to the face feature.
+ * @return HResult indicating the success or failure of the operation.
+ */
+HYPER_CAPI_EXPORT extern HResult HFCreateFaceFeature(PHFFaceFeature feature);
+
+/**
+ * @brief Release a face feature. Only the features created through the HFCreateFaceFeature need to be processed.
+ * @param feature Pointer to the face feature.
+ * @return HResult indicating the success or failure of the operation.
+ */
+HYPER_CAPI_EXPORT extern HResult HFReleaseFaceFeature(PHFFaceFeature feature);
+
/**
* @brief Get the face alignment image.
* @param session Handle to the session.
@@ -663,6 +741,15 @@ HYPER_CAPI_EXPORT extern HResult HFFaceFeatureExtractCpy(HFSession session, HFIm
HYPER_CAPI_EXPORT extern HResult HFFaceGetFaceAlignmentImage(HFSession session, HFImageStream streamHandle, HFFaceBasicToken singleFace,
HFImageBitmap *handle);
+/**
+ * @brief Use the aligned face image to extract face features to the HFFaceFeature that has applied memory in advance.
+ * @param session Handle to the session.
+ * @param streamHandle Handle to the data buffer representing the camera stream component.
+ * @param feature Pointer to the buffer where the extracted feature will be copied.
+ * @return HResult indicating the success or failure of the operation.
+ */
+HYPER_CAPI_EXPORT extern HResult HFFaceFeatureExtractWithAlignmentImage(HFSession session, HFImageStream streamHandle, HFFaceFeature feature);
+
/************************************************************************
* Feature Hub
************************************************************************/
@@ -851,7 +938,7 @@ HYPER_CAPI_EXPORT extern HResult HFFeatureHubFaceSearchTopK(HFFaceFeature search
/**
* @brief Remove a face feature from the features group based on custom ID.
*
- * @param customId The custom ID of the feature to be removed.
+ * @param ID The custom ID of the feature to be removed.
* @return HResult indicating the success or failure of the operation.
*/
HYPER_CAPI_EXPORT extern HResult HFFeatureHubFaceRemove(HFaceId id);
diff --git a/cpp-package/inspireface/cpp/inspireface/c_api/inspireface_internal.h b/cpp-package/inspireface/cpp/inspireface/c_api/inspireface_internal.h
index cf770c9..7d92f58 100644
--- a/cpp-package/inspireface/cpp/inspireface/c_api/inspireface_internal.h
+++ b/cpp-package/inspireface/cpp/inspireface/c_api/inspireface_internal.h
@@ -6,15 +6,15 @@
#ifndef INSPIREFACE_INTERNAL_H
#define INSPIREFACE_INTERNAL_H
-#include "face_session.h"
+#include "engine/face_session.h"
typedef struct HF_FaceAlgorithmSession {
inspire::FaceSession impl; ///< Implementation of the face context.
} HF_FaceAlgorithmSession; ///< Handle for managing face context.
typedef struct HF_CameraStream {
- inspirecv::InspireImageProcess impl; ///< Implementation of the camera stream.
-} HF_CameraStream; ///< Handle for managing camera stream.
+ inspirecv::FrameProcess impl; ///< Implementation of the camera stream.
+} HF_CameraStream; ///< Handle for managing camera stream.
typedef struct HF_ImageBitmap {
inspirecv::Image impl; ///< Implementation of the image bitmap.
diff --git a/cpp-package/inspireface/cpp/inspireface/common/face_data/face_serialize_tools.h b/cpp-package/inspireface/cpp/inspireface/common/face_data/face_serialize_tools.h
index bf9dd93..dd53df7 100644
--- a/cpp-package/inspireface/cpp/inspireface/common/face_data/face_serialize_tools.h
+++ b/cpp-package/inspireface/cpp/inspireface/common/face_data/face_serialize_tools.h
@@ -6,7 +6,7 @@
#ifndef INSPIRE_FACE_SERIALIZE_TOOLS_H
#define INSPIRE_FACE_SERIALIZE_TOOLS_H
-#include "face_data_type.h"
+#include "face_warpper.h"
#include "../face_info/face_object_internal.h"
#include "herror.h"
#include "data_type.h"
@@ -27,10 +27,10 @@ inline void PrintTransformMatrix(const TransMatrix& matrix) {
}
/**
- * @brief Print HyperFaceData structure.
- * @param data The HyperFaceData structure to print.
+ * @brief Print FaceTrackWrap structure.
+ * @param data The FaceTrackWrap structure to print.
*/
-inline void INSPIRE_API PrintHyperFaceDataDetail(const HyperFaceData& data) {
+inline void INSPIRE_API PrintHyperFaceDataDetail(const FaceTrackWrap& data) {
INSPIRE_LOGI("Track State: %d", data.trackState);
INSPIRE_LOGI("In Group Index: %d", data.inGroupIndex);
INSPIRE_LOGI("Track ID: %d", data.trackId);
@@ -43,13 +43,13 @@ inline void INSPIRE_API PrintHyperFaceDataDetail(const HyperFaceData& data) {
}
/**
- * @brief Convert a FaceObject to HyperFaceData.
+ * @brief Convert a FaceObject to FaceTrackWrap.
* @param obj The FaceObject to convert.
* @param group_index The group index.
- * @return The converted HyperFaceData structure.
+ * @return The converted FaceTrackWrap structure.
*/
-inline HyperFaceData INSPIRE_API FaceObjectInternalToHyperFaceData(const FaceObjectInternal& obj, int group_index = -1) {
- HyperFaceData data;
+inline FaceTrackWrap INSPIRE_API FaceObjectInternalToHyperFaceData(const FaceObjectInternal& obj, int group_index = -1) {
+ FaceTrackWrap data;
// Face rect
data.rect.x = obj.bbox_.GetX();
data.rect.y = obj.bbox_.GetY();
@@ -134,15 +134,15 @@ inline inspirecv::Point2f INSPIRE_API HPointToInternalPoint2f(const Point2F& poi
}
/**
- * @brief Serialize HyperFaceData to a byte stream.
- * @param data The HyperFaceData to serialize.
+ * @brief Serialize FaceTrackWrap to a byte stream.
+ * @param data The FaceTrackWrap to serialize.
* @param byteArray The output byte stream.
* @return The result code.
*/
-inline int32_t INSPIRE_API RunSerializeHyperFaceData(const HyperFaceData& data, ByteArray& byteArray) {
+inline int32_t INSPIRE_API RunSerializeHyperFaceData(const FaceTrackWrap& data, ByteArray& byteArray) {
byteArray.reserve(sizeof(data));
- // Serialize the HyperFaceData structure itself
+ // Serialize the FaceTrackWrap structure itself
const char* dataBytes = reinterpret_cast(&data);
byteArray.insert(byteArray.end(), dataBytes, dataBytes + sizeof(data));
@@ -150,18 +150,18 @@ inline int32_t INSPIRE_API RunSerializeHyperFaceData(const HyperFaceData& data,
}
/**
- * @brief Deserialize a byte stream to HyperFaceData.
+ * @brief Deserialize a byte stream to FaceTrackWrap.
* @param byteArray The input byte stream.
- * @param data The output HyperFaceData structure.
+ * @param data The output FaceTrackWrap structure.
* @return The result code.
*/
-inline int32_t INSPIRE_API RunDeserializeHyperFaceData(const ByteArray& byteArray, HyperFaceData& data) {
+inline int32_t INSPIRE_API RunDeserializeHyperFaceData(const ByteArray& byteArray, FaceTrackWrap& data) {
// Check if the byte stream size is sufficient
if (byteArray.size() >= sizeof(data)) {
- // Copy data from the byte stream to the HyperFaceData structure
+ // Copy data from the byte stream to the FaceTrackWrap structure
std::memcpy(&data, byteArray.data(), sizeof(data));
} else {
- INSPIRE_LOGE("The byte stream size is insufficient to restore HyperFaceData");
+ INSPIRE_LOGE("The byte stream size is insufficient to restore FaceTrackWrap");
return HERR_SESS_FACE_DATA_ERROR;
}
@@ -169,19 +169,19 @@ inline int32_t INSPIRE_API RunDeserializeHyperFaceData(const ByteArray& byteArra
}
/**
- * @brief Deserialize a byte stream to HyperFaceData.
+ * @brief Deserialize a byte stream to FaceTrackWrap.
* @param byteArray The input byte stream as a character array.
* @param byteCount The size of the byte stream.
- * @param data The output HyperFaceData structure.
+ * @param data The output FaceTrackWrap structure.
* @return The result code.
*/
-inline int32_t INSPIRE_API RunDeserializeHyperFaceData(const char* byteArray, size_t byteCount, HyperFaceData& data) {
+inline int32_t INSPIRE_API RunDeserializeHyperFaceData(const char* byteArray, size_t byteCount, FaceTrackWrap& data) {
// Check if the byte stream size is sufficient
if (byteCount >= sizeof(data)) {
- // Copy data from the byte stream to the HyperFaceData structure
+ // Copy data from the byte stream to the FaceTrackWrap structure
std::memcpy(&data, byteArray, sizeof(data));
} else {
- INSPIRE_LOGE("The byte stream size is insufficient to restore HyperFaceData");
+ INSPIRE_LOGE("The byte stream size is insufficient to restore FaceTrackWrap");
return HERR_SESS_FACE_DATA_ERROR;
}
diff --git a/cpp-package/inspireface/cpp/inspireface/common/face_info/face_action_data.h b/cpp-package/inspireface/cpp/inspireface/common/face_info/face_action_data.h
index 178096b..189a47c 100644
--- a/cpp-package/inspireface/cpp/inspireface/common/face_info/face_action_data.h
+++ b/cpp-package/inspireface/cpp/inspireface/common/face_info/face_action_data.h
@@ -48,7 +48,7 @@ public:
index = 0;
}
- FaceActionList AnalysisFaceAction() {
+ FaceActionList AnalysisFaceAction(const SemanticIndex& semantic_index) {
FaceActionList actionRecord;
actions.clear();
eye_state_list.clear();
@@ -64,8 +64,8 @@ public:
// count mouth aspect ratio
- float mouth_widthwise_d = record_list[0][FaceLandmarkAdapt::MOUTH_LEFT_CORNER].Distance(record_list[0][FaceLandmarkAdapt::MOUTH_RIGHT_CORNER]);
- float mouth_heightwise_d = record_list[0][FaceLandmarkAdapt::MOUTH_UPPER].Distance(record_list[0][FaceLandmarkAdapt::MOUTH_LOWER]);
+ float mouth_widthwise_d = record_list[0][semantic_index.mouth_left_corner].Distance(record_list[0][semantic_index.mouth_right_corner]);
+ float mouth_heightwise_d = record_list[0][semantic_index.mouth_upper].Distance(record_list[0][semantic_index.mouth_lower]);
float mouth_aspect_ratio = mouth_heightwise_d / mouth_widthwise_d;
if (mouth_aspect_ratio > 0.3) {
actions.push_back(ACT_JAW_OPEN);
diff --git a/cpp-package/inspireface/cpp/inspireface/common/face_info/face_object_internal.h b/cpp-package/inspireface/cpp/inspireface/common/face_info/face_object_internal.h
index 7ea130d..0449298 100755
--- a/cpp-package/inspireface/cpp/inspireface/common/face_info/face_object_internal.h
+++ b/cpp-package/inspireface/cpp/inspireface/common/face_info/face_object_internal.h
@@ -9,6 +9,7 @@
#include "face_process.h"
#include "face_action_data.h"
#include "track_module/quality/face_pose_quality_adapt.h"
+#include "track_module/landmark/landmark_param.h"
namespace inspire {
@@ -109,11 +110,11 @@ public:
return box_square;
}
- FaceActionList UpdateFaceAction() {
+ FaceActionList UpdateFaceAction(const SemanticIndex& semantic_index) {
inspirecv::Vec3f euler{high_result.pitch, high_result.yaw, high_result.roll};
inspirecv::Vec2f eyes{left_eye_status_.back(), right_eye_status_.back()};
face_action_->RecordActionFrame(landmark_, euler, eyes);
- return face_action_->AnalysisFaceAction();
+ return face_action_->AnalysisFaceAction(semantic_index);
}
void DisableTracking() {
diff --git a/cpp-package/inspireface/cpp/inspireface/face_session.cpp b/cpp-package/inspireface/cpp/inspireface/engine/face_session.cpp
similarity index 84%
rename from cpp-package/inspireface/cpp/inspireface/face_session.cpp
rename to cpp-package/inspireface/cpp/inspireface/engine/face_session.cpp
index 4df93fc..2c94415 100644
--- a/cpp-package/inspireface/cpp/inspireface/face_session.cpp
+++ b/cpp-package/inspireface/cpp/inspireface/engine/face_session.cpp
@@ -4,7 +4,7 @@
*/
#include "face_session.h"
-#include "initialization_module/launch.h"
+#include
#include
#include "log.h"
#include "herror.h"
@@ -20,35 +20,30 @@ int32_t FaceSession::Configuration(DetectModuleMode detect_mode, int32_t max_det
m_detect_mode_ = detect_mode;
m_max_detect_face_ = max_detect_face;
m_parameter_ = param;
- if (!INSPIRE_LAUNCH->isMLoad()) {
+ if (!INSPIREFACE_CONTEXT->isMLoad()) {
return HERR_ARCHIVE_NOT_LOAD;
}
- if (INSPIRE_LAUNCH->getMArchive().QueryStatus() != SARC_SUCCESS) {
+ if (INSPIREFACE_CONTEXT->getMArchive().QueryStatus() != SARC_SUCCESS) {
return HERR_ARCHIVE_LOAD_FAILURE;
}
- if (m_parameter_.enable_interaction_liveness) {
- m_parameter_.enable_detect_mode_landmark = true;
- }
-
- m_face_track_ = std::make_shared(m_detect_mode_, m_max_detect_face_, 20, 192, detect_level_px, track_by_detect_mode_fps,
- m_parameter_.enable_detect_mode_landmark);
- m_face_track_->Configuration(INSPIRE_LAUNCH->getMArchive());
+ m_face_track_ = std::make_shared(m_detect_mode_, m_max_detect_face_, 20, 192, detect_level_px, track_by_detect_mode_fps, true);
+ m_face_track_->Configuration(INSPIREFACE_CONTEXT->getMArchive(), "", m_parameter_.enable_face_pose || m_parameter_.enable_face_quality);
// SetDetectMode(m_detect_mode_);
- m_face_recognition_ = std::make_shared(INSPIRE_LAUNCH->getMArchive(), m_parameter_.enable_recognition);
+ m_face_recognition_ = std::make_shared(INSPIREFACE_CONTEXT->getMArchive(), m_parameter_.enable_recognition);
if (m_face_recognition_->QueryStatus() != HSUCCEED) {
return m_face_recognition_->QueryStatus();
}
- m_face_pipeline_ = std::make_shared(INSPIRE_LAUNCH->getMArchive(), param.enable_liveness, param.enable_mask_detect,
+ m_face_pipeline_ = std::make_shared(INSPIREFACE_CONTEXT->getMArchive(), param.enable_liveness, param.enable_mask_detect,
param.enable_face_attribute, param.enable_interaction_liveness);
- m_face_track_cost_ = std::make_shared("FaceTrack");
+ m_face_track_cost_ = std::make_shared("FaceTrack");
return HSUCCEED;
}
-int32_t FaceSession::FaceDetectAndTrack(inspirecv::InspireImageProcess& process) {
+int32_t FaceSession::FaceDetectAndTrack(inspirecv::FrameProcess& process) {
std::lock_guard lock(m_mtx_);
if (m_enable_track_cost_spend_) {
m_face_track_cost_->Start();
@@ -81,7 +76,7 @@ int32_t FaceSession::FaceDetectAndTrack(inspirecv::InspireImageProcess& process)
m_face_track_->UpdateStream(process);
for (int i = 0; i < m_face_track_->trackingFace.size(); ++i) {
auto& face = m_face_track_->trackingFace[i];
- HyperFaceData data = FaceObjectInternalToHyperFaceData(face, i);
+ FaceTrackWrap data = FaceObjectInternalToHyperFaceData(face, i);
ByteArray byteArray;
auto ret = RunSerializeHyperFaceData(data, byteArray);
if (ret != HSUCCEED) {
@@ -118,6 +113,11 @@ int32_t FaceSession::FaceDetectAndTrack(inspirecv::InspireImageProcess& process)
return HSUCCEED;
}
+int32_t FaceSession::SetLandmarkLoop(int32_t value) {
+ // TODO: implement this function
+ return HSUCCEED;
+}
+
int32_t FaceSession::SetFaceDetectThreshold(float value) {
m_face_track_->SetDetectThreshold(value);
return HSUCCEED;
@@ -139,8 +139,7 @@ const int32_t FaceSession::GetNumberOfFacesCurrentlyDetected() const {
return m_face_track_->trackingFace.size();
}
-int32_t FaceSession::FacesProcess(inspirecv::InspireImageProcess& process, const std::vector& faces,
- const CustomPipelineParameter& param) {
+int32_t FaceSession::FacesProcess(inspirecv::FrameProcess& process, const std::vector& faces, const CustomPipelineParameter& param) {
std::lock_guard lock(m_mtx_);
m_mask_results_cache_.resize(faces.size(), -1.0f);
m_rgb_liveness_results_cache_.resize(faces.size(), -1.0f);
@@ -205,7 +204,7 @@ int32_t FaceSession::FacesProcess(inspirecv::InspireImageProcess& process, const
m_react_left_eye_results_cache_[i] = new_eye_left;
m_react_right_eye_results_cache_[i] = new_eye_right;
}
- const auto actions = target.UpdateFaceAction();
+ const auto actions = target.UpdateFaceAction(INSPIREFACE_CONTEXT->getMArchive().GetLandmarkParam()->semantic_index);
m_action_normal_results_cache_[i] = actions.normal;
m_action_jaw_open_results_cache_[i] = actions.jawOpen;
m_action_blink_results_cache_[i] = actions.blink;
@@ -324,24 +323,52 @@ const std::vector& FaceSession::GetFaceRaiseHeadAactionsResultCache() const
return m_action_raise_head_results_cache_;
}
-int32_t FaceSession::FaceFeatureExtract(inspirecv::InspireImageProcess& process, FaceBasicData& data) {
+int32_t FaceSession::FaceFeatureExtract(inspirecv::FrameProcess& process, FaceBasicData& data, bool normalize) {
std::lock_guard lock(m_mtx_);
int32_t ret;
- HyperFaceData face = {0};
+ FaceTrackWrap face = {0};
ret = RunDeserializeHyperFaceData((char*)data.data, data.dataSize, face);
if (ret != HSUCCEED) {
return ret;
}
m_face_feature_cache_.clear();
- ret = m_face_recognition_->FaceExtract(process, face, m_face_feature_cache_, m_face_feature_norm_);
+ ret = m_face_recognition_->FaceExtract(process, face, m_face_feature_cache_, m_face_feature_norm_, normalize);
return ret;
}
-int32_t FaceSession::FaceGetFaceAlignmentImage(inspirecv::InspireImageProcess& process, FaceBasicData& data, inspirecv::Image& image) {
+int32_t FaceSession::FaceFeatureExtract(inspirecv::FrameProcess& process, FaceTrackWrap& data, bool normalize) {
std::lock_guard lock(m_mtx_);
int32_t ret;
- HyperFaceData face = {0};
+ m_face_feature_cache_.clear();
+ ret = m_face_recognition_->FaceExtract(process, data, m_face_feature_cache_, m_face_feature_norm_, normalize);
+ if (ret != HSUCCEED) {
+ return ret;
+ }
+
+ return ret;
+}
+
+int32_t FaceSession::FaceFeatureExtractWithAlignmentImage(inspirecv::FrameProcess& process, Embedded& embedding, float& norm, bool normalize) {
+ std::lock_guard lock(m_mtx_);
+ int32_t ret;
+ m_face_feature_cache_.clear();
+ ret = m_face_recognition_->FaceExtractWithAlignmentImage(process, embedding, norm, normalize);
+
+ return ret;
+}
+
+int32_t FaceSession::FaceFeatureExtractWithAlignmentImage(const inspirecv::Image& wrapped, FaceEmbedding& embedding, float& norm, bool normalize) {
+ std::lock_guard lock(m_mtx_);
+ int32_t ret;
+ ret = m_face_recognition_->FaceExtractWithAlignmentImage(wrapped, embedding.embedding, norm, normalize);
+ return ret;
+}
+
+int32_t FaceSession::FaceGetFaceAlignmentImage(inspirecv::FrameProcess& process, FaceBasicData& data, inspirecv::Image& image) {
+ std::lock_guard lock(m_mtx_);
+ int32_t ret;
+ FaceTrackWrap face = {0};
ret = RunDeserializeHyperFaceData((char*)data.data, data.dataSize, face);
if (ret != HSUCCEED) {
return ret;
@@ -361,7 +388,7 @@ const CustomPipelineParameter& FaceSession::getMParameter() const {
int32_t FaceSession::FaceQualityDetect(FaceBasicData& data, float& result) {
int32_t ret;
- HyperFaceData face = {0};
+ FaceTrackWrap face = {0};
ret = RunDeserializeHyperFaceData((char*)data.data, data.dataSize, face);
// PrintHyperFaceData(face);
if (ret != HSUCCEED) {
@@ -396,6 +423,10 @@ int32_t FaceSession::SetTrackPreviewSize(const int32_t preview_size) {
return HSUCCEED;
}
+int32_t FaceSession::GetTrackPreviewSize() const {
+ return m_face_track_->GetTrackPreviewSize();
+}
+
int32_t FaceSession::SetTrackFaceMinimumSize(int32_t minSize) {
m_face_track_->SetMinimumFacePxSize(minSize);
return HSUCCEED;
@@ -428,4 +459,8 @@ void FaceSession::PrintTrackCostSpend() {
}
}
+int32_t FaceSession::GetDebugPreviewImageSize() const {
+ return m_face_track_->GetDebugPreviewImageSize();
+}
+
} // namespace inspire
diff --git a/cpp-package/inspireface/cpp/inspireface/face_session.h b/cpp-package/inspireface/cpp/inspireface/engine/face_session.h
similarity index 87%
rename from cpp-package/inspireface/cpp/inspireface/face_session.h
rename to cpp-package/inspireface/cpp/inspireface/engine/face_session.h
index b20a64f..a0fe46c 100644
--- a/cpp-package/inspireface/cpp/inspireface/face_session.h
+++ b/cpp-package/inspireface/cpp/inspireface/engine/face_session.h
@@ -14,29 +14,12 @@
#include "pipeline_module/face_pipeline_module.h"
#include "middleware/model_archive/inspire_archive.h"
#include "recognition_module/face_feature_extraction_module.h"
-#include "middleware/inspirecv_image_process.h"
+#include "frame_process.h"
#include "common/face_data/face_serialize_tools.h"
+#include "spend_timer.h"
namespace inspire {
-/**
- * @struct CustomPipelineParameter
- * @brief Structure to hold custom parameters for the face detection and processing pipeline.
- *
- * Includes options for enabling various features such as recognition, liveness detection, and quality assessment.
- */
-typedef struct CustomPipelineParameter {
- bool enable_recognition = false; ///< Enable face recognition feature
- bool enable_liveness = false; ///< Enable RGB liveness detection feature
- bool enable_ir_liveness = false; ///< Enable IR (Infrared) liveness detection feature
- bool enable_mask_detect = false; ///< Enable mask detection feature
- bool enable_face_attribute = false; ///< Enable face attribute prediction feature
- bool enable_face_quality = false; ///< Enable face quality assessment feature
- bool enable_interaction_liveness = false; ///< Enable interactive liveness detection feature
- bool enable_detect_mode_landmark = false; ///< Enable landmark detection in detection mode
-
-} ContextCustomParameter;
-
/**
* @class FaceContext
* @brief Manages the context for face detection, tracking, and feature extraction in the HyperFaceRepo project.
@@ -68,7 +51,14 @@ public:
* @param image The camera stream to process for face detection and tracking.
* @return int32_t Returns the number of faces detected and tracked.
*/// Method for face detection and tracking
- int32_t FaceDetectAndTrack(inspirecv::InspireImageProcess& process);
+ int32_t FaceDetectAndTrack(inspirecv::FrameProcess& process);
+
+ /**
+ * @brief Set the face landmark loop
+ * @param value The landmark loop value
+ * @return int32_t Status code of the operation.
+ * */
+ int32_t SetLandmarkLoop(int32_t value);
/**
* @brief Set the threshold of face detection function, which only acts on the detection model
@@ -86,11 +76,11 @@ public:
/**
* @brief Processes faces using the provided pipeline parameters.
* @param image Camera stream containing faces.
- * @param faces Vector of HyperFaceData for detected faces.
+ * @param faces Vector of FaceTrackWrap for detected faces.
* @param param Custom pipeline parameters.
* @return int32_t Status code of the processing.
*/
- int32_t FacesProcess(inspirecv::InspireImageProcess& process, const std::vector& faces, const CustomPipelineParameter& param);
+ int32_t FacesProcess(inspirecv::FrameProcess& process, const std::vector& faces, const CustomPipelineParameter& param);
/**
* @brief Retrieves the face recognition module.
@@ -116,7 +106,31 @@ public:
* @param data FaceBasicData to store extracted features.
* @return int32_t Status code of the feature extraction.
*/
- int32_t FaceFeatureExtract(inspirecv::InspireImageProcess& process, FaceBasicData& data);
+ int32_t FaceFeatureExtract(inspirecv::FrameProcess& process, FaceBasicData& data, bool normalize = true);
+
+ /**
+ * @brief Extracts features of a face from an image.
+ * @param image Camera stream containing the face.
+ * @param data FaceTrackWrap to store extracted features.
+ * @return int32_t Status code of the feature extraction.
+ */
+ int32_t FaceFeatureExtract(inspirecv::FrameProcess& process, FaceTrackWrap& data, bool normalize = true);
+
+ /**
+ * @brief Extracts features of a face from an image.
+ * @param image Camera stream containing the face.
+ * @param data FaceTrackWrap to store extracted features.
+ * @return int32_t Status code of the feature extraction.
+ */
+ int32_t FaceFeatureExtractWithAlignmentImage(inspirecv::FrameProcess& process, Embedded& embedding, float& norm, bool normalize = true);
+
+ /**
+ * @brief Extracts features of a face from an image.
+ * @param image Camera stream containing the face.
+ * @param data FaceTrackWrap to store extracted features.
+ * @return int32_t Status code of the feature extraction.
+ */
+ int32_t FaceFeatureExtractWithAlignmentImage(const inspirecv::Image& wrapped, FaceEmbedding& embedding, float& norm, bool normalize = true);
/**
* @brief Gets the face alignment image.
@@ -125,7 +139,7 @@ public:
* @param image The output image.
* @return int32_t The status code of the operation.
*/
- int32_t FaceGetFaceAlignmentImage(inspirecv::InspireImageProcess& process, FaceBasicData& data, inspirecv::Image& image);
+ int32_t FaceGetFaceAlignmentImage(inspirecv::FrameProcess& process, FaceBasicData& data, inspirecv::Image& image);
/**
* @brief Retrieves the custom pipeline parameters.
@@ -148,6 +162,12 @@ public:
*/
int32_t SetTrackPreviewSize(int32_t preview_size);
+ /**
+ * @brief Gets the preview size for face tracking.
+ * @return int32_t The preview size.
+ */
+ int32_t GetTrackPreviewSize() const;
+
/**
* @brief Filter the minimum face pixel size.
* @param minSize The minimum pixel value.
@@ -347,6 +367,12 @@ public:
* */
void PrintTrackCostSpend();
+ /**
+ * @brief Get the debug preview image size
+ * @return int32_t The debug preview image size
+ * */
+ int32_t GetDebugPreviewImageSize() const;
+
private:
// Private member variables
CustomPipelineParameter m_parameter_; ///< Stores custom parameters for the pipeline
@@ -390,7 +416,7 @@ private:
std::mutex m_mtx_; ///< Mutex for thread safety.
// cost spend
- std::shared_ptr m_face_track_cost_;
+ std::shared_ptr m_face_track_cost_;
int m_enable_track_cost_spend_ = 0;
};
diff --git a/cpp-package/inspireface/cpp/inspireface/feature_hub/embedding_db/embedding_db.cpp b/cpp-package/inspireface/cpp/inspireface/feature_hub/embedding_db/embedding_db.cpp
index 66ed5b7..3b06937 100644
--- a/cpp-package/inspireface/cpp/inspireface/feature_hub/embedding_db/embedding_db.cpp
+++ b/cpp-package/inspireface/cpp/inspireface/feature_hub/embedding_db/embedding_db.cpp
@@ -2,6 +2,9 @@
#include "sqlite-vec.h"
#include "isf_check.h"
#include
+#if defined(__ANDROID__)
+#include
+#endif
namespace inspire {
@@ -118,20 +121,13 @@ std::vector EmbeddingDB::BatchInsertVectors(const std::vector insertedIds;
insertedIds.reserve(vectors.size());
- try {
- for (const auto &data : vectors) {
- int64_t id = 0;
- bool ret = InsertVector(data.id, data.vector, id);
- if (!ret) {
- throw std::runtime_error("Failed to insert vector");
- }
- insertedIds.push_back(id);
- }
- ExecuteSQL("COMMIT");
- } catch (...) {
- ExecuteSQL("ROLLBACK");
- throw;
+ for (const auto &data : vectors) {
+ int64_t id = 0;
+ bool ret = InsertVector(data.id, data.vector, id);
+ INSPIREFACE_CHECK_MSG(ret, "Failed to insert vector");
+ insertedIds.push_back(id);
}
+ ExecuteSQL("COMMIT");
return insertedIds;
}
@@ -141,20 +137,13 @@ std::vector EmbeddingDB::BatchInsertVectors(const std::vector insertedIds;
insertedIds.reserve(vectors.size());
- try {
- for (const auto &vector : vectors) {
- int64_t id = 0;
- bool ret = InsertVector(0, vector, id);
- if (!ret) {
- throw std::runtime_error("Failed to insert vector");
- }
- insertedIds.push_back(id);
- }
- ExecuteSQL("COMMIT");
- } catch (...) {
- ExecuteSQL("ROLLBACK");
- throw;
+ for (const auto &vector : vectors) {
+ int64_t id = 0;
+ bool ret = InsertVector(0, vector, id);
+ INSPIREFACE_CHECK_MSG(ret, "Failed to insert vector");
+ insertedIds.push_back(id);
}
+ ExecuteSQL("COMMIT");
return insertedIds;
}
diff --git a/cpp-package/inspireface/cpp/inspireface/feature_hub/embedding_db/embedding_db.h b/cpp-package/inspireface/cpp/inspireface/feature_hub/embedding_db/embedding_db.h
index d4c50f0..e1605fd 100644
--- a/cpp-package/inspireface/cpp/inspireface/feature_hub/embedding_db/embedding_db.h
+++ b/cpp-package/inspireface/cpp/inspireface/feature_hub/embedding_db/embedding_db.h
@@ -19,18 +19,12 @@
#include
#include
#include
+#include "data_type.h"
#define EMBEDDING_DB inspire::EmbeddingDB
namespace inspire {
-// Search for most similar vectors
-struct FaceSearchResult {
- int64_t id;
- double similarity;
- std::vector feature;
-};
-
// Vector data structure
struct VectorData {
int64_t id; // This field is ignored in auto-increment mode
diff --git a/cpp-package/inspireface/cpp/inspireface/feature_hub/feature_hub_db.cpp b/cpp-package/inspireface/cpp/inspireface/feature_hub/feature_hub_db.cpp
index b015ad6..2adbea8 100644
--- a/cpp-package/inspireface/cpp/inspireface/feature_hub/feature_hub_db.cpp
+++ b/cpp-package/inspireface/cpp/inspireface/feature_hub/feature_hub_db.cpp
@@ -9,13 +9,42 @@
#include
#include "middleware/utils.h"
#include "middleware/system.h"
+#include "log.h"
+#include "feature_hub/embedding_db/embedding_db.h"
+
+#define DB_FILE_NAME ".feature_hub_db_v0"
namespace inspire {
+class FeatureHubDB::Impl {
+public:
+ Impl() : m_enable_(false), m_recognition_threshold_(0.48f), m_search_mode_(SEARCH_MODE_EAGER) {}
+
+ Embedded m_search_face_feature_cache_;
+ Embedded m_getter_face_feature_cache_;
+ std::shared_ptr m_face_feature_ptr_cache_;
+
+ std::vector m_search_top_k_cache_;
+ std::vector m_top_k_confidence_;
+ std::vector m_top_k_custom_ids_cache_;
+
+ std::vector m_all_ids_;
+
+ DatabaseConfiguration m_db_configuration_;
+ float m_recognition_threshold_;
+ SearchMode m_search_mode_;
+
+ bool m_enable_;
+
+ std::mutex m_res_mtx_;
+};
+
std::mutex FeatureHubDB::mutex_;
std::shared_ptr FeatureHubDB::instance_ = nullptr;
-FeatureHubDB::FeatureHubDB() {}
+FeatureHubDB::FeatureHubDB() : pImpl(new Impl()) {}
+
+FeatureHubDB::~FeatureHubDB() = default;
std::shared_ptr FeatureHubDB::GetInstance() {
std::lock_guard lock(mutex_);
@@ -26,79 +55,76 @@ std::shared_ptr FeatureHubDB::GetInstance() {
}
int32_t FeatureHubDB::DisableHub() {
- if (!m_enable_) {
+ if (!pImpl->m_enable_) {
INSPIRE_LOGW("FeatureHub is already disabled.");
return HSUCCEED;
}
- // Close the database if it starts
+
if (EMBEDDING_DB::GetInstance().IsInitialized()) {
EMBEDDING_DB::Deinit();
- // if (ret != HSUCCEED) {
- // INSPIRE_LOGE("Failed to close the database: %d", ret);
- // return ret;
- // }
- // m_db_.reset();
}
- m_search_face_feature_cache_.clear();
+ pImpl->m_search_face_feature_cache_.clear();
- m_db_configuration_ = DatabaseConfiguration(); // Reset using the default constructor
- m_recognition_threshold_ = 0.0f;
- m_search_mode_ = SEARCH_MODE_EAGER;
+ pImpl->m_db_configuration_ = DatabaseConfiguration();
+ pImpl->m_recognition_threshold_ = 0.0f;
+ pImpl->m_search_mode_ = SEARCH_MODE_EAGER;
- m_face_feature_ptr_cache_.reset();
- m_enable_ = false;
+ pImpl->m_face_feature_ptr_cache_.reset();
+ pImpl->m_enable_ = false;
return HSUCCEED;
}
int32_t FeatureHubDB::GetAllIds() {
- if (!m_enable_) {
+ if (!pImpl->m_enable_) {
INSPIRE_LOGE("FeatureHub is disabled, please enable it before it can be served");
return HERR_FT_HUB_DISABLE;
}
- m_all_ids_ = EMBEDDING_DB::GetInstance().GetAllIds();
+ pImpl->m_all_ids_ = EMBEDDING_DB::GetInstance().GetAllIds();
return HSUCCEED;
}
int32_t FeatureHubDB::EnableHub(const DatabaseConfiguration &configuration) {
- int32_t ret;
- if (m_enable_) {
+ if (pImpl->m_enable_) {
INSPIRE_LOGW("You have enabled the FeatureHub feature. It is not valid to do so again");
return HSUCCEED;
}
- // Config
- m_db_configuration_ = configuration;
- m_recognition_threshold_ = m_db_configuration_.recognition_threshold;
- if (m_recognition_threshold_ < -1.0f || m_recognition_threshold_ > 1.0f) {
+
+ pImpl->m_db_configuration_ = configuration;
+ pImpl->m_recognition_threshold_ = pImpl->m_db_configuration_.recognition_threshold;
+ if (pImpl->m_recognition_threshold_ < -1.0f || pImpl->m_recognition_threshold_ > 1.0f) {
INSPIRE_LOGW("The search threshold entered does not fit the required range (-1.0f, 1.0f) and has been set to 0.5 by default");
- m_recognition_threshold_ = 0.5f;
+ pImpl->m_recognition_threshold_ = 0.5f;
}
+
std::string dbFile = ":memory:";
- if (m_db_configuration_.enable_persistence) {
- if (IsDirectory(m_db_configuration_.persistence_db_path)) {
- dbFile = os::PathJoin(m_db_configuration_.persistence_db_path, DB_FILE_NAME);
+ if (pImpl->m_db_configuration_.enable_persistence) {
+ if (IsDirectory(pImpl->m_db_configuration_.persistence_db_path)) {
+ dbFile = os::PathJoin(pImpl->m_db_configuration_.persistence_db_path, DB_FILE_NAME);
} else {
- dbFile = m_db_configuration_.persistence_db_path;
+ dbFile = pImpl->m_db_configuration_.persistence_db_path;
}
}
EMBEDDING_DB::Init(dbFile, 512, IdMode(configuration.primary_key_mode));
- m_enable_ = true;
- m_face_feature_ptr_cache_ = std::make_shared();
+ pImpl->m_enable_ = true;
+ pImpl->m_face_feature_ptr_cache_ = std::make_shared();
return HSUCCEED;
}
int32_t FeatureHubDB::CosineSimilarity(const std::vector &v1, const std::vector &v2, float &res, bool normalize) {
if (v1.size() != v2.size() || v1.empty()) {
- return HERR_SESS_REC_CONTRAST_FEAT_ERR; // The similarity cannot be calculated if the vector lengths are not equal
+ return HERR_SESS_REC_CONTRAST_FEAT_ERR;
}
+
if (normalize) {
std::vector v1_norm = v1;
std::vector v2_norm = v2;
float mse1 = 0.0f;
float mse2 = 0.0f;
+
for (const auto &one : v1_norm) {
mse1 += one * one;
}
@@ -114,9 +140,9 @@ int32_t FeatureHubDB::CosineSimilarity(const std::vector &v1, const std::
for (float &one : v2_norm) {
one /= mse2;
}
+
res = simd_dot(v1_norm.data(), v2_norm.data(), v1_norm.size());
} else {
- // Calculate the cosine similarity
res = simd_dot(v1.data(), v2.data(), v1.size());
}
@@ -129,6 +155,7 @@ int32_t FeatureHubDB::CosineSimilarity(const float *v1, const float *v2, int32_t
std::vector v2_norm(v2, v2 + size);
float mse1 = 0.0f;
float mse2 = 0.0f;
+
for (const auto &one : v1_norm) {
mse1 += one * one;
}
@@ -136,6 +163,7 @@ int32_t FeatureHubDB::CosineSimilarity(const float *v1, const float *v2, int32_t
for (float &one : v1_norm) {
one /= mse1;
}
+
for (const auto &one : v2_norm) {
mse2 += one * one;
}
@@ -143,6 +171,7 @@ int32_t FeatureHubDB::CosineSimilarity(const float *v1, const float *v2, int32_t
for (float &one : v2_norm) {
one /= mse2;
}
+
res = simd_dot(v1_norm.data(), v2_norm.data(), v1_norm.size());
} else {
res = simd_dot(v1, v2, size);
@@ -152,37 +181,34 @@ int32_t FeatureHubDB::CosineSimilarity(const float *v1, const float *v2, int32_t
}
int32_t FeatureHubDB::GetFaceFeatureCount() {
- if (!m_enable_) {
+ if (!pImpl->m_enable_) {
INSPIRE_LOGW("FeatureHub is disabled, please enable it before it can be served");
return 0;
}
- int totalFeatureCount = 0;
- // Iterate over all FeatureBlocks and add up the number of feature vectors used
- totalFeatureCount = EMBEDDING_DB::GetInstance().GetVectorCount();
-
- return totalFeatureCount;
+ return EMBEDDING_DB::GetInstance().GetVectorCount();
}
int32_t FeatureHubDB::SearchFaceFeature(const Embedded &queryFeature, FaceSearchResult &searchResult, bool returnFeature) {
std::lock_guard lock(mutex_);
- if (!m_enable_) {
+ if (!pImpl->m_enable_) {
INSPIRE_LOGE("FeatureHub is disabled, please enable it before it can be served");
return HSUCCEED;
}
- m_search_face_feature_cache_.clear();
- auto results = EMBEDDING_DB::GetInstance().SearchSimilarVectors(queryFeature, 1, m_recognition_threshold_, returnFeature);
+
+ pImpl->m_search_face_feature_cache_.clear();
+ auto results = EMBEDDING_DB::GetInstance().SearchSimilarVectors(queryFeature, 1, pImpl->m_recognition_threshold_, returnFeature);
searchResult.id = -1;
+
if (!results.empty()) {
auto &searched = results[0];
searchResult.similarity = searched.similarity;
searchResult.id = searched.id;
if (returnFeature) {
searchResult.feature = searched.feature;
- // copy feature to cache
- m_search_face_feature_cache_ = searched.feature;
- m_face_feature_ptr_cache_->data = m_search_face_feature_cache_.data();
- m_face_feature_ptr_cache_->dataSize = m_search_face_feature_cache_.size();
+ pImpl->m_search_face_feature_cache_ = searched.feature;
+ pImpl->m_face_feature_ptr_cache_->data = pImpl->m_search_face_feature_cache_.data();
+ pImpl->m_face_feature_ptr_cache_->dataSize = pImpl->m_search_face_feature_cache_.size();
}
}
@@ -191,16 +217,18 @@ int32_t FeatureHubDB::SearchFaceFeature(const Embedded &queryFeature, FaceSearch
int32_t FeatureHubDB::SearchFaceFeatureTopKCache(const Embedded &queryFeature, size_t topK) {
std::lock_guard lock(mutex_);
- if (!m_enable_) {
+ if (!pImpl->m_enable_) {
INSPIRE_LOGE("FeatureHub is disabled, please enable it before it can be served");
return HERR_FT_HUB_DISABLE;
}
- m_top_k_confidence_.clear();
- m_top_k_custom_ids_cache_.clear();
- auto results = EMBEDDING_DB::GetInstance().SearchSimilarVectors(queryFeature, topK, m_recognition_threshold_, false);
+
+ pImpl->m_top_k_confidence_.clear();
+ pImpl->m_top_k_custom_ids_cache_.clear();
+ auto results = EMBEDDING_DB::GetInstance().SearchSimilarVectors(queryFeature, topK, pImpl->m_recognition_threshold_, false);
+
for (size_t i = 0; i < results.size(); i++) {
- m_top_k_custom_ids_cache_.push_back(results[i].id);
- m_top_k_confidence_.push_back(results[i].similarity);
+ pImpl->m_top_k_custom_ids_cache_.push_back(results[i].id);
+ pImpl->m_top_k_confidence_.push_back(results[i].similarity);
}
return HSUCCEED;
@@ -209,17 +237,18 @@ int32_t FeatureHubDB::SearchFaceFeatureTopKCache(const Embedded &queryFeature, s
int32_t FeatureHubDB::SearchFaceFeatureTopK(const Embedded &queryFeature, std::vector &searchResult, size_t topK,
bool returnFeature) {
std::lock_guard lock(mutex_);
- if (!m_enable_) {
+ if (!pImpl->m_enable_) {
INSPIRE_LOGW("FeatureHub is disabled, please enable it before it can be served");
return HERR_FT_HUB_DISABLE;
}
- searchResult = EMBEDDING_DB::GetInstance().SearchSimilarVectors(queryFeature, topK, m_recognition_threshold_, returnFeature);
+
+ searchResult = EMBEDDING_DB::GetInstance().SearchSimilarVectors(queryFeature, topK, pImpl->m_recognition_threshold_, returnFeature);
return HSUCCEED;
}
int32_t FeatureHubDB::FaceFeatureInsert(const std::vector &feature, int32_t id, int64_t &result_id) {
std::lock_guard lock(mutex_);
- if (!m_enable_) {
+ if (!pImpl->m_enable_) {
INSPIRE_LOGE("FeatureHub is disabled, please enable it before it can be served");
return HERR_FT_HUB_DISABLE;
}
@@ -235,65 +264,62 @@ int32_t FeatureHubDB::FaceFeatureInsert(const std::vector &feature, int32
int32_t FeatureHubDB::FaceFeatureRemove(int32_t id) {
std::lock_guard lock(mutex_);
- if (!m_enable_) {
+ if (!pImpl->m_enable_) {
INSPIRE_LOGE("FeatureHub is disabled, please enable it before it can be served");
return HERR_FT_HUB_DISABLE;
}
- EMBEDDING_DB::GetInstance().DeleteVector(id);
+ EMBEDDING_DB::GetInstance().DeleteVector(id);
return HSUCCEED;
}
int32_t FeatureHubDB::FaceFeatureUpdate(const std::vector &feature, int32_t customId) {
std::lock_guard lock(mutex_);
- if (!m_enable_) {
+ if (!pImpl->m_enable_) {
INSPIRE_LOGE("FeatureHub is disabled, please enable it before it can be served");
return HERR_FT_HUB_DISABLE;
}
- try {
- EMBEDDING_DB::GetInstance().UpdateVector(customId, feature);
- } catch (const std::exception &e) {
- INSPIRE_LOGW("Failed to update face feature, id: %d", customId);
- return HERR_FT_HUB_NOT_FOUND_FEATURE;
- }
+ EMBEDDING_DB::GetInstance().UpdateVector(customId, feature);
return HSUCCEED;
}
int32_t FeatureHubDB::GetFaceFeature(int32_t id) {
std::lock_guard lock(mutex_);
- if (!m_enable_) {
+ if (!pImpl->m_enable_) {
INSPIRE_LOGE("FeatureHub is disabled, please enable it before it can be served");
return HERR_FT_HUB_DISABLE;
}
+
auto vec = EMBEDDING_DB::GetInstance().GetVector(id);
if (vec.empty()) {
return HERR_FT_HUB_NOT_FOUND_FEATURE;
}
- m_getter_face_feature_cache_ = vec;
- m_face_feature_ptr_cache_->data = m_getter_face_feature_cache_.data();
- m_face_feature_ptr_cache_->dataSize = m_getter_face_feature_cache_.size();
+
+ pImpl->m_getter_face_feature_cache_ = vec;
+ pImpl->m_face_feature_ptr_cache_->data = pImpl->m_getter_face_feature_cache_.data();
+ pImpl->m_face_feature_ptr_cache_->dataSize = pImpl->m_getter_face_feature_cache_.size();
return HSUCCEED;
}
int32_t FeatureHubDB::GetFaceFeature(int32_t id, std::vector &feature) {
std::lock_guard lock(mutex_);
- if (!m_enable_) {
+ if (!pImpl->m_enable_) {
INSPIRE_LOGW("FeatureHub is disabled, please enable it before it can be served");
return HERR_FT_HUB_DISABLE;
}
- try {
- feature = EMBEDDING_DB::GetInstance().GetVector(id);
- } catch (const std::exception &e) {
- INSPIRE_LOGW("Failed to get face feature, id: %d", id);
+
+ feature = EMBEDDING_DB::GetInstance().GetVector(id);
+ if (feature.empty()) {
return HERR_FT_HUB_NOT_FOUND_FEATURE;
}
+
return HSUCCEED;
}
int32_t FeatureHubDB::ViewDBTable() {
- if (!m_enable_) {
+ if (!pImpl->m_enable_) {
INSPIRE_LOGE("FeatureHub is disabled, please enable it before it can be served");
return HERR_FT_HUB_DISABLE;
}
@@ -302,33 +328,33 @@ int32_t FeatureHubDB::ViewDBTable() {
}
void FeatureHubDB::SetRecognitionThreshold(float threshold) {
- m_recognition_threshold_ = threshold;
+ pImpl->m_recognition_threshold_ = threshold;
}
void FeatureHubDB::SetRecognitionSearchMode(SearchMode mode) {
- m_search_mode_ = mode;
+ pImpl->m_search_mode_ = mode;
}
// =========== Getter ===========
const Embedded &FeatureHubDB::GetSearchFaceFeatureCache() const {
- return m_search_face_feature_cache_;
+ return pImpl->m_search_face_feature_cache_;
}
const std::shared_ptr &FeatureHubDB::GetFaceFeaturePtrCache() const {
- return m_face_feature_ptr_cache_;
+ return pImpl->m_face_feature_ptr_cache_;
}
std::vector &FeatureHubDB::GetTopKConfidence() {
- return m_top_k_confidence_;
+ return pImpl->m_top_k_confidence_;
}
std::vector &FeatureHubDB::GetTopKCustomIdsCache() {
- return m_top_k_custom_ids_cache_;
+ return pImpl->m_top_k_custom_ids_cache_;
}
std::vector &FeatureHubDB::GetExistingIds() {
- return m_all_ids_;
+ return pImpl->m_all_ids_;
}
} // namespace inspire
diff --git a/cpp-package/inspireface/cpp/inspireface/image_process/frame_process.cpp b/cpp-package/inspireface/cpp/inspireface/image_process/frame_process.cpp
new file mode 100644
index 0000000..0d462f1
--- /dev/null
+++ b/cpp-package/inspireface/cpp/inspireface/image_process/frame_process.cpp
@@ -0,0 +1,395 @@
+#include "frame_process.h"
+#include
+#include
+#include "isf_check.h"
+
+namespace inspirecv {
+
+class FrameProcess::Impl {
+public:
+ Impl() : buffer_(nullptr), height_(0), width_(0), preview_scale_(0), preview_size_(192), rotation_mode_(ROTATION_0) {
+ SetDataFormat(NV21);
+ SetDestFormat(BGR);
+ config_.filterType = MNN::CV::BILINEAR;
+ config_.wrap = MNN::CV::ZERO;
+ }
+
+ void SetDataFormat(DATA_FORMAT data_format) {
+ if (data_format == NV21) {
+ config_.sourceFormat = MNN::CV::YUV_NV21;
+ }
+ if (data_format == NV12) {
+ config_.sourceFormat = MNN::CV::YUV_NV12;
+ }
+ if (data_format == RGBA) {
+ config_.sourceFormat = MNN::CV::RGBA;
+ }
+ if (data_format == RGB) {
+ config_.sourceFormat = MNN::CV::RGB;
+ }
+ if (data_format == BGR) {
+ config_.sourceFormat = MNN::CV::BGR;
+ }
+ if (data_format == BGRA) {
+ config_.sourceFormat = MNN::CV::BGRA;
+ }
+ }
+
+ void SetDestFormat(DATA_FORMAT data_format) {
+ if (data_format == NV21) {
+ config_.destFormat = MNN::CV::YUV_NV21;
+ }
+ if (data_format == NV12) {
+ config_.destFormat = MNN::CV::YUV_NV12;
+ }
+ if (data_format == RGBA) {
+ config_.destFormat = MNN::CV::RGBA;
+ }
+ if (data_format == RGB) {
+ config_.destFormat = MNN::CV::RGB;
+ }
+ if (data_format == BGR) {
+ config_.destFormat = MNN::CV::BGR;
+ }
+ if (data_format == BGRA) {
+ config_.destFormat = MNN::CV::BGRA;
+ }
+ }
+
+ void UpdateTransformMatrix() {
+ float srcPoints[] = {0.0f, 0.0f, 0.0f, (float)(height_ - 1), (float)(width_ - 1), 0.0f, (float)(width_ - 1), (float)(height_ - 1)};
+
+ float dstPoints[8];
+ if (rotation_mode_ == ROTATION_270) {
+ float points[] = {(float)(height_ * preview_scale_ - 1),
+ 0.0f,
+ 0.0f,
+ 0.0f,
+ (float)(height_ * preview_scale_ - 1),
+ (float)(width_ * preview_scale_ - 1),
+ 0.0f,
+ (float)(width_ * preview_scale_ - 1)};
+ memcpy(dstPoints, points, sizeof(points));
+ } else if (rotation_mode_ == ROTATION_90) {
+ float points[] = {0.0f,
+ (float)(width_ * preview_scale_ - 1),
+ (float)(height_ * preview_scale_ - 1),
+ (float)(width_ * preview_scale_ - 1),
+ 0.0f,
+ 0.0f,
+ (float)(height_ * preview_scale_ - 1),
+ 0.0f};
+ memcpy(dstPoints, points, sizeof(points));
+ } else if (rotation_mode_ == ROTATION_180) {
+ float points[] = {(float)(width_ * preview_scale_ - 1),
+ (float)(height_ * preview_scale_ - 1),
+ (float)(width_ * preview_scale_ - 1),
+ 0.0f,
+ 0.0f,
+ (float)(height_ * preview_scale_ - 1),
+ 0.0f,
+ 0.0f};
+ memcpy(dstPoints, points, sizeof(points));
+ } else { // ROTATION_0
+ float points[] = {0.0f,
+ 0.0f,
+ 0.0f,
+ (float)(height_ * preview_scale_ - 1),
+ (float)(width_ * preview_scale_ - 1),
+ 0.0f,
+ (float)(width_ * preview_scale_ - 1),
+ (float)(height_ * preview_scale_ - 1)};
+ memcpy(dstPoints, points, sizeof(points));
+ }
+
+ tr_.setPolyToPoly((MNN::CV::Point *)dstPoints, (MNN::CV::Point *)srcPoints, 4);
+ }
+
+ const uint8_t *buffer_; // Pointer to the data buffer.
+ int height_; // Height of the camera stream image.
+ int width_; // Width of the camera stream image.
+ float preview_scale_; // Scaling factor for the preview image.
+ int preview_size_; // Size of the preview image.
+ MNN::CV::Matrix tr_; // Affine transformation matrix.
+ ROTATION_MODE rotation_mode_; // Current rotation mode.
+ MNN::CV::ImageProcess::Config config_; // Image processing configuration.
+};
+
+FrameProcess FrameProcess::Create(const uint8_t *data_buffer, int height, int width, DATA_FORMAT data_format, ROTATION_MODE rotation_mode) {
+ FrameProcess process;
+ process.SetDataBuffer(data_buffer, height, width);
+ process.SetDataFormat(data_format);
+ process.SetRotationMode(rotation_mode);
+ return process;
+}
+
+FrameProcess FrameProcess::Create(const inspirecv::Image &image, DATA_FORMAT data_format, ROTATION_MODE rotation_mode) {
+ return Create(image.Data(), image.Height(), image.Width(), data_format, rotation_mode);
+}
+
+FrameProcess::FrameProcess() : pImpl(std::make_unique()) {
+ pImpl->UpdateTransformMatrix();
+}
+
+FrameProcess::~FrameProcess() = default;
+
+FrameProcess::FrameProcess(const FrameProcess &other) : pImpl(std::make_unique(*other.pImpl)) {}
+
+FrameProcess::FrameProcess(FrameProcess &&other) noexcept = default;
+
+FrameProcess &FrameProcess::operator=(const FrameProcess &other) {
+ if (this != &other) {
+ *pImpl = *other.pImpl;
+ }
+ return *this;
+}
+
+FrameProcess &FrameProcess::operator=(FrameProcess &&other) noexcept = default;
+
+void FrameProcess::SetDataBuffer(const uint8_t *data_buffer, int height, int width) {
+ pImpl->buffer_ = data_buffer;
+ pImpl->height_ = height;
+ pImpl->width_ = width;
+ pImpl->preview_scale_ = pImpl->preview_size_ / static_cast(std::max(height, width));
+ pImpl->UpdateTransformMatrix();
+}
+
+void FrameProcess::SetPreviewSize(const int size) {
+ pImpl->preview_size_ = size;
+ pImpl->preview_scale_ = pImpl->preview_size_ / static_cast(std::max(pImpl->height_, pImpl->width_));
+ pImpl->UpdateTransformMatrix();
+}
+
+void FrameProcess::SetPreviewScale(const float scale) {
+ pImpl->preview_scale_ = scale;
+ pImpl->preview_size_ = static_cast(pImpl->preview_scale_ * std::max(pImpl->height_, pImpl->width_));
+ pImpl->UpdateTransformMatrix();
+}
+
+void FrameProcess::SetRotationMode(ROTATION_MODE mode) {
+ pImpl->rotation_mode_ = mode;
+ pImpl->UpdateTransformMatrix();
+}
+
+void FrameProcess::SetDataFormat(DATA_FORMAT data_format) {
+ pImpl->SetDataFormat(data_format);
+}
+
+void FrameProcess::SetDestFormat(DATA_FORMAT data_format) {
+ pImpl->SetDestFormat(data_format);
+}
+
+float FrameProcess::GetPreviewScale() {
+ return pImpl->preview_scale_;
+}
+
+inspirecv::TransformMatrix FrameProcess::GetAffineMatrix() const {
+ auto affine_matrix = inspirecv::TransformMatrix::Create();
+ affine_matrix[0] = pImpl->tr_[0];
+ affine_matrix[1] = pImpl->tr_[1];
+ affine_matrix[2] = pImpl->tr_[2];
+ affine_matrix[3] = pImpl->tr_[3];
+ affine_matrix[4] = pImpl->tr_[4];
+ affine_matrix[5] = pImpl->tr_[5];
+ return affine_matrix;
+}
+
+int FrameProcess::GetHeight() const {
+ return pImpl->height_;
+}
+
+int FrameProcess::GetWidth() const {
+ return pImpl->width_;
+}
+
+ROTATION_MODE FrameProcess::getRotationMode() const {
+ return pImpl->rotation_mode_;
+}
+
+inspirecv::Image FrameProcess::ExecuteImageAffineProcessing(inspirecv::TransformMatrix &affine_matrix, const int width_out,
+ const int height_out) const {
+ int sw = pImpl->width_;
+ int sh = pImpl->height_;
+ int rot_sw = sw;
+ int rot_sh = sh;
+ MNN::CV::Matrix tr;
+ std::vector tr_cv({1, 0, 0, 0, 1, 0, 0, 0, 1});
+ memcpy(tr_cv.data(), affine_matrix.Squeeze().data(), sizeof(float) * 6);
+ tr.set9(tr_cv.data());
+ MNN::CV::Matrix tr_inv;
+ tr.invert(&tr_inv);
+ std::shared_ptr process(MNN::CV::ImageProcess::create(pImpl->config_));
+ process->setMatrix(tr_inv);
+ auto img_out = inspirecv::Image::Create(width_out, height_out, 3);
+ std::shared_ptr tensor(MNN::Tensor::create(std::vector{1, height_out, width_out, 3}, (uint8_t *)img_out.Data()));
+ auto ret = process->convert(pImpl->buffer_, sw, sh, 0, tensor.get());
+ INSPIREFACE_CHECK_MSG(ret == MNN::ErrorCode::NO_ERROR, "ImageProcess::convert failed");
+ return img_out;
+}
+
+inspirecv::Image FrameProcess::ExecutePreviewImageProcessing(bool with_rotation) {
+ return ExecuteImageScaleProcessing(pImpl->preview_scale_, with_rotation);
+}
+
+inspirecv::Image FrameProcess::ExecuteImageScaleProcessing(const float scale, bool with_rotation) {
+ int sw = pImpl->width_;
+ int sh = pImpl->height_;
+ int rot_sw = sw;
+ int rot_sh = sh;
+ // MNN::CV::Matrix tr;
+ std::shared_ptr process(MNN::CV::ImageProcess::create(pImpl->config_));
+ if (pImpl->rotation_mode_ == ROTATION_270 && with_rotation) {
+ float srcPoints[] = {
+ 0.0f, 0.0f, 0.0f, (float)(pImpl->height_ - 1), (float)(pImpl->width_ - 1), 0.0f, (float)(pImpl->width_ - 1), (float)(pImpl->height_ - 1),
+ };
+ float dstPoints[] = {
+ (float)(pImpl->height_ * scale - 1), 0.0f, 0.0f, 0.0f, (float)(pImpl->height_ * scale - 1), (float)(pImpl->width_ * scale - 1), 0.0f,
+ (float)(pImpl->width_ * scale - 1)};
+
+ pImpl->tr_.setPolyToPoly((MNN::CV::Point *)dstPoints, (MNN::CV::Point *)srcPoints, 4);
+ process->setMatrix(pImpl->tr_);
+ int scaled_height = static_cast(pImpl->width_ * scale);
+ int scaled_width = static_cast(pImpl->height_ * scale);
+ inspirecv::Image img_out(scaled_width, scaled_height, 3);
+ std::shared_ptr tensor(
+ MNN::Tensor::create(std::vector{1, scaled_height, scaled_width, 3}, (uint8_t *)img_out.Data()));
+ auto ret = process->convert(pImpl->buffer_, sw, sh, 0, tensor.get());
+ INSPIREFACE_CHECK_MSG(ret == MNN::ErrorCode::NO_ERROR, "ImageProcess::convert failed");
+ return img_out;
+ } else if (pImpl->rotation_mode_ == ROTATION_90 && with_rotation) {
+ float srcPoints[] = {
+ 0.0f, 0.0f, 0.0f, (float)(pImpl->height_ - 1), (float)(pImpl->width_ - 1), 0.0f, (float)(pImpl->width_ - 1), (float)(pImpl->height_ - 1),
+ };
+ float dstPoints[] = {
+ 0.0f,
+ (float)(pImpl->width_ * scale - 1),
+ (float)(pImpl->height_ * scale - 1),
+ (float)(pImpl->width_ * scale - 1),
+ 0.0f,
+ 0.0f,
+ (float)(pImpl->height_ * scale - 1),
+ 0.0f,
+ };
+ pImpl->tr_.setPolyToPoly((MNN::CV::Point *)dstPoints, (MNN::CV::Point *)srcPoints, 4);
+ process->setMatrix(pImpl->tr_);
+ int scaled_height = static_cast(pImpl->width_ * scale);
+ int scaled_width = static_cast(pImpl->height_ * scale);
+ inspirecv::Image img_out(scaled_width, scaled_height, 3);
+ std::shared_ptr tensor(
+ MNN::Tensor::create(std::vector{1, scaled_height, scaled_width, 3}, (uint8_t *)img_out.Data()));
+ auto ret = process->convert(pImpl->buffer_, sw, sh, 0, tensor.get());
+ INSPIREFACE_CHECK_MSG(ret == MNN::ErrorCode::NO_ERROR, "ImageProcess::convert failed");
+ return img_out;
+ } else if (pImpl->rotation_mode_ == ROTATION_180 && with_rotation) {
+ float srcPoints[] = {
+ 0.0f, 0.0f, 0.0f, (float)(pImpl->height_ - 1), (float)(pImpl->width_ - 1), 0.0f, (float)(pImpl->width_ - 1), (float)(pImpl->height_ - 1),
+ };
+ float dstPoints[] = {
+ (float)(pImpl->width_ * scale - 1),
+ (float)(pImpl->height_ * scale - 1),
+ (float)(pImpl->width_ * scale - 1),
+ 0.0f,
+ 0.0f,
+ (float)(pImpl->height_ * scale - 1),
+ 0.0f,
+ 0.0f,
+ };
+ pImpl->tr_.setPolyToPoly((MNN::CV::Point *)dstPoints, (MNN::CV::Point *)srcPoints, 4);
+ process->setMatrix(pImpl->tr_);
+ int scaled_height = static_cast(pImpl->height_ * scale);
+ int scaled_width = static_cast(pImpl->width_ * scale);
+ inspirecv::Image img_out(scaled_width, scaled_height, 3);
+ std::shared_ptr tensor(
+ MNN::Tensor::create(std::vector{1, scaled_height, scaled_width, 3}, (uint8_t *)img_out.Data()));
+ auto ret = process->convert(pImpl->buffer_, sw, sh, 0, tensor.get());
+ INSPIREFACE_CHECK_MSG(ret == MNN::ErrorCode::NO_ERROR, "ImageProcess::convert failed");
+ return img_out;
+ } else {
+ float srcPoints[] = {
+ 0.0f, 0.0f, 0.0f, (float)(pImpl->height_ - 1), (float)(pImpl->width_ - 1), 0.0f, (float)(pImpl->width_ - 1), (float)(pImpl->height_ - 1),
+ };
+ float dstPoints[] = {
+ 0.0f,
+ 0.0f,
+ 0.0f,
+ (float)(pImpl->height_ * scale - 1),
+ (float)(pImpl->width_ * scale - 1),
+ 0.0f,
+ (float)(pImpl->width_ * scale - 1),
+ (float)(pImpl->height_ * scale - 1),
+ };
+ pImpl->tr_.setPolyToPoly((MNN::CV::Point *)dstPoints, (MNN::CV::Point *)srcPoints, 4);
+ process->setMatrix(pImpl->tr_);
+ int scaled_height = static_cast(pImpl->height_ * scale);
+ int scaled_width = static_cast(pImpl->width_ * scale);
+
+ inspirecv::Image img_out(scaled_width, scaled_height, 3);
+ std::shared_ptr tensor(
+ MNN::Tensor::create(std::vector{1, scaled_height, scaled_width, 3}, (uint8_t *)img_out.Data()));
+ auto ret = process->convert(pImpl->buffer_, sw, sh, 0, tensor.get());
+ INSPIREFACE_CHECK_MSG(ret == MNN::ErrorCode::NO_ERROR, "ImageProcess::convert failed");
+ return img_out;
+ }
+}
+
+inspirecv::TransformMatrix FrameProcess::GetRotationModeAffineMatrix() const {
+ float srcPoints[] = {0.0f, 0.0f, 0.0f, (float)(pImpl->height_ - 1), (float)(pImpl->width_ - 1), 0.0f, (float)(pImpl->width_ - 1), (float)(pImpl->height_ - 1)};
+ float dstPoints[8];
+
+ if (pImpl->rotation_mode_ == ROTATION_270) {
+ float points[] = {(float)(pImpl->height_ - 1),
+ 0.0f,
+ 0.0f,
+ 0.0f,
+ (float)(pImpl->height_ - 1),
+ (float)(pImpl->width_ - 1),
+ 0.0f,
+ (float)(pImpl->width_ - 1)};
+ memcpy(dstPoints, points, sizeof(points));
+ } else if (pImpl->rotation_mode_ == ROTATION_90) {
+ float points[] = {0.0f,
+ (float)(pImpl->width_ - 1),
+ (float)(pImpl->height_ - 1),
+ (float)(pImpl->width_ - 1),
+ 0.0f,
+ 0.0f,
+ (float)(pImpl->height_ - 1),
+ 0.0f};
+ memcpy(dstPoints, points, sizeof(points));
+ } else if (pImpl->rotation_mode_ == ROTATION_180) {
+ float points[] = {(float)(pImpl->width_ - 1),
+ (float)(pImpl->height_ - 1),
+ (float)(pImpl->width_ - 1),
+ 0.0f,
+ 0.0f,
+ (float)(pImpl->height_ - 1),
+ 0.0f,
+ 0.0f};
+ memcpy(dstPoints, points, sizeof(points));
+ } else { // ROTATION_0
+ float points[] = {0.0f,
+ 0.0f,
+ 0.0f,
+ (float)(pImpl->height_ - 1),
+ (float)(pImpl->width_ - 1),
+ 0.0f,
+ (float)(pImpl->width_ - 1),
+ (float)(pImpl->height_ - 1)};
+ memcpy(dstPoints, points, sizeof(points));
+ }
+
+ MNN::CV::Matrix tr;
+ tr.setPolyToPoly((MNN::CV::Point *)dstPoints, (MNN::CV::Point *)srcPoints, 4);
+
+ auto affine_matrix = inspirecv::TransformMatrix::Create();
+ affine_matrix[0] = tr[0];
+ affine_matrix[1] = tr[1];
+ affine_matrix[2] = tr[2];
+ affine_matrix[3] = tr[3];
+ affine_matrix[4] = tr[4];
+ affine_matrix[5] = tr[5];
+
+ return affine_matrix;
+}
+
+} // namespace inspirecv
\ No newline at end of file
diff --git a/cpp-package/inspireface/cpp/inspireface/middleware/nexus_processor/image_processor.cpp b/cpp-package/inspireface/cpp/inspireface/image_process/nexus_processor/image_processor.cpp
similarity index 100%
rename from cpp-package/inspireface/cpp/inspireface/middleware/nexus_processor/image_processor.cpp
rename to cpp-package/inspireface/cpp/inspireface/image_process/nexus_processor/image_processor.cpp
diff --git a/cpp-package/inspireface/cpp/inspireface/middleware/nexus_processor/image_processor.h b/cpp-package/inspireface/cpp/inspireface/image_process/nexus_processor/image_processor.h
similarity index 100%
rename from cpp-package/inspireface/cpp/inspireface/middleware/nexus_processor/image_processor.h
rename to cpp-package/inspireface/cpp/inspireface/image_process/nexus_processor/image_processor.h
diff --git a/cpp-package/inspireface/cpp/inspireface/middleware/nexus_processor/image_processor_general.cpp b/cpp-package/inspireface/cpp/inspireface/image_process/nexus_processor/image_processor_general.cpp
similarity index 100%
rename from cpp-package/inspireface/cpp/inspireface/middleware/nexus_processor/image_processor_general.cpp
rename to cpp-package/inspireface/cpp/inspireface/image_process/nexus_processor/image_processor_general.cpp
diff --git a/cpp-package/inspireface/cpp/inspireface/middleware/nexus_processor/image_processor_general.h b/cpp-package/inspireface/cpp/inspireface/image_process/nexus_processor/image_processor_general.h
similarity index 100%
rename from cpp-package/inspireface/cpp/inspireface/middleware/nexus_processor/image_processor_general.h
rename to cpp-package/inspireface/cpp/inspireface/image_process/nexus_processor/image_processor_general.h
diff --git a/cpp-package/inspireface/cpp/inspireface/middleware/nexus_processor/image_processor_rga.cpp b/cpp-package/inspireface/cpp/inspireface/image_process/nexus_processor/image_processor_rga.cpp
similarity index 100%
rename from cpp-package/inspireface/cpp/inspireface/middleware/nexus_processor/image_processor_rga.cpp
rename to cpp-package/inspireface/cpp/inspireface/image_process/nexus_processor/image_processor_rga.cpp
diff --git a/cpp-package/inspireface/cpp/inspireface/middleware/nexus_processor/image_processor_rga.h b/cpp-package/inspireface/cpp/inspireface/image_process/nexus_processor/image_processor_rga.h
similarity index 97%
rename from cpp-package/inspireface/cpp/inspireface/middleware/nexus_processor/image_processor_rga.h
rename to cpp-package/inspireface/cpp/inspireface/image_process/nexus_processor/image_processor_rga.h
index 00e85b2..fb16a3b 100644
--- a/cpp-package/inspireface/cpp/inspireface/middleware/nexus_processor/image_processor_rga.h
+++ b/cpp-package/inspireface/cpp/inspireface/image_process/nexus_processor/image_processor_rga.h
@@ -25,7 +25,7 @@
#include "RgaUtils.h"
#include "rga/utils.h"
#include "rga/dma_alloc.h"
-#include "initialization_module/launch.h"
+#include
namespace inspire {
@@ -109,7 +109,7 @@ private:
channels = c;
buffer_size = width * height * channels;
- int ret = dma_buf_alloc(INSPIRE_LAUNCH->GetRockchipDmaHeapPath().c_str(), buffer_size, &dma_fd, &virtual_addr);
+ int ret = dma_buf_alloc(INSPIREFACE_CONTEXT->GetRockchipDmaHeapPath().c_str(), buffer_size, &dma_fd, &virtual_addr);
if (ret < 0) {
INSPIRECV_LOG(ERROR) << "Failed to allocate DMA buffer: " << ret;
return false;
diff --git a/cpp-package/inspireface/cpp/inspireface/middleware/nexus_processor/rga/dma_alloc.cpp b/cpp-package/inspireface/cpp/inspireface/image_process/nexus_processor/rga/dma_alloc.cpp
similarity index 100%
rename from cpp-package/inspireface/cpp/inspireface/middleware/nexus_processor/rga/dma_alloc.cpp
rename to cpp-package/inspireface/cpp/inspireface/image_process/nexus_processor/rga/dma_alloc.cpp
diff --git a/cpp-package/inspireface/cpp/inspireface/middleware/nexus_processor/rga/dma_alloc.h b/cpp-package/inspireface/cpp/inspireface/image_process/nexus_processor/rga/dma_alloc.h
similarity index 100%
rename from cpp-package/inspireface/cpp/inspireface/middleware/nexus_processor/rga/dma_alloc.h
rename to cpp-package/inspireface/cpp/inspireface/image_process/nexus_processor/rga/dma_alloc.h
diff --git a/cpp-package/inspireface/cpp/inspireface/middleware/nexus_processor/rga/utils.cpp b/cpp-package/inspireface/cpp/inspireface/image_process/nexus_processor/rga/utils.cpp
similarity index 100%
rename from cpp-package/inspireface/cpp/inspireface/middleware/nexus_processor/rga/utils.cpp
rename to cpp-package/inspireface/cpp/inspireface/image_process/nexus_processor/rga/utils.cpp
diff --git a/cpp-package/inspireface/cpp/inspireface/middleware/nexus_processor/rga/utils.h b/cpp-package/inspireface/cpp/inspireface/image_process/nexus_processor/rga/utils.h
similarity index 100%
rename from cpp-package/inspireface/cpp/inspireface/middleware/nexus_processor/rga/utils.h
rename to cpp-package/inspireface/cpp/inspireface/image_process/nexus_processor/rga/utils.h
diff --git a/cpp-package/inspireface/cpp/inspireface/include/inspireface/cuda_toolkit.h b/cpp-package/inspireface/cpp/inspireface/include/inspireface/cuda_toolkit.h
new file mode 100644
index 0000000..14cf649
--- /dev/null
+++ b/cpp-package/inspireface/cpp/inspireface/include/inspireface/cuda_toolkit.h
@@ -0,0 +1,22 @@
+#ifndef INSPIRE_CUDA_TOOLKIT_H
+#define INSPIRE_CUDA_TOOLKIT_H
+
+#include "data_type.h"
+
+namespace inspire {
+
+// Get the number of CUDA devices
+int32_t INSPIRE_API_EXPORT GetCudaDeviceCount(int32_t *device_count);
+
+// Check the availability of CUDA
+int32_t INSPIRE_API_EXPORT CheckCudaUsability(int32_t *is_support);
+
+// Internal function, print detailed information of CUDA devices
+int32_t INSPIRE_API_EXPORT _PrintCudaDeviceInfo();
+
+// Wrapper function to print CUDA device information
+int32_t INSPIRE_API_EXPORT PrintCudaDeviceInfo();
+
+} // namespace inspire
+
+#endif // INSPIRE_CUDA_TOOLKIT_H
\ No newline at end of file
diff --git a/cpp-package/inspireface/cpp/inspireface/data_type.h b/cpp-package/inspireface/cpp/inspireface/include/inspireface/data_type.h
similarity index 52%
rename from cpp-package/inspireface/cpp/inspireface/data_type.h
rename to cpp-package/inspireface/cpp/inspireface/include/inspireface/data_type.h
index 7792909..e9c46d9 100644
--- a/cpp-package/inspireface/cpp/inspireface/data_type.h
+++ b/cpp-package/inspireface/cpp/inspireface/include/inspireface/data_type.h
@@ -6,6 +6,8 @@
#ifndef INSPIRE_FACE_DATATYPE_H
#define INSPIRE_FACE_DATATYPE_H
+#include
+
#include
#if defined(_WIN32) && (defined(_DEBUG) || defined(DEBUG))
#define _CRTDBG_MAP_ALLOC
@@ -16,7 +18,15 @@
#define INSPIRE_API
#endif
-#include
+#if defined(_WIN32)
+#ifdef ISF_BUILD_SHARED_LIBS
+#define INSPIRE_API_EXPORT __declspec(dllexport)
+#else
+#define INSPIRE_API_EXPORT
+#endif
+#else
+#define INSPIRE_API_EXPORT __attribute__((visibility("default")))
+#endif // _WIN32
#ifndef M_PI
#define M_PI 3.14159265358979323846264338327950288
@@ -152,6 +162,33 @@ typedef std::string String;
*/
typedef std::vector IndexList;
+/**
+ * @enum DetectMode
+ * @brief Enumeration for different detection modes.
+ */
+enum DetectModuleMode {
+ DETECT_MODE_ALWAYS_DETECT = 0, ///< Detection mode: Always detect
+ DETECT_MODE_LIGHT_TRACK, ///< Detection mode: Light face track
+ DETECT_MODE_TRACK_BY_DETECT, ///< Detection mode: Tracking by detection
+};
+
+/**
+ * @struct CustomPipelineParameter
+ * @brief Structure to hold custom parameters for the face detection and processing pipeline.
+ *
+ * Includes options for enabling various features such as recognition, liveness detection, and quality assessment.
+ */
+typedef struct CustomPipelineParameter {
+ bool enable_recognition = false; ///< Enable face recognition feature
+ bool enable_liveness = false; ///< Enable RGB liveness detection feature
+ bool enable_ir_liveness = false; ///< Enable IR (Infrared) liveness detection feature
+ bool enable_mask_detect = false; ///< Enable mask detection feature
+ bool enable_face_attribute = false; ///< Enable face attribute prediction feature
+ bool enable_face_quality = false; ///< Enable face quality assessment feature
+ bool enable_interaction_liveness = false; ///< Enable interactive liveness detection feature
+ bool enable_face_pose = false; ///< Enable face pose estimation feature
+} ContextCustomParameter;
+
/** @struct FaceLoc
* @brief Struct representing standardized face landmarks for detection.
*
@@ -191,6 +228,74 @@ typedef struct FaceFeatureEntity {
float* data;
} FaceFeaturePtr;
+// Search for most similar vectors
+struct FaceSearchResult {
+ int64_t id;
+ double similarity;
+ std::vector feature;
+};
+
+/** @struct FaceEmbedding
+ * @brief Struct for face embedding data.
+ *
+ * Contains the isNormal flag and the embedding vector.
+ */
+struct FaceEmbedding {
+ int32_t isNormal;
+ float norm;
+ Embedded embedding;
+};
+
+/** @struct FaceInteractionState
+ * @brief Struct for face interaction state data.
+ *
+ * Contains the confidence scores for face interaction.
+ */
+struct FaceInteractionState {
+ float left_eye_status_confidence;
+ float right_eye_status_confidence;
+};
+
+/** @struct FaceInteractionAction
+ * @brief Struct for face interaction action data.
+ *
+ * Contains the actions for face interaction.
+ */
+struct FaceInteractionAction {
+ int32_t normal; ///< Normal action.
+ int32_t shake; ///< Shake action.
+ int32_t jawOpen; ///< Jaw open action.
+ int32_t headRaise; ///< Head raise action.
+ int32_t blink; ///< Blink action.
+};
+
+/** @struct FaceAttributeResult
+ * @brief Struct for face attribute result data.
+ *
+ * Contains the results for face attribute.
+ */
+struct FaceAttributeResult {
+ int32_t race; ///< Race of the detected face.
+ ///< 0: Black;
+ ///< 1: Asian;
+ ///< 2: Latino/Hispanic;
+ ///< 3: Middle Eastern;
+ ///< 4: White;
+ int32_t gender; ///< Gender of the detected face.
+ ///< 0: Female;
+ ///< 1: Male;
+ int32_t ageBracket; ///< Age bracket of the detected face.
+ ///< 0: 0-2 years old;
+ ///< 1: 3-9 years old;
+ ///< 2: 10-19 years old;
+ ///< 3: 20-29 years old;
+ ///< 4: 30-39 years old;
+ ///< 5: 40-49 years old;
+ ///< 6: 50-59 years old;
+ ///< 7: 60-69 years old;
+ ///< 8: more than 70 years old;
+};
+
/** @} */
} // namespace inspire
diff --git a/cpp-package/inspireface/cpp/inspireface/common/face_data/face_data_type.h b/cpp-package/inspireface/cpp/inspireface/include/inspireface/face_warpper.h
similarity index 88%
rename from cpp-package/inspireface/cpp/inspireface/common/face_data/face_data_type.h
rename to cpp-package/inspireface/cpp/inspireface/include/inspireface/face_warpper.h
index bb81cd8..96c3635 100644
--- a/cpp-package/inspireface/cpp/inspireface/common/face_data/face_data_type.h
+++ b/cpp-package/inspireface/cpp/inspireface/include/inspireface/face_warpper.h
@@ -8,11 +8,8 @@
#ifndef INSPIRE_FACE_FACEDATATYPE_H
#define INSPIRE_FACE_FACEDATATYPE_H
-// Include the necessary header files
-#include "../../data_type.h"
-#include "../face_info/face_object_internal.h"
+#include "data_type.h"
-// Define the namespace "inspire" for encapsulation
namespace inspire {
/**
@@ -55,9 +52,9 @@ typedef struct TransMatrix {
} TransMatrix;
/**
- * Struct to represent hyper face data.
+ * Struct to represent basic face data.
*/
-typedef struct HyperFaceData {
+typedef struct FaceTrackWrap {
int trackState; ///< Track state
int inGroupIndex; ///< Index within a group
int trackId; ///< Track ID
@@ -69,7 +66,7 @@ typedef struct HyperFaceData {
float quality[5]; ///< Quality values for key points
Point2F densityLandmark[106]; ///< Face density landmark
int densityLandmarkEnable; ///< Density landmark enable
-} HyperFaceData;
+} FaceTrackWrap;
} // namespace inspire
diff --git a/cpp-package/inspireface/cpp/inspireface/feature_hub/feature_hub_db.h b/cpp-package/inspireface/cpp/inspireface/include/inspireface/feature_hub_db.h
similarity index 64%
rename from cpp-package/inspireface/cpp/inspireface/feature_hub/feature_hub_db.h
rename to cpp-package/inspireface/cpp/inspireface/include/inspireface/feature_hub_db.h
index 8c33ce7..a683b7e 100644
--- a/cpp-package/inspireface/cpp/inspireface/feature_hub/feature_hub_db.h
+++ b/cpp-package/inspireface/cpp/inspireface/include/inspireface/feature_hub_db.h
@@ -6,28 +6,17 @@
#ifndef INSPIRE_FEATURE_HUB_DB_H
#define INSPIRE_FEATURE_HUB_DB_H
-#include
+#include
#include
#include
-#include
#include "data_type.h"
-#include "feature_hub/embedding_db/embedding_db.h"
-#include "log.h"
+#include
-// Default database file name used in the FaceContext.
-#define DB_FILE_NAME ".feature_hub_db_v0"
-
-#define FEATURE_HUB_DB FeatureHubDB::GetInstance()
+#define INSPIREFACE_FEATURE_HUB inspire::FeatureHubDB::GetInstance()
+#define INSPIRE_INVALID_ID -1
namespace inspire {
-// Comparator function object to sort SearchResult by score (descending order)
-struct CompareByScore {
- bool operator()(const FaceSearchResult& a, const FaceSearchResult& b) const {
- return a.similarity > b.similarity;
- }
-};
-
typedef enum SearchMode {
SEARCH_MODE_EAGER = 0, // Eager mode: Stops when a vector meets the threshold.
SEARCH_MODE_EXHAUSTIVE, // Exhaustive mode: Searches until the best match is found.
@@ -43,7 +32,7 @@ typedef enum PrimaryKeyMode {
* @brief Structure to configure database settings for FaceRecognition.
*/
using DatabaseConfiguration = struct DatabaseConfiguration {
- PrimaryKeyMode primary_key_mode = PrimaryKeyMode::AUTO_INCREMENT; ///<
+ PrimaryKeyMode primary_key_mode = PrimaryKeyMode::AUTO_INCREMENT; ///< Primary key mode
bool enable_persistence = false; ///< Whether to enable data persistence.
std::string persistence_db_path; ///< Path to the database file.
float recognition_threshold = 0.48f; ///< Face search threshold
@@ -51,72 +40,75 @@ using DatabaseConfiguration = struct DatabaseConfiguration {
};
/**
- * @class FeatureHub
+ * @class FeatureHubDB
* @brief Service for internal feature vector storage.
*
* This class provides methods for face feature extraction, registration, update, search, and more.
+ * It uses the PIMPL (Pointer to Implementation) pattern to hide implementation details.
*/
-class INSPIRE_API FeatureHubDB {
-private:
- static std::mutex mutex_; ///< Mutex lock
- static std::shared_ptr instance_; ///< FeatureHub Instance
+class INSPIRE_API_EXPORT FeatureHubDB {
+public:
+ /**
+ * @brief Constructor for FeatureHubDB class.
+ */
+ FeatureHubDB();
+
+ /**
+ * @brief Destructor for FeatureHubDB class.
+ */
+ ~FeatureHubDB();
FeatureHubDB(const FeatureHubDB&) = delete;
FeatureHubDB& operator=(const FeatureHubDB&) = delete;
-public:
/**
- * @brief Enables the feature hub with the specified configuration and matrix core.
- *
- * This function initializes and configures the feature hub based on the provided database
- * configuration and the specified matrix processing core. It prepares the hub for operation,
- * setting up necessary resources such as database connections and data processing pipelines.
- *
- * @param configuration The database configuration settings used to configure the hub.
- * @param core The matrix core used for processing, defaulting to OpenCV if not specified.
+ * @brief Gets the singleton instance of FeatureHubDB.
+ * @return Shared pointer to the FeatureHubDB instance.
+ */
+ static std::shared_ptr GetInstance();
+
+ /**
+ * @brief Enables the feature hub with the specified configuration.
+ * @param configuration The database configuration settings.
* @return int32_t Returns a status code indicating success (0) or failure (non-zero).
*/
int32_t EnableHub(const DatabaseConfiguration& configuration);
/**
* @brief Disables the feature hub, freeing all associated resources.
- *
- * This function stops all operations within the hub, releases all occupied resources,
- * such as database connections and internal data structures. It is used to safely
- * shutdown the hub when it is no longer needed or before the application exits, ensuring
- * that all resources are properly cleaned up.
- *
* @return int32_t Returns a status code indicating success (0) or failure (non-zero).
*/
int32_t DisableHub();
/**
* @brief Get all ids in the database.
- * @param ids Output parameter to store the ids.
* @return int32_t Status code of the operation.
*/
int32_t GetAllIds();
- static std::shared_ptr GetInstance();
-
/**
* @brief Searches for a face feature within stored data.
* @param queryFeature Embedded feature to search for.
* @param searchResult SearchResult object to store search results.
+ * @param returnFeature Whether to return the feature data.
* @return int32_t Status code of the search operation.
*/
int32_t SearchFaceFeature(const Embedded& queryFeature, FaceSearchResult& searchResult, bool returnFeature = true);
/**
* @brief Search the stored data for the top k facial features that are most similar.
- * @param topK Maximum search
+ * @param queryFeature Embedded feature to search for.
+ * @param topK Maximum number of results to return.
* @return int32_t Status code of the search operation.
*/
int32_t SearchFaceFeatureTopKCache(const Embedded& queryFeature, size_t topK);
/**
* @brief Search the stored data for the top k facial features that are most similar.
- * @param topK Maximum search
+ * @param queryFeature Embedded feature to search for.
+ * @param searchResult Vector to store search results.
+ * @param topK Maximum number of results to return.
+ * @param returnFeature Whether to return the feature data.
* @return int32_t Status code of the search operation.
*/
int32_t SearchFaceFeatureTopK(const Embedded& queryFeature, std::vector& searchResult, size_t topK, bool returnFeature = false);
@@ -124,39 +116,38 @@ public:
/**
* @brief Inserts a face feature with a custom ID.
* @param feature Vector of floats representing the face feature.
- * @param tag String tag associated with the feature.
- * @param customId Custom ID for the feature.
+ * @param id ID for the feature.
+ * @param result_id Output parameter to store the resulting ID.
* @return int32_t Status code of the insertion operation.
*/
int32_t FaceFeatureInsert(const std::vector& feature, int32_t id, int64_t& result_id);
/**
- * @brief Removes a face feature by its custom ID.
- * @param customId Custom ID of the feature to remove.
+ * @brief Removes a face feature by its ID.
+ * @param id ID of the feature to remove.
* @return int32_t Status code of the removal operation.
*/
int32_t FaceFeatureRemove(int32_t id);
/**
- * @brief Updates a face feature by its custom ID.
+ * @brief Updates a face feature by its ID.
* @param feature Vector of floats representing the new face feature.
- * @param tag String tag associated with the feature.
- * @param customId Custom ID of the feature to update.
+ * @param customId ID of the feature to update.
* @return int32_t Status code of the update operation.
*/
int32_t FaceFeatureUpdate(const std::vector& feature, int32_t customId);
/**
- * @brief Retrieves a face feature by its custom ID.
- * @param customId Custom ID of the feature to retrieve.
+ * @brief Retrieves a face feature by its ID.
+ * @param id ID of the feature to retrieve.
* @return int32_t Status code of the retrieval operation.
*/
int32_t GetFaceFeature(int32_t id);
/**
- * @brief Retrieves a face feature by its custom ID.
- * @param customId Custom ID of the feature to retrieve.
- * @param feature Vector of floats representing the face feature.
+ * @brief Retrieves a face feature by its ID.
+ * @param id ID of the feature to retrieve.
+ * @param feature Vector to store the retrieved feature.
* @return int32_t Status code of the retrieval operation.
*/
int32_t GetFaceFeature(int32_t id, std::vector& feature);
@@ -181,27 +172,26 @@ public:
/**
* @brief Computes the cosine similarity between two feature vectors.
- *
* @param v1 First feature vector.
* @param v2 Second feature vector.
* @param res Output parameter to store the cosine similarity result.
+ * @param normalize Whether to normalize the vectors before computing similarity.
* @return int32_t Status code indicating success (0) or failure.
*/
static int32_t CosineSimilarity(const std::vector& v1, const std::vector& v2, float& res, bool normalize = false);
/**
* @brief Computes the cosine similarity between two feature vectors.
- *
* @param v1 Pointer to the first feature vector.
* @param v2 Pointer to the second feature vector.
* @param size Size of the feature vectors.
* @param res Output parameter to store the cosine similarity result.
+ * @param normalize Whether to normalize the vectors before computing similarity.
* @return int32_t Status code indicating success (0) or failure.
*/
static int32_t CosineSimilarity(const float* v1, const float* v2, int32_t size, float& res, bool normalize = true);
-public:
- // Getter Function
+ // Getter methods
/**
* @brief Gets the cache used for search operations in face feature data.
@@ -216,8 +206,7 @@ public:
const std::shared_ptr& GetFaceFeaturePtrCache() const;
/**
- * @brief Retrieves the total number of facial features stored in the feature block.
- *
+ * @brief Retrieves the total number of facial features stored.
* @return int32_t Total number of facial features.
*/
int32_t GetFaceFeatureCount();
@@ -240,37 +229,15 @@ public:
*/
std::vector& GetExistingIds();
- /**
- * @brief Constructor for FeatureHub class.
- */
- FeatureHubDB();
-
- /**
- * @brief Prints information about the feature matrix.
- */
- void PrintFeatureMatrixInfo();
-
private:
- Embedded m_search_face_feature_cache_; ///< Cache for face feature data used in search operations
- Embedded m_getter_face_feature_cache_; ///< Cache for face feature data used in search operations
- std::shared_ptr m_face_feature_ptr_cache_; ///< Shared pointer to cache of face feature pointers
+ class Impl;
- std::vector m_search_top_k_cache_; ///< Cache for top k search results
- std::vector m_top_k_confidence_; ///< Cache for top k confidence scores
- std::vector m_top_k_custom_ids_cache_; ///< Cache for top k custom ids
+ std::unique_ptr pImpl;
- std::vector m_all_ids_; ///< Cache for all ids
-
-private:
- DatabaseConfiguration m_db_configuration_; ///< Configuration settings for the database
- float m_recognition_threshold_{0.48f}; ///< Threshold value for face recognition
- SearchMode m_search_mode_{SEARCH_MODE_EAGER}; ///< Flag to determine if the search should find the most similar feature
-
- bool m_enable_{false}; ///< Running status
-
- std::mutex m_res_mtx_; ///< Mutex for thread safety.
+ static std::mutex mutex_;
+ static std::shared_ptr instance_;
};
} // namespace inspire
-#endif // INSPIRE_FEATURE_HUB_DB_H
+#endif // INSPIRE_FEATURE_HUB_DB_H
\ No newline at end of file
diff --git a/cpp-package/inspireface/cpp/inspireface/include/inspireface/frame_process.h b/cpp-package/inspireface/cpp/inspireface/include/inspireface/frame_process.h
new file mode 100644
index 0000000..17ed60d
--- /dev/null
+++ b/cpp-package/inspireface/cpp/inspireface/include/inspireface/frame_process.h
@@ -0,0 +1,198 @@
+#ifndef INSPIREFACE_FRAME_PROCESS_H
+#define INSPIREFACE_FRAME_PROCESS_H
+
+#include
+#include
+#include "data_type.h"
+
+namespace inspirecv {
+
+/**
+ * @brief Enum to represent rotation modes.
+ */
+enum ROTATION_MODE { ROTATION_0 = 0, ROTATION_90 = 1, ROTATION_180 = 2, ROTATION_270 = 3 };
+
+/**
+ * @brief Enum to represent data formats.
+ */
+enum DATA_FORMAT { NV21 = 0, NV12 = 1, RGBA = 2, RGB = 3, BGR = 4, BGRA = 5 };
+
+/**
+ * @brief A class to handle camera stream and image processing.
+ */
+class INSPIRE_API_EXPORT FrameProcess {
+public:
+ /**
+ * @brief Create a FrameProcess instance.
+ *
+ * @param data_buffer Pointer to the data buffer.
+ * @param height Height of the image.
+ * @param width Width of the image.
+ * @param data_format Data format (e.g., NV21, RGBA).
+ * @param rotation_mode Rotation mode (e.g., ROTATION_0, ROTATION_90).
+ * @return FrameProcess instance.
+ */
+ static FrameProcess Create(const uint8_t* data_buffer, int height, int width, DATA_FORMAT data_format = BGR,
+ ROTATION_MODE rotation_mode = ROTATION_0);
+
+ /**
+ * @brief Create a FrameProcess instance from an inspirecv::Image.
+ *
+ * @param image The image to process.
+ * @param data_format Data format (e.g., NV21, RGBA).
+ * @param rotation_mode Rotation mode (e.g., ROTATION_0, ROTATION_90).
+ * @return FrameProcess instance.
+ */
+ static FrameProcess Create(const inspirecv::Image& image, DATA_FORMAT data_format = BGR, ROTATION_MODE rotation_mode = ROTATION_0);
+
+ /**
+ * @brief Default constructor.
+ */
+ FrameProcess();
+
+ /**
+ * @brief Destructor.
+ */
+ ~FrameProcess();
+
+ /**
+ * @brief Copy constructor.
+ */
+ FrameProcess(const FrameProcess& other);
+
+ /**
+ * @brief Move constructor.
+ */
+ FrameProcess(FrameProcess&& other) noexcept;
+
+ /**
+ * @brief Copy assignment operator.
+ */
+ FrameProcess& operator=(const FrameProcess& other);
+
+ /**
+ * @brief Move assignment operator.
+ */
+ FrameProcess& operator=(FrameProcess&& other) noexcept;
+
+ /**
+ * @brief Set the data buffer, height, and width of the camera stream.
+ *
+ * @param data_buffer Pointer to the data buffer.
+ * @param height Height of the image.
+ * @param width Width of the image.
+ */
+ void SetDataBuffer(const uint8_t* data_buffer, int height, int width);
+
+ /**
+ * @brief Set the preview size.
+ *
+ * @param size Preview size.
+ */
+ void SetPreviewSize(const int size);
+
+ /**
+ * @brief Set the preview scale.
+ *
+ * @param scale Preview scale.
+ */
+ void SetPreviewScale(const float scale);
+
+ /**
+ * @brief Set the rotation mode.
+ *
+ * @param mode Rotation mode (e.g., ROTATION_0, ROTATION_90).
+ */
+ void SetRotationMode(ROTATION_MODE mode);
+
+ /**
+ * @brief Set the data format.
+ *
+ * @param data_format Data format (e.g., NV21, RGBA).
+ */
+ void SetDataFormat(DATA_FORMAT data_format);
+
+ /**
+ * @brief Set the destination format.
+ *
+ * @param data_format Data format (e.g., NV21, RGBA).
+ */
+ void SetDestFormat(DATA_FORMAT data_format);
+
+ /**
+ * @brief Get an affine-transformed image.
+ *
+ * @param affine_matrix Affine transformation matrix.
+ * @param width_out Width of the output image.
+ * @param height_out Height of the output image.
+ * @return inspirecv::Image Affine-transformed image.
+ */
+ inspirecv::Image ExecuteImageAffineProcessing(inspirecv::TransformMatrix& affine_matrix, const int width_out, const int height_out) const;
+
+ /**
+ * @brief Get a preview image with optional rotation.
+ *
+ * @param with_rotation True if rotation is applied, false otherwise.
+ * @return inspirecv::Image Preview image.
+ */
+ inspirecv::Image ExecutePreviewImageProcessing(bool with_rotation);
+
+ /**
+ * @brief Get the preview scale.
+ *
+ * @return float Preview scale.
+ */
+ float GetPreviewScale();
+
+ /**
+ * @brief Execute image scale processing.
+ *
+ * @param scale Scale factor.
+ * @param with_rotation True if rotation is applied, false otherwise.
+ * @return inspirecv::Image Scaled image.
+ */
+ inspirecv::Image ExecuteImageScaleProcessing(const float scale, bool with_rotation);
+
+ /**
+ * @brief Get the affine transformation matrix.
+ *
+ * @return inspirecv::TransformMatrix Affine transformation matrix.
+ */
+ inspirecv::TransformMatrix GetAffineMatrix() const;
+
+ /**
+ * @brief Get the rotation mode affine transformation matrix, scale coefficient is not included.
+ *
+ * @return inspirecv::TransformMatrix Rotation mode affine transformation matrix.
+ */
+ inspirecv::TransformMatrix GetRotationModeAffineMatrix() const;
+
+ /**
+ * @brief Get the height of the camera stream image.
+ *
+ * @return int Height.
+ */
+ int GetHeight() const;
+
+ /**
+ * @brief Get the width of the camera stream image.
+ *
+ * @return int Width.
+ */
+ int GetWidth() const;
+
+ /**
+ * @brief Get the current rotation mode.
+ *
+ * @return ROTATION_MODE Current rotation mode.
+ */
+ ROTATION_MODE getRotationMode() const;
+
+private:
+ class Impl;
+ std::unique_ptr pImpl;
+};
+
+} // namespace inspirecv
+
+#endif // INSPIREFACE_FRAME_PROCESS_H
\ No newline at end of file
diff --git a/cpp-package/inspireface/cpp/inspireface/herror.h b/cpp-package/inspireface/cpp/inspireface/include/inspireface/herror.h
similarity index 100%
rename from cpp-package/inspireface/cpp/inspireface/herror.h
rename to cpp-package/inspireface/cpp/inspireface/include/inspireface/herror.h
diff --git a/cpp-package/inspireface/cpp/inspireface/include/inspireface/inspireface.hpp b/cpp-package/inspireface/cpp/inspireface/include/inspireface/inspireface.hpp
new file mode 100644
index 0000000..482607e
--- /dev/null
+++ b/cpp-package/inspireface/cpp/inspireface/include/inspireface/inspireface.hpp
@@ -0,0 +1,14 @@
+#include "session.h"
+#include "cuda_toolkit.h"
+#include "data_type.h"
+#include "log.h"
+#include "herror.h"
+#include "feature_hub_db.h"
+#include "frame_process.h"
+#include "isf_check.h"
+#include "launch.h"
+#include "log.h"
+#include "similarity_converter.h"
+#include "spend_timer.h"
+#include "information.h"
+#include "face_warpper.h"
\ No newline at end of file
diff --git a/cpp-package/inspireface/cpp/inspireface/include/inspireface/isf_check.h b/cpp-package/inspireface/cpp/inspireface/include/inspireface/isf_check.h
new file mode 100644
index 0000000..44692d1
--- /dev/null
+++ b/cpp-package/inspireface/cpp/inspireface/include/inspireface/isf_check.h
@@ -0,0 +1,33 @@
+#ifndef INSPIRE_FACE_CHECK_H
+#define INSPIRE_FACE_CHECK_H
+#include "log.h"
+#include "herror.h"
+
+#define INSPIREFACE_RETURN_IF_ERROR(...) \
+ do { \
+ const int32_t _status = (__VA_ARGS__); \
+ if (_status != HSUCCEED) { \
+ INSPIRE_LOGE("Error code: %d", _status); \
+ return _status; \
+ } \
+ } while (0)
+
+#define INSPIREFACE_LOG_IF(severity, condition) \
+ if (condition) \
+ INSPIRE_LOG##severity
+
+#define INSPIREFACE_CHECK(condition) \
+ do { \
+ if (!(condition)) { \
+ INSPIRE_LOGF("Check failed: (%s)", #condition); \
+ } \
+ } while (0)
+
+#define INSPIREFACE_CHECK_MSG(condition, message) \
+ do { \
+ if (!(condition)) { \
+ INSPIRE_LOGF("Check failed: (%s) %s", #condition, message); \
+ } \
+ } while (0)
+
+#endif // INSPIRE_FACE_CHECK_H
diff --git a/cpp-package/inspireface/cpp/inspireface/Initialization_module/launch.h b/cpp-package/inspireface/cpp/inspireface/include/inspireface/launch.h
similarity index 54%
rename from cpp-package/inspireface/cpp/inspireface/Initialization_module/launch.h
rename to cpp-package/inspireface/cpp/inspireface/include/inspireface/launch.h
index 7e593dc..f546b6a 100644
--- a/cpp-package/inspireface/cpp/inspireface/Initialization_module/launch.h
+++ b/cpp-package/inspireface/cpp/inspireface/include/inspireface/launch.h
@@ -5,28 +5,42 @@
#pragma once
#ifndef INSPIREFACE_LAUNCH_H
#define INSPIREFACE_LAUNCH_H
-#include "middleware/model_archive/inspire_archive.h"
-#if defined(ISF_ENABLE_RGA)
-#include "middleware/nexus_processor/rga/dma_alloc.h"
-#endif
-#include
-#include "middleware/inference_wrapper/inference_wrapper.h"
-#include "middleware/system.h"
-#ifndef INSPIRE_API
-#define INSPIRE_API
-#endif
+#include
+#include
+#include
+#include "data_type.h"
-#define INSPIRE_LAUNCH inspire::Launch::GetInstance()
+#define INSPIREFACE_CONTEXT inspire::Launch::GetInstance()
namespace inspire {
+// Forward declarations
+class InspireArchive;
+
// The Launch class acts as the main entry point for the InspireFace system.
// It is responsible for loading static resources such as models, configurations, and parameters.
-class INSPIRE_API Launch {
+class INSPIRE_API_EXPORT Launch {
public:
+ // Special Backend enum for CoreML
+ enum NNInferenceBackend {
+ NN_INFERENCE_CPU = 0,
+ NN_INFERENCE_MMM_CUDA,
+ NN_INFERENCE_COREML_CPU,
+ NN_INFERENCE_COREML_GPU,
+ NN_INFERENCE_COREML_ANE,
+ NN_INFERENCE_TENSORRT_CUDA,
+ };
+
+ enum LandmarkEngine {
+ LANDMARK_HYPLMV2_0_25 = 0,
+ LANDMARK_HYPLMV2_0_50,
+ LANDMARK_INSIGHTFACE_2D106_TRACK,
+ };
+
Launch(const Launch&) = delete; // Delete the copy constructor to prevent copying.
Launch& operator=(const Launch&) = delete; // Delete the assignment operator to prevent assignment.
+ ~Launch(); // Destructor needs to be defined where the implementation is complete
// Retrieves the singleton instance of Launch, ensuring that only one instance exists.
static std::shared_ptr GetInstance();
@@ -61,10 +75,10 @@ public:
std::string GetExtensionPath() const;
// Set the global coreml inference mode
- void SetGlobalCoreMLInferenceMode(InferenceWrapper::SpecialBackend mode);
+ void SetGlobalCoreMLInferenceMode(NNInferenceBackend mode);
// Get the global coreml inference mode
- InferenceWrapper::SpecialBackend GetGlobalCoreMLInferenceMode() const;
+ NNInferenceBackend GetGlobalCoreMLInferenceMode() const;
// Build the extension path
void BuildAppleExtensionPath(const std::string& resource_path);
@@ -75,35 +89,30 @@ public:
// Get the cuda device id
int32_t GetCudaDeviceId() const;
+ // Set the face detect pixel list
+ void SetFaceDetectPixelList(const std::vector& pixel_list);
+
+ // Get the face detect pixel list
+ std::vector GetFaceDetectPixelList() const;
+
+ // Set the face detect model list
+ void SetFaceDetectModelList(const std::vector& model_list);
+
+ // Get the face detect model list
+ std::vector GetFaceDetectModelList() const;
+
+ // Switch the landmark engine
+ void SwitchLandmarkEngine(LandmarkEngine engine);
+
private:
- // Parameters
- std::string m_rockchip_dma_heap_path_;
+ // Private constructor for the singleton pattern
+ Launch();
- // Constructor
- Launch() : m_load_(false), m_archive_(nullptr) {
-#if defined(ISF_ENABLE_RGA)
-#if defined(ISF_RKNPU_RV1106)
- m_rockchip_dma_heap_path_ = RV1106_CMA_HEAP_PATH;
-#else
- m_rockchip_dma_heap_path_ = DMA_HEAP_DMA32_UNCACHE_PATCH;
-#endif
- INSPIRE_LOGW("Rockchip dma heap configured path: %s", m_rockchip_dma_heap_path_.c_str());
-#endif
- } ///< Private constructor for the singleton pattern.
-
- static std::mutex mutex_; ///< Mutex for synchronizing access to the singleton instance.
- static std::shared_ptr instance_; ///< The singleton instance of Launch.
-
- std::string m_extension_path_;
-
- std::unique_ptr m_archive_; ///< The archive containing all necessary resources.
- bool m_load_; ///< Flag indicating whether the resources have been successfully loaded.
-
- int32_t m_cuda_device_id_{0};
-
- InferenceWrapper::SpecialBackend m_global_coreml_inference_mode_{InferenceWrapper::COREML_ANE}; ///< The global coreml inference mode
+ // Private implementation class
+ class Impl;
+ std::unique_ptr pImpl;
};
} // namespace inspire
-#endif // INSPIREFACE_LAUNCH_H
+#endif // INSPIREFACE_LAUNCH_H
\ No newline at end of file
diff --git a/cpp-package/inspireface/cpp/inspireface/include/inspireface/log.h b/cpp-package/inspireface/cpp/inspireface/include/inspireface/log.h
new file mode 100755
index 0000000..1dcd445
--- /dev/null
+++ b/cpp-package/inspireface/cpp/inspireface/include/inspireface/log.h
@@ -0,0 +1,89 @@
+#ifndef INSPIRE_FACE_LOG_H
+#define INSPIRE_FACE_LOG_H
+
+#include
+#include
+#include
+#include "data_type.h"
+
+// Macro to extract the filename from the full path
+#define __FILENAME__ (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__)
+
+#ifdef ANDROID
+// Android platform log macros
+#define INSPIRE_ANDROID_LOG_TAG "InspireFace"
+#define INSPIRE_LOGD(...) inspire::LogManager::getInstance()->logAndroid(inspire::LogLevel::ISF_LOG_DEBUG, INSPIRE_ANDROID_LOG_TAG, __VA_ARGS__)
+#define INSPIRE_LOGI(...) inspire::LogManager::getInstance()->logAndroid(inspire::LogLevel::ISF_LOG_INFO, INSPIRE_ANDROID_LOG_TAG, __VA_ARGS__)
+#define INSPIRE_LOGW(...) inspire::LogManager::getInstance()->logAndroid(inspire::LogLevel::ISF_LOG_WARN, INSPIRE_ANDROID_LOG_TAG, __VA_ARGS__)
+#define INSPIRE_LOGE(...) inspire::LogManager::getInstance()->logAndroid(inspire::LogLevel::ISF_LOG_ERROR, INSPIRE_ANDROID_LOG_TAG, __VA_ARGS__)
+#define INSPIRE_LOGF(...) inspire::LogManager::getInstance()->logAndroid(inspire::LogLevel::ISF_LOG_FATAL, INSPIRE_ANDROID_LOG_TAG, __VA_ARGS__)
+#else
+// Standard platform log macros
+#define INSPIRE_LOGD(...) \
+ inspire::LogManager::getInstance()->logStandard(inspire::LogLevel::ISF_LOG_DEBUG, __FILENAME__, __FUNCTION__, __LINE__, __VA_ARGS__)
+#define INSPIRE_LOGI(...) inspire::LogManager::getInstance()->logStandard(inspire::LogLevel::ISF_LOG_INFO, "", "", -1, __VA_ARGS__)
+#define INSPIRE_LOGW(...) inspire::LogManager::getInstance()->logStandard(inspire::LogLevel::ISF_LOG_WARN, "", "", -1, __VA_ARGS__)
+#define INSPIRE_LOGE(...) inspire::LogManager::getInstance()->logStandard(inspire::LogLevel::ISF_LOG_ERROR, "", "", -1, __VA_ARGS__)
+#define INSPIRE_LOGF(...) inspire::LogManager::getInstance()->logStandard(inspire::LogLevel::ISF_LOG_FATAL, "", "", -1, __VA_ARGS__)
+#endif
+
+// Macro to set the global log level
+#define INSPIRE_SET_LOG_LEVEL(level) inspire::LogManager::getInstance()->setLogLevel(level)
+
+namespace inspire {
+
+// Log levels
+enum LogLevel { ISF_LOG_NONE = 0, ISF_LOG_DEBUG, ISF_LOG_INFO, ISF_LOG_WARN, ISF_LOG_ERROR, ISF_LOG_FATAL };
+
+/**
+ * @class LogManager
+ * @brief A singleton class for logging messages to the console or Android logcat.
+ *
+ * This class provides methods to log messages of different severity levels (DEBUG, INFO, WARN, ERROR, FATAL)
+ * to the console or Android logcat based on the current log level setting.
+ *
+ * Implementation details are hidden using the PIMPL (Pointer to Implementation) pattern.
+ */
+class INSPIRE_API_EXPORT LogManager {
+public:
+ // Get the singleton instance
+ static LogManager* getInstance();
+
+ // Destructor
+ ~LogManager();
+
+ // Set the log level
+ void setLogLevel(LogLevel level);
+
+ // Get the current log level
+ LogLevel getLogLevel() const;
+
+#ifdef ANDROID
+ // Method for logging on the Android platform
+ void logAndroid(LogLevel level, const char* tag, const char* format, ...) const;
+#else
+ // Method for standard platform logging
+ void logStandard(LogLevel level, const char* filename, const char* function, int line, const char* format, ...) const;
+#endif
+
+private:
+ // Private constructor for singleton pattern
+ LogManager();
+
+ // Disable copy construction and assignment
+ LogManager(const LogManager&) = delete;
+ LogManager& operator=(const LogManager&) = delete;
+
+ // Forward declaration of the implementation class
+ class Impl;
+
+ // Pointer to implementation
+ std::unique_ptr pImpl;
+
+ // Static instance for singleton pattern
+ static LogManager* instance;
+};
+
+} // namespace inspire
+
+#endif // INSPIRE_FACE_LOG_H
\ No newline at end of file
diff --git a/cpp-package/inspireface/cpp/inspireface/include/inspireface/session.h b/cpp-package/inspireface/cpp/inspireface/include/inspireface/session.h
new file mode 100644
index 0000000..6a977f1
--- /dev/null
+++ b/cpp-package/inspireface/cpp/inspireface/include/inspireface/session.h
@@ -0,0 +1,199 @@
+#ifndef INSPIRE_FACE_SESSION_H
+#define INSPIRE_FACE_SESSION_H
+#include
+#include "data_type.h"
+#include "frame_process.h"
+#include "face_warpper.h"
+
+namespace inspire {
+
+/**
+ * @brief The face algorithm session class.
+ */
+class INSPIRE_API_EXPORT Session {
+public:
+ Session();
+ ~Session();
+
+ Session(Session&&) noexcept;
+ Session& operator=(Session&&) noexcept;
+
+ Session(const Session&) = delete;
+ Session& operator=(const Session&) = delete;
+
+ /**
+ * @brief Create a new session with the given parameters.
+ * @param detect_mode The mode of face detection.
+ * @param max_detect_face The maximum number of faces to detect.
+ * @param param The custom pipeline parameter.
+ * @param detect_level_px The detection level in pixels.
+ * @param track_by_detect_mode_fps The tracking frame rate.
+ * @return A new session.
+ */
+ static Session Create(DetectModuleMode detect_mode, int32_t max_detect_face, const CustomPipelineParameter& param, int32_t detect_level_px = -1,
+ int32_t track_by_detect_mode_fps = -1);
+
+ /**
+ * @brief Create a new session pointer with the given parameters.
+ * @param detect_mode The mode of face detection.
+ * @param max_detect_face The maximum number of faces to detect.
+ * @param param The custom pipeline parameter.
+ * @param detect_level_px The detection level in pixels.
+ * @param track_by_detect_mode_fps The tracking frame rate.
+ * @return A raw pointer to new session. The caller is responsible for memory management.
+ */
+ static Session* CreatePtr(DetectModuleMode detect_mode, int32_t max_detect_face, const CustomPipelineParameter& param,
+ int32_t detect_level_px = -1, int32_t track_by_detect_mode_fps = -1) {
+ return new Session(Create(detect_mode, max_detect_face, param, detect_level_px, track_by_detect_mode_fps));
+ }
+
+ /**
+ * @brief Set the track preview size.
+ * @param preview_size The preview size.
+ */
+ void SetTrackPreviewSize(int32_t preview_size);
+
+ /**
+ * @brief Set the minimum face pixel size.
+ * @param min_face_pixel_size The minimum face pixel size.
+ */
+ void SetFilterMinimumFacePixelSize(int32_t min_face_pixel_size);
+
+ /**
+ * @brief Set the face detect threshold.
+ * @param threshold The face detect threshold.
+ */
+ void SetFaceDetectThreshold(float threshold);
+
+ /**
+ * @brief Set the track mode smooth ratio.
+ * @param smooth_ratio The track mode smooth ratio.
+ */
+ void SetTrackModeSmoothRatio(int32_t smooth_ratio);
+
+ /**
+ * @brief Set the track mode num smooth cache frame.
+ * @param num_smooth_cache_frame The track mode num smooth cache frame.
+ */
+ void SetTrackModeNumSmoothCacheFrame(int32_t num_smooth_cache_frame);
+
+ /**
+ * @brief Set the track mode detect interval.
+ * @param detect_interval The track mode detect interval.
+ */
+ void SetTrackModeDetectInterval(int32_t detect_interval);
+
+ /**
+ * @brief Detect and track the faces in the frame.
+ * @param process The frame process.
+ * @param results The detected faces.
+ */
+ int32_t FaceDetectAndTrack(inspirecv::FrameProcess& process, std::vector& results);
+
+ /**
+ * @brief Get the face bounding box.
+ * @param face_data The face data.
+ * @return The face bounding box.
+ */
+ inspirecv::Rect2i GetFaceBoundingBox(const FaceTrackWrap& face_data);
+
+ /**
+ * @brief Get the face dense landmark.
+ * @param face_data The face data.
+ * @return The face dense landmark.
+ */
+ std::vector GetFaceDenseLandmark(const FaceTrackWrap& face_data);
+
+ /**
+ * @brief Get the face five key points.
+ * @param face_data The face data.
+ * @return The face five key points.
+ */
+ std::vector GetFaceFiveKeyPoints(const FaceTrackWrap& face_data);
+
+ /**
+ * @brief Extract the face feature.
+ * @param process The frame process.
+ * @param data The face data.
+ * @param embedding The face embedding.
+ * @param normalize The normalize flag.
+ */
+ int32_t FaceFeatureExtract(inspirecv::FrameProcess& process, FaceTrackWrap& data, FaceEmbedding& embedding, bool normalize = true);
+
+ /**
+ * @brief Get the face alignment image.
+ * @param process The frame process.
+ * @param data The face data.
+ * @param wrapped The wrapped image.
+ */
+ void GetFaceAlignmentImage(inspirecv::FrameProcess& process, FaceTrackWrap& data, inspirecv::Image& wrapped);
+
+ /**
+ * @brief Extract the face feature with alignment image.
+ * @param process The frame process.
+ * @param embedding The face embedding.
+ * @param normalize The normalize flag.
+ */
+ int32_t FaceFeatureExtractWithAlignmentImage(inspirecv::FrameProcess& process, FaceEmbedding& embedding, bool normalize = true);
+
+ /**
+ * @brief Extract the face feature with alignment image.
+ * @param wrapped The wrapped image.
+ * @param embedding The face embedding.
+ * @param normalize The normalize flag.
+ */
+ int32_t FaceFeatureExtractWithAlignmentImage(const inspirecv::Image& wrapped, FaceEmbedding& embedding, bool normalize = true);
+
+ /**
+ * @brief Multiple face pipeline process.
+ * @param process The frame process.
+ * @param param The custom pipeline parameter.
+ * @param face_data_list The face data list.
+ */
+ int32_t MultipleFacePipelineProcess(inspirecv::FrameProcess& process, const CustomPipelineParameter& param,
+ const std::vector& face_data_list);
+
+ /**
+ * @brief Get the RGB liveness confidence.
+ * @return The RGB liveness confidence.
+ */
+ std::vector GetRGBLivenessConfidence();
+
+ /**
+ * @brief Get the face mask confidence.
+ * @return The face mask confidence.
+ */
+ std::vector GetFaceMaskConfidence();
+
+ /**
+ * @brief Get the face quality confidence.
+ * @return The face quality confidence.
+ */
+ std::vector GetFaceQualityConfidence();
+
+ /**
+ * @brief Get the face interaction state.
+ * @return The face interaction state.
+ */
+ std::vector GetFaceInteractionState();
+
+ /**
+ * @brief Get the face interaction action.
+ * @return The face interaction action.
+ */
+ std::vector GetFaceInteractionAction();
+
+ /**
+ * @brief Get the face attribute result.
+ * @return The face attribute result.
+ */
+ std::vector GetFaceAttributeResult();
+
+private:
+ class Impl;
+ std::unique_ptr pImpl;
+};
+
+} // namespace inspire
+
+#endif // INSPIRE_FACE_SESSION_H
\ No newline at end of file
diff --git a/cpp-package/inspireface/cpp/inspireface/recognition_module/similarity_converter.h b/cpp-package/inspireface/cpp/inspireface/include/inspireface/similarity_converter.h
similarity index 98%
rename from cpp-package/inspireface/cpp/inspireface/recognition_module/similarity_converter.h
rename to cpp-package/inspireface/cpp/inspireface/include/inspireface/similarity_converter.h
index 7f9c853..f6dbae9 100644
--- a/cpp-package/inspireface/cpp/inspireface/recognition_module/similarity_converter.h
+++ b/cpp-package/inspireface/cpp/inspireface/include/inspireface/similarity_converter.h
@@ -4,6 +4,7 @@
#include
#include
#include
+#include "data_type.h"
#define SIMILARITY_CONVERTER_UPDATE_CONFIG(config) inspire::SimilarityConverter::getInstance().updateConfig(config)
#define SIMILARITY_CONVERTER_RUN(cosine) inspire::SimilarityConverter::getInstance().convert(cosine)
@@ -22,7 +23,7 @@ struct SimilarityConverterConfig {
double outputMax = 1.0; // Maximum value of output range
};
-class SimilarityConverter {
+class INSPIRE_API_EXPORT SimilarityConverter {
private:
SimilarityConverterConfig config;
double outputScale; // Scale of output range
diff --git a/cpp-package/inspireface/cpp/inspireface/include/inspireface/spend_timer.h b/cpp-package/inspireface/cpp/inspireface/include/inspireface/spend_timer.h
new file mode 100644
index 0000000..cdc2746
--- /dev/null
+++ b/cpp-package/inspireface/cpp/inspireface/include/inspireface/spend_timer.h
@@ -0,0 +1,51 @@
+#ifndef INSPIRE_FACE_TIMER_H
+#define INSPIRE_FACE_TIMER_H
+
+#include "data_type.h"
+
+namespace inspire {
+
+// Get the current time in microseconds.
+uint64_t INSPIRE_API_EXPORT _now();
+
+/**
+ * @brief A class to measure the cost of a block of code.
+ */
+class INSPIRE_API_EXPORT SpendTimer {
+public:
+ SpendTimer();
+ explicit SpendTimer(const std::string &name);
+
+ void Start();
+ void Stop();
+ void Reset();
+
+ uint64_t Get() const;
+ uint64_t Average() const;
+ uint64_t Total() const;
+ uint64_t Count() const;
+ uint64_t Min() const;
+ uint64_t Max() const;
+ const std::string &name() const;
+ std::string Report() const;
+
+ static void Disable();
+
+protected:
+ uint64_t start_;
+ uint64_t stop_;
+ uint64_t total_;
+ uint64_t count_;
+ uint64_t min_;
+ uint64_t max_;
+ std::string name_;
+
+ static int is_enable;
+};
+
+INSPIRE_API_EXPORT std::ostream &operator<<(std::ostream &os, const SpendTimer &timer);
+
+#define TIME_NOW inspirecv::_now()
+
+} // namespace inspire
+#endif // INSPIRE_FACE_TIMER_H
diff --git a/cpp-package/inspireface/cpp/inspireface/information.h b/cpp-package/inspireface/cpp/inspireface/information.h
deleted file mode 100644
index 6815ff0..0000000
--- a/cpp-package/inspireface/cpp/inspireface/information.h
+++ /dev/null
@@ -1,15 +0,0 @@
-/**
- * Created by Jingyu Yan
- * @date 2024-10-01
- */
-
-#ifndef INSPIRE_FACE_INFORMATION_H
-#define INSPIRE_FACE_INFORMATION_H
-
-#define INSPIRE_FACE_VERSION_MAJOR_STR "1"
-#define INSPIRE_FACE_VERSION_MINOR_STR "2"
-#define INSPIRE_FACE_VERSION_PATCH_STR "0"
-
-#define INSPIRE_FACE_EXTENDED_INFORMATION "InspireFace[Community Edition]@General - Build Time: 2025-03-25"
-
-#endif // INSPIRE_FACE_INFORMATION_H
diff --git a/cpp-package/inspireface/cpp/inspireface/isf_check.h b/cpp-package/inspireface/cpp/inspireface/isf_check.h
deleted file mode 100644
index f72633f..0000000
--- a/cpp-package/inspireface/cpp/inspireface/isf_check.h
+++ /dev/null
@@ -1,42 +0,0 @@
-#ifndef INSPIRE_FACE_CHECK_H
-#define INSPIRE_FACE_CHECK_H
-#include "log.h"
-#include "herror.h"
-
-#define INSPIREFACE_RETURN_IF_ERROR(...) \
- do { \
- const int32_t _status = (__VA_ARGS__); \
- if (_status != HSUCCEED) { \
- INSPIRE_LOGE("Error code: %d", _status); \
- return _status; \
- } \
- } while (0)
-
-
-#define INSPIREFACE_LOG_IF(severity, condition) \
- if (condition) \
- INSPIRE_LOG##severity
-
-
-#define INSPIREFACE_CHECK(condition) \
- do { \
- if (!(condition)) { \
- INSPIRE_LOGF("Check failed: (%s)", #condition); \
- } \
- } while (0)
-
-#define INSPIREFACE_CHECK_MSG(condition, message) \
- do { \
- if (!(condition)) { \
- INSPIRE_LOGF("Check failed: (%s) %s", #condition, message); \
- } \
- } while (0)
-
-#define INSPIREFACE_CHECK_EQ(a, b) INSPIREFACE_CHECK((a) == (b)) << "Expected equality of these values: " << #a << " vs " << #b
-#define INSPIREFACE_CHECK_NE(a, b) INSPIREFACE_CHECK((a) != (b)) << "Expected inequality of these values: " << #a << " vs " << #b
-#define INSPIREFACE_CHECK_LE(a, b) INSPIREFACE_CHECK((a) <= (b)) << "Expected " << #a << " <= " << #b
-#define INSPIREFAFECE_CHECK_LT(a, b) INSPIREFACE_CHECK((a) < (b)) << "Expected " << #a << " < " << #b
-#define INSPIREFAFECE_CHECK_GE(a, b) INSPIREFACE_CHECK((a) >= (b)) << "Expected " << #a << " >= " << #b
-#define INSPIREFAFECE_CHECK_GT(a, b) INSPIREFACE_CHECK((a) > (b)) << "Expected " << #a << " > " << #b
-
-#endif // INSPIRE_FACE_CHECK_H
diff --git a/cpp-package/inspireface/cpp/inspireface/log.cpp b/cpp-package/inspireface/cpp/inspireface/log.cpp
index d7c9f76..4dd0af1 100644
--- a/cpp-package/inspireface/cpp/inspireface/log.cpp
+++ b/cpp-package/inspireface/cpp/inspireface/log.cpp
@@ -3,11 +3,150 @@
* @date 2024-10-01
*/
#include "log.h"
+#include
+#include
+#include
+#include
+
+#ifdef ANDROID
+#include
+#endif
namespace inspire {
-// Static Logger initialization
+// Implementation class for LogManager
+class LogManager::Impl {
+public:
+ Impl() : currentLevel(LogLevel::ISF_LOG_INFO) {}
+
+ LogLevel currentLevel;
+ static std::mutex mutex;
+};
+
+// Static initialization
+std::mutex LogManager::Impl::mutex;
LogManager* LogManager::instance = nullptr;
-std::mutex LogManager::mutex;
+
+// Constructor
+LogManager::LogManager() : pImpl(std::make_unique()) {}
+
+// Destructor
+LogManager::~LogManager() = default;
+
+// Get singleton instance
+LogManager* LogManager::getInstance() {
+ std::lock_guard lock(Impl::mutex);
+ if (instance == nullptr) {
+ instance = new LogManager();
+ }
+ return instance;
+}
+
+// Set log level
+void LogManager::setLogLevel(LogLevel level) {
+ pImpl->currentLevel = level;
+}
+
+// Get log level
+LogLevel LogManager::getLogLevel() const {
+ return pImpl->currentLevel;
+}
+
+#ifdef ANDROID
+// Android logging implementation
+void LogManager::logAndroid(LogLevel level, const char* tag, const char* format, ...) const {
+ if (pImpl->currentLevel == LogLevel::ISF_LOG_NONE || level < pImpl->currentLevel)
+ return;
+
+ int androidLevel;
+ switch (level) {
+ case LogLevel::ISF_LOG_DEBUG:
+ androidLevel = ANDROID_LOG_DEBUG;
+ break;
+ case LogLevel::ISF_LOG_INFO:
+ androidLevel = ANDROID_LOG_INFO;
+ break;
+ case LogLevel::ISF_LOG_WARN:
+ androidLevel = ANDROID_LOG_WARN;
+ break;
+ case LogLevel::ISF_LOG_ERROR:
+ androidLevel = ANDROID_LOG_ERROR;
+ break;
+ case LogLevel::ISF_LOG_FATAL:
+ androidLevel = ANDROID_LOG_FATAL;
+ break;
+ default:
+ androidLevel = ANDROID_LOG_DEFAULT;
+ }
+
+ va_list args;
+ va_start(args, format);
+ __android_log_vprint(androidLevel, tag, format, args);
+ va_end(args);
+
+ // If the log level is fatal, flush the error stream and abort the program
+ if (level == LogLevel::ISF_LOG_FATAL) {
+ std::flush(std::cerr);
+ abort();
+ }
+}
+#else
+// Standard logging implementation
+void LogManager::logStandard(LogLevel level, const char* filename, const char* function, int line, const char* format, ...) const {
+ // Check whether the current level is LOG NONE or the log level is not enough to log
+ if (pImpl->currentLevel == LogLevel::ISF_LOG_NONE || level < pImpl->currentLevel)
+ return;
+
+ // Build log prefix dynamically based on available data
+ bool hasPrintedPrefix = false;
+ if (filename && strlen(filename) > 0) {
+ printf("[%s]", filename);
+ hasPrintedPrefix = true;
+ }
+ if (function && strlen(function) > 0) {
+ printf("[%s]", function);
+ hasPrintedPrefix = true;
+ }
+ if (line != -1) {
+ printf("[%d]", line);
+ hasPrintedPrefix = true;
+ }
+
+ // Only add colon and space if any prefix was printed
+ if (hasPrintedPrefix) {
+ printf(": ");
+ }
+
+ // Set text color for different log levels, but only if not on iOS
+#ifndef TARGET_OS_IOS
+ if (level == LogLevel::ISF_LOG_ERROR || level == LogLevel::ISF_LOG_FATAL) {
+ printf("\033[1;31m"); // Red color for errors and fatal issues
+ } else if (level == LogLevel::ISF_LOG_WARN) {
+ printf("\033[1;33m"); // Yellow color for warnings
+ }
+#endif
+
+ // Print the actual log message
+ va_list args;
+ va_start(args, format);
+ vprintf(format, args);
+ va_end(args);
+
+ // Reset text color if needed, but only if not on iOS
+#ifndef TARGET_OS_IOS
+ if (level == LogLevel::ISF_LOG_ERROR || level == LogLevel::ISF_LOG_WARN || level == LogLevel::ISF_LOG_FATAL) {
+ printf("\033[0m"); // Reset color
+ }
+#endif
+
+ printf("\n"); // New line after log message
+
+ // If the log level is fatal, flush the error stream and abort the program
+ if (level == LogLevel::ISF_LOG_FATAL) {
+ std::flush(std::cerr);
+ abort();
+ }
+}
+#endif
} // namespace inspire
\ No newline at end of file
diff --git a/cpp-package/inspireface/cpp/inspireface/log.h b/cpp-package/inspireface/cpp/inspireface/log.h
deleted file mode 100755
index 563e3c9..0000000
--- a/cpp-package/inspireface/cpp/inspireface/log.h
+++ /dev/null
@@ -1,184 +0,0 @@
-#ifndef INSPIRE_FACE_LOG_H
-#define INSPIRE_FACE_LOG_H
-
-#include
-#include
-#include
-#include
-#include
-
-#ifndef INSPIRE_API
-#define INSPIRE_API
-#endif
-
-// Macro to extract the filename from the full path
-#define __FILENAME__ (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__)
-
-#ifdef ANDROID
-// Android platform log macros
-#include
-#define INSPIRE_ANDROID_LOG_TAG "InspireFace"
-#define INSPIRE_LOGD(...) inspire::LogManager::getInstance()->logAndroid(inspire::ISF_LOG_DEBUG, INSPIRE_ANDROID_LOG_TAG, __VA_ARGS__)
-#define INSPIRE_LOGI(...) inspire::LogManager::getInstance()->logAndroid(inspire::ISF_LOG_INFO, INSPIRE_ANDROID_LOG_TAG, __VA_ARGS__)
-#define INSPIRE_LOGW(...) inspire::LogManager::getInstance()->logAndroid(inspire::ISF_LOG_WARN, INSPIRE_ANDROID_LOG_TAG, __VA_ARGS__)
-#define INSPIRE_LOGE(...) inspire::LogManager::getInstance()->logAndroid(inspire::ISF_LOG_ERROR, INSPIRE_ANDROID_LOG_TAG, __VA_ARGS__)
-#define INSPIRE_LOGF(...) inspire::LogManager::getInstance()->logAndroid(inspire::ISF_LOG_FATAL, INSPIRE_ANDROID_LOG_TAG, __VA_ARGS__)
-#else
-// Standard platform log macros
-#define INSPIRE_LOGD(...) inspire::LogManager::getInstance()->logStandard(inspire::ISF_LOG_DEBUG, __FILENAME__, __FUNCTION__, __LINE__, __VA_ARGS__)
-#define INSPIRE_LOGI(...) inspire::LogManager::getInstance()->logStandard(inspire::ISF_LOG_INFO, "", "", -1, __VA_ARGS__)
-#define INSPIRE_LOGW(...) inspire::LogManager::getInstance()->logStandard(inspire::ISF_LOG_WARN, "", "", -1, __VA_ARGS__)
-#define INSPIRE_LOGE(...) inspire::LogManager::getInstance()->logStandard(inspire::ISF_LOG_ERROR, "", "", -1, __VA_ARGS__)
-#define INSPIRE_LOGF(...) inspire::LogManager::getInstance()->logStandard(inspire::ISF_LOG_FATAL, "", "", -1, __VA_ARGS__)
-#endif
-
-// Macro to set the global log level
-#define INSPIRE_SET_LOG_LEVEL(level) inspire::LogManager::getInstance()->setLogLevel(level)
-
-namespace inspire {
-
-// Log levels
-enum LogLevel { ISF_LOG_NONE = 0, ISF_LOG_DEBUG, ISF_LOG_INFO, ISF_LOG_WARN, ISF_LOG_ERROR, ISF_LOG_FATAL };
-
-/**
- * @class LogManager
- * @brief A singleton class for logging messages to the console or Android logcat.
- *
- * This class provides methods to log messages of different severity levels (DEBUG, INFO, WARN, ERROR, FATAL)
- * to the console or Android logcat based on the current log level setting.
- */
-class INSPIRE_API LogManager {
-private:
- LogLevel currentLevel;
- static LogManager* instance;
- static std::mutex mutex;
-
- // Private constructor
- LogManager() : currentLevel(ISF_LOG_INFO) {} // Default log level is INFO
-
-public:
- // Disable copy construction and assignment
- LogManager(const LogManager&) = delete;
- LogManager& operator=(const LogManager&) = delete;
-
- // Get the singleton instance
- static LogManager* getInstance() {
- std::lock_guard lock(mutex);
- if (instance == nullptr) {
- instance = new LogManager();
- }
- return instance;
- }
-
- // Set the log level
- void setLogLevel(LogLevel level) {
- currentLevel = level;
- }
-
- // Get the current log level
- LogLevel getLogLevel() const {
- return currentLevel;
- }
-
-#ifdef ANDROID
- // Method for logging on the Android platform
- void logAndroid(LogLevel level, const char* tag, const char* format, ...) const {
- if (currentLevel == ISF_LOG_NONE || level < currentLevel)
- return;
-
- int androidLevel;
- switch (level) {
- case ISF_LOG_DEBUG:
- androidLevel = ANDROID_LOG_DEBUG;
- break;
- case ISF_LOG_INFO:
- androidLevel = ANDROID_LOG_INFO;
- break;
- case ISF_LOG_WARN:
- androidLevel = ANDROID_LOG_WARN;
- break;
- case ISF_LOG_ERROR:
- androidLevel = ANDROID_LOG_ERROR;
- break;
- case ISF_LOG_FATAL:
- androidLevel = ANDROID_LOG_FATAL;
- break;
- default:
- androidLevel = ANDROID_LOG_DEFAULT;
- }
-
- va_list args;
- va_start(args, format);
- __android_log_vprint(androidLevel, tag, format, args);
- va_end(args);
-
- // If the log level is fatal, flush the error stream and abort the program
- if (level == ISF_LOG_FATAL) {
- std::flush(std::cerr);
- abort();
- }
- }
-#else
- // Method for standard platform logging
- void logStandard(LogLevel level, const char* filename, const char* function, int line, const char* format, ...) const {
- // Check whether the current level is LOG NONE or the log level is not enough to log
- if (currentLevel == ISF_LOG_NONE || level < currentLevel)
- return;
-
- // Build log prefix dynamically based on available data
- bool hasPrintedPrefix = false;
- if (filename && strlen(filename) > 0) {
- printf("[%s]", filename);
- hasPrintedPrefix = true;
- }
- if (function && strlen(function) > 0) {
- printf("[%s]", function);
- hasPrintedPrefix = true;
- }
- if (line != -1) {
- printf("[%d]", line);
- hasPrintedPrefix = true;
- }
-
- // Only add colon and space if any prefix was printed
- if (hasPrintedPrefix) {
- printf(": ");
- }
-
- // Set text color for different log levels, but only if not on iOS
-#ifndef TARGET_OS_IOS
- if (level == ISF_LOG_ERROR || level == ISF_LOG_FATAL) {
- printf("\033[1;31m"); // Red color for errors and fatal issues
- } else if (level == ISF_LOG_WARN) {
- printf("\033[1;33m"); // Yellow color for warnings
- }
-#endif
-
- // Print the actual log message
- va_list args;
- va_start(args, format);
- vprintf(format, args);
- va_end(args);
-
- // Reset text color if needed, but only if not on iOS
-#ifndef TARGET_OS_IOS
- if (level == ISF_LOG_ERROR || level == ISF_LOG_WARN || level == ISF_LOG_FATAL) {
- printf("\033[0m"); // Reset color
- }
-#endif
-
- printf("\n"); // New line after log message
-
- // If the log level is fatal, flush the error stream and abort the program
- if (level == ISF_LOG_FATAL) {
- std::flush(std::cerr);
- abort();
- }
- }
-
-#endif
-};
-
-} // namespace inspire
-
-#endif // INSPIRE_FACE_LOG_H
\ No newline at end of file
diff --git a/cpp-package/inspireface/cpp/inspireface/middleware/any_net_adapter.h b/cpp-package/inspireface/cpp/inspireface/middleware/any_net_adapter.h
index 43b06e5..8824d51 100644
--- a/cpp-package/inspireface/cpp/inspireface/middleware/any_net_adapter.h
+++ b/cpp-package/inspireface/cpp/inspireface/middleware/any_net_adapter.h
@@ -13,8 +13,8 @@
#include "configurable.h"
#include "log.h"
#include "model_archive/inspire_archive.h"
-#include "nexus_processor/image_processor.h"
-#include "initialization_module/launch.h"
+#include "image_process/nexus_processor/image_processor.h"
+#include
#include "system.h"
namespace inspire {
@@ -51,7 +51,7 @@ public:
* @param type Type of the inference helper (default: INFER_MNN).
* @return int32_t Status of the loading and initialization process.
*/
- int32_t loadData(InspireModel &model, InferenceWrapper::EngineType type = InferenceWrapper::INFER_MNN, bool dynamic = false) {
+ int32_t LoadData(InspireModel &model, InferenceWrapper::EngineType type = InferenceWrapper::INFER_MNN, bool dynamic = false) {
m_infer_type_ = type;
// must
pushData(model.Config(), "model_index", 0);
@@ -78,7 +78,7 @@ public:
m_nn_inference_->SetNumThreads(getData("threads"));
if (m_infer_type_ == InferenceWrapper::INFER_TENSORRT) {
- m_nn_inference_->SetDevice(INSPIRE_LAUNCH->GetCudaDeviceId());
+ m_nn_inference_->SetDevice(INSPIREFACE_CONTEXT->GetCudaDeviceId());
}
#if defined(ISF_GLOBAL_INFERENCE_BACKEND_USE_MNN_CUDA) && !defined(ISF_ENABLE_RKNN)
@@ -87,7 +87,13 @@ public:
#endif
#if defined(ISF_ENABLE_APPLE_EXTENSION)
- m_nn_inference_->SetSpecialBackend(INSPIRE_LAUNCH->GetGlobalCoreMLInferenceMode());
+ if (INSPIREFACE_CONTEXT->GetGlobalCoreMLInferenceMode() == InferenceWrapper::COREML_CPU) {
+ m_nn_inference_->SetSpecialBackend(InferenceWrapper::COREML_CPU);
+ } else if (INSPIREFACE_CONTEXT->GetGlobalCoreMLInferenceMode() == InferenceWrapper::COREML_GPU) {
+ m_nn_inference_->SetSpecialBackend(InferenceWrapper::COREML_GPU);
+ } else if (INSPIREFACE_CONTEXT->GetGlobalCoreMLInferenceMode() == InferenceWrapper::COREML_ANE) {
+ m_nn_inference_->SetSpecialBackend(InferenceWrapper::COREML_ANE);
+ }
#endif
m_output_tensor_info_list_.clear();
@@ -99,7 +105,7 @@ public:
}
int32_t ret;
if (model.loadFilePath) {
- auto extensionPath = INSPIRE_LAUNCH->GetExtensionPath();
+ auto extensionPath = INSPIREFACE_CONTEXT->GetExtensionPath();
if (extensionPath.empty()) {
INSPIRE_LOGE("Extension path is empty");
return InferenceWrapper::WrapperError;
diff --git a/cpp-package/inspireface/cpp/inspireface/middleware/cuda_toolkit.h b/cpp-package/inspireface/cpp/inspireface/middleware/cuda_toolkit.cpp
similarity index 84%
rename from cpp-package/inspireface/cpp/inspireface/middleware/cuda_toolkit.h
rename to cpp-package/inspireface/cpp/inspireface/middleware/cuda_toolkit.cpp
index 40a7a99..413fe15 100644
--- a/cpp-package/inspireface/cpp/inspireface/middleware/cuda_toolkit.h
+++ b/cpp-package/inspireface/cpp/inspireface/middleware/cuda_toolkit.cpp
@@ -1,23 +1,29 @@
#ifdef ISF_ENABLE_TENSORRT
-#ifndef INSPIRE_CUDA_TOOLKIT_H
-#define INSPIRE_CUDA_TOOLKIT_H
+#include
#include
#include
+#endif // ISF_ENABLE_TENSORRT
#include
-#include "herror.h"
+#include
namespace inspire {
-inline static int32_t GetCudaDeviceCount(int32_t *device_count) {
+int32_t INSPIRE_API_EXPORT GetCudaDeviceCount(int32_t *device_count) {
+#ifdef ISF_ENABLE_TENSORRT
cudaError_t error = cudaGetDeviceCount(device_count);
if (error != cudaSuccess) {
INSPIRE_LOGE("CUDA error: %s", cudaGetErrorString(error));
return HERR_DEVICE_CUDA_UNKNOWN_ERROR;
}
return HSUCCEED;
+#else
+ *device_count = 0;
+ return HERR_DEVICE_CUDA_NOT_SUPPORT;
+#endif
}
-inline static int32_t CheckCudaUsability(int32_t *is_support) {
+int32_t INSPIRE_API_EXPORT CheckCudaUsability(int32_t *is_support) {
+#ifdef ISF_ENABLE_TENSORRT
int device_count;
auto ret = GetCudaDeviceCount(&device_count);
if (ret != HSUCCEED) {
@@ -30,9 +36,14 @@ inline static int32_t CheckCudaUsability(int32_t *is_support) {
}
*is_support = device_count > 0;
return HSUCCEED;
+#else
+ *is_support = 0;
+ return HERR_DEVICE_CUDA_NOT_SUPPORT;
+#endif
}
-inline static int32_t _PrintCudaDeviceInfo() {
+int32_t INSPIRE_API_EXPORT _PrintCudaDeviceInfo() {
+#ifdef ISF_ENABLE_TENSORRT
try {
INSPIRE_LOGW("TensorRT version: %d.%d.%d", NV_TENSORRT_MAJOR, NV_TENSORRT_MINOR, NV_TENSORRT_PATCH);
@@ -98,16 +109,22 @@ inline static int32_t _PrintCudaDeviceInfo() {
INSPIRE_LOGE("error when printing CUDA device info: %s", e.what());
return HERR_DEVICE_CUDA_UNKNOWN_ERROR;
}
+#else
+ INSPIRE_LOGE("CUDA/TensorRT support is not enabled");
+ return HERR_DEVICE_CUDA_NOT_SUPPORT;
+#endif
}
-inline static int32_t PrintCudaDeviceInfo() {
+int32_t INSPIRE_API_EXPORT PrintCudaDeviceInfo() {
+#ifdef ISF_ENABLE_TENSORRT
INSPIRE_LOGW("================================================");
auto ret = _PrintCudaDeviceInfo();
INSPIRE_LOGW("================================================");
return ret;
+#else
+ INSPIRE_LOGE("CUDA/TensorRT support is not enabled");
+ return HERR_DEVICE_CUDA_NOT_SUPPORT;
+#endif
}
-} // namespace inspire
-
-#endif // INSPIRE_CUDA_TOOLKIT_H
-#endif // ISF_ENABLE_TENSORRT
+} // namespace inspire
\ No newline at end of file
diff --git a/cpp-package/inspireface/cpp/inspireface/middleware/inference_wrapper/inference_wrapper.h b/cpp-package/inspireface/cpp/inspireface/middleware/inference_wrapper/inference_wrapper.h
index 648eb62..3196243 100644
--- a/cpp-package/inspireface/cpp/inspireface/middleware/inference_wrapper/inference_wrapper.h
+++ b/cpp-package/inspireface/cpp/inspireface/middleware/inference_wrapper/inference_wrapper.h
@@ -223,6 +223,12 @@ public:
virtual int32_t Process(std::vector& output_tensor_info_list) = 0;
virtual int32_t ParameterInitialization(std::vector& input_tensor_info_list,
std::vector& output_tensor_info_list) = 0;
+
+#ifdef BATCH_FORWARD_IMPLEMENTED
+ virtual int32_t PreProcessBatch(const std::vector>& input_tensor_info_list) = 0;
+ virtual int32_t ProcessBatch(std::vector>& output_tensor_info_list) = 0;
+ virtual int32_t PostProcessBatch(std::vector>& output_tensor_info_list) = 0;
+#endif
virtual int32_t SetSpecialBackend(SpecialBackend backend) {
special_backend_ = backend;
diff --git a/cpp-package/inspireface/cpp/inspireface/middleware/inference_wrapper/inference_wrapper_tensorrt.cpp b/cpp-package/inspireface/cpp/inspireface/middleware/inference_wrapper/inference_wrapper_tensorrt.cpp
index 6cab4f4..ebedd23 100644
--- a/cpp-package/inspireface/cpp/inspireface/middleware/inference_wrapper/inference_wrapper_tensorrt.cpp
+++ b/cpp-package/inspireface/cpp/inspireface/middleware/inference_wrapper/inference_wrapper_tensorrt.cpp
@@ -1,4 +1,5 @@
#if INFERENCE_WRAPPER_ENABLE_TENSORRT
+#include
#include
#include
#include
@@ -40,7 +41,6 @@ int32_t InferenceWrapperTensorRT::Initialize(char* model_buffer, int model_size,
net_->setDevice(device_id_);
auto ret = net_->readFromBin(model_buffer, model_size);
if (ret != WrapperOk) {
- std::cout << "model_size: " << model_size << std::endl;
PRINT_E("Failed to load TensorRT model\n");
return WrapperError;
}
diff --git a/cpp-package/inspireface/cpp/inspireface/middleware/inspirecv_image_process.h b/cpp-package/inspireface/cpp/inspireface/middleware/inspirecv_image_process.h
deleted file mode 100644
index d796b70..0000000
--- a/cpp-package/inspireface/cpp/inspireface/middleware/inspirecv_image_process.h
+++ /dev/null
@@ -1,392 +0,0 @@
-#ifndef INSPIRECV_IMAGE_PROCESS_H
-#define INSPIRECV_IMAGE_PROCESS_H
-
-#include
-#include
-#include
-#include "isf_check.h"
-
-// using namespace inspire;
-namespace inspirecv {
-
-/**
- * @brief Enum to represent rotation modes.
- */
-enum ROTATION_MODE { ROTATION_0 = 0, ROTATION_90 = 1, ROTATION_180 = 2, ROTATION_270 = 3 };
-
-/**
- * @brief Enum to represent data formats.
- */
-enum DATA_FORMAT { NV21 = 0, NV12 = 1, RGBA = 2, RGB = 3, BGR = 4, BGRA = 5 };
-
-/**
- * @brief A class to handle camera stream and image processing.
- */
-class InspireImageProcess {
-public:
- static InspireImageProcess Create(const uint8_t *data_buffer, int height, int width, DATA_FORMAT data_format = BGR,
- ROTATION_MODE rotation_mode = ROTATION_0) {
- InspireImageProcess process;
- process.SetDataBuffer(data_buffer, height, width);
- process.SetDataFormat(data_format);
- process.SetRotationMode(rotation_mode);
- return process;
- }
-
- InspireImageProcess() {
- SetDataFormat(NV21);
- SetDestFormat(BGR);
- config_.filterType = MNN::CV::BILINEAR;
- config_.wrap = MNN::CV::ZERO;
- rotation_mode_ = ROTATION_0;
- preview_size_ = 192;
- UpdateTransformMatrix();
- }
-
- /**
- * @brief Set the data buffer, height, and width of the camera stream.
- *
- * @param data_buffer Pointer to the data buffer.
- * @param height Height of the image.
- * @param width Width of the image.
- */
- void SetDataBuffer(const uint8_t *data_buffer, int height, int width) {
- this->buffer_ = data_buffer;
- this->height_ = height;
- this->width_ = width;
- preview_scale_ = preview_size_ / static_cast(std::max(height, width));
- UpdateTransformMatrix();
- }
-
- /**
- * @brief Set the preview size.
- *
- * @param size Preview size.
- */
- void SetPreviewSize(const int size) {
- preview_size_ = size;
- preview_scale_ = preview_size_ / static_cast(std::max(this->height_, this->width_));
- UpdateTransformMatrix();
- }
-
- void SetPreviewScale(const float scale) {
- preview_scale_ = scale;
- preview_size_ = static_cast(preview_scale_ * std::max(this->height_, this->width_));
- UpdateTransformMatrix();
- }
-
- /**
- * @brief Set the rotation mode.
- *
- * @param mode Rotation mode (e.g., ROTATION_0, ROTATION_90).
- */
- void SetRotationMode(ROTATION_MODE mode) {
- rotation_mode_ = mode;
- UpdateTransformMatrix();
- }
-
- /**
- * @brief Set the data format.
- *
- * @param data_format Data format (e.g., NV21, RGBA).
- */
- void SetDataFormat(DATA_FORMAT data_format) {
- if (data_format == NV21) {
- config_.sourceFormat = MNN::CV::YUV_NV21;
- }
- if (data_format == NV12) {
- config_.sourceFormat = MNN::CV::YUV_NV12;
- }
- if (data_format == RGBA) {
- config_.sourceFormat = MNN::CV::RGBA;
- }
- if (data_format == RGB) {
- config_.sourceFormat = MNN::CV::RGB;
- }
- if (data_format == BGR) {
- config_.sourceFormat = MNN::CV::BGR;
- }
- if (data_format == BGRA) {
- config_.sourceFormat = MNN::CV::BGRA;
- }
- }
-
- /**
- * @brief Set the destination format.
- *
- * @param data_format Data format (e.g., NV21, RGBA).
- */
- void SetDestFormat(DATA_FORMAT data_format) {
- if (data_format == NV21) {
- config_.destFormat = MNN::CV::YUV_NV21;
- }
- if (data_format == NV12) {
- config_.destFormat = MNN::CV::YUV_NV12;
- }
- if (data_format == RGBA) {
- config_.destFormat = MNN::CV::RGBA;
- }
- if (data_format == RGB) {
- config_.destFormat = MNN::CV::RGB;
- }
- if (data_format == BGR) {
- config_.destFormat = MNN::CV::BGR;
- }
- if (data_format == BGRA) {
- config_.destFormat = MNN::CV::BGRA;
- }
- }
-
- /**
- * @brief Get an affine-transformed image.
- *
- * @param affine_matrix Affine transformation matrix.
- * @param width_out Width of the output image.
- * @param height_out Height of the output image.
- * @return cv::Mat Affine-transformed image.
- */
- inspirecv::Image ExecuteImageAffineProcessing(inspirecv::TransformMatrix &affine_matrix, const int width_out, const int height_out) const {
- int sw = width_;
- int sh = height_;
- int rot_sw = sw;
- int rot_sh = sh;
- MNN::CV::Matrix tr;
- std::vector tr_cv({1, 0, 0, 0, 1, 0, 0, 0, 1});
- memcpy(tr_cv.data(), affine_matrix.Squeeze().data(), sizeof(float) * 6);
- tr.set9(tr_cv.data());
- MNN::CV::Matrix tr_inv;
- tr.invert(&tr_inv);
- std::shared_ptr process(MNN::CV::ImageProcess::create(config_));
- process->setMatrix(tr_inv);
- auto img_out = inspirecv::Image::Create(width_out, height_out, 3);
- std::shared_ptr tensor(MNN::Tensor::create(std::vector{1, height_out, width_out, 3}, (uint8_t *)img_out.Data()));
- auto ret = process->convert(buffer_, sw, sh, 0, tensor.get());
- INSPIREFACE_CHECK_MSG(ret == MNN::ErrorCode::NO_ERROR, "ImageProcess::convert failed");
- return img_out;
- }
-
- /**
- * @brief Get a preview image with optional rotation.
- *
- * @param with_rotation True if rotation is applied, false otherwise.
- * @return cv::Mat Preview image.
- */
- inspirecv::Image ExecutePreviewImageProcessing(bool with_rotation) {
- return ExecuteImageScaleProcessing(preview_scale_, with_rotation);
- }
-
- /**
- * @brief Get the preview scale.
- *
- * @return float Preview scale.
- */
- float GetPreviewScale() {
- return preview_scale_;
- }
-
- /**
- * @brief Execute image scale processing.
- *
- * @param scale Scale factor.
- * @param with_rotation True if rotation is applied, false otherwise.
- * @return inspirecv::Image Scaled image.
- */
- inspirecv::Image ExecuteImageScaleProcessing(const float scale, bool with_rotation) {
- int sw = width_;
- int sh = height_;
- int rot_sw = sw;
- int rot_sh = sh;
- // MNN::CV::Matrix tr;
- std::shared_ptr process(MNN::CV::ImageProcess::create(config_));
- if (rotation_mode_ == ROTATION_270 && with_rotation) {
- float srcPoints[] = {
- 0.0f, 0.0f, 0.0f, (float)(height_ - 1), (float)(width_ - 1), 0.0f, (float)(width_ - 1), (float)(height_ - 1),
- };
- float dstPoints[] = {(float)(height_ * scale - 1), 0.0f, 0.0f, 0.0f, (float)(height_ * scale - 1), (float)(width_ * scale - 1), 0.0f,
- (float)(width_ * scale - 1)};
-
- tr_.setPolyToPoly((MNN::CV::Point *)dstPoints, (MNN::CV::Point *)srcPoints, 4);
- process->setMatrix(tr_);
- int scaled_height = static_cast(width_ * scale);
- int scaled_width = static_cast(height_ * scale);
- inspirecv::Image img_out(scaled_width, scaled_height, 3);
- std::shared_ptr tensor(
- MNN::Tensor::create(std::vector{1, scaled_height, scaled_width, 3}, (uint8_t *)img_out.Data()));
- auto ret = process->convert(buffer_, sw, sh, 0, tensor.get());
- INSPIREFACE_CHECK_MSG(ret == MNN::ErrorCode::NO_ERROR, "ImageProcess::convert failed");
- return img_out;
- } else if (rotation_mode_ == ROTATION_90 && with_rotation) {
- float srcPoints[] = {
- 0.0f, 0.0f, 0.0f, (float)(height_ - 1), (float)(width_ - 1), 0.0f, (float)(width_ - 1), (float)(height_ - 1),
- };
- float dstPoints[] = {
- 0.0f, (float)(width_ * scale - 1), (float)(height_ * scale - 1), (float)(width_ * scale - 1), 0.0f, 0.0f, (float)(height_ * scale - 1),
- 0.0f,
- };
- tr_.setPolyToPoly((MNN::CV::Point *)dstPoints, (MNN::CV::Point *)srcPoints, 4);
- process->setMatrix(tr_);
- int scaled_height = static_cast(width_ * scale);
- int scaled_width = static_cast(height_ * scale);
- inspirecv::Image img_out(scaled_width, scaled_height, 3);
- std::shared_ptr tensor(
- MNN::Tensor::create(std::vector{1, scaled_height, scaled_width, 3}, (uint8_t *)img_out.Data()));
- auto ret = process->convert(buffer_, sw, sh, 0, tensor.get());
- INSPIREFACE_CHECK_MSG(ret == MNN::ErrorCode::NO_ERROR, "ImageProcess::convert failed");
- return img_out;
- } else if (rotation_mode_ == ROTATION_180 && with_rotation) {
- float srcPoints[] = {
- 0.0f, 0.0f, 0.0f, (float)(height_ - 1), (float)(width_ - 1), 0.0f, (float)(width_ - 1), (float)(height_ - 1),
- };
- float dstPoints[] = {
- (float)(width_ * scale - 1),
- (float)(height_ * scale - 1),
- (float)(width_ * scale - 1),
- 0.0f,
- 0.0f,
- (float)(height_ * scale - 1),
- 0.0f,
- 0.0f,
- };
- tr_.setPolyToPoly((MNN::CV::Point *)dstPoints, (MNN::CV::Point *)srcPoints, 4);
- process->setMatrix(tr_);
- int scaled_height = static_cast(height_ * scale);
- int scaled_width = static_cast(width_ * scale);
- inspirecv::Image img_out(scaled_width, scaled_height, 3);
- std::shared_ptr tensor(
- MNN::Tensor::create(std::vector