mirror of
https://github.com/deepinsight/insightface.git
synced 2026-07-19 12:31:07 +00:00
Update
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
cmake_minimum_required(VERSION 3.10)
|
||||
cmake_minimum_required(VERSION 3.20)
|
||||
project(InspireFaceTest)
|
||||
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3")
|
||||
@@ -8,6 +8,8 @@ option(ISF_ENABLE_BENCHMARK "Enable the benchmark test cases." ON)
|
||||
option(ISF_ENABLE_USE_LFW_DATA "Enable test cases for LFW data sets." OFF)
|
||||
# If you want to test the evaluation function, you need to set this to ON, need LFW data set.
|
||||
option(ISF_ENABLE_TEST_EVALUATION "Enable evaluation function test cases." OFF)
|
||||
# If you want to test the base test cases, you need to set this to ON, if you want to hide the symbols, you need to set ISF_ENABLE_SYMBOL_HIDING to ON
|
||||
option(ISF_ENABLE_TEST_INTERNAL "Enable internal test cases." OFF)
|
||||
|
||||
if (ISF_ENABLE_BENCHMARK)
|
||||
add_definitions("-DISF_ENABLE_BENCHMARK")
|
||||
@@ -51,27 +53,26 @@ set(TEST_COMMON_FILES ${CMAKE_CURRENT_SOURCE_DIR}/settings/test_settings.cpp)
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/settings)
|
||||
|
||||
# =======================Internal Base Import Tests===========================
|
||||
file(GLOB_RECURSE INTERNAL_TEST_INTERNAL_FILES unit/base/*.cpp)
|
||||
add_executable(TestBase ${CMAKE_CURRENT_SOURCE_DIR}/test_base.cpp ${INTERNAL_TEST_INTERNAL_FILES} ${TEST_COMMON_FILES})
|
||||
target_link_libraries(TestBase InspireFace ${DEPEND})
|
||||
target_include_directories(TestBase PUBLIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/
|
||||
${ISF_THIRD_PARTY_DIR}/spdlog/include
|
||||
${ISF_THIRD_PARTY_DIR}/Catch2/single_include/
|
||||
${ISF_THIRD_PARTY_DIR}/indicators/include/
|
||||
${SRC_DIR}
|
||||
${INSPIRECV_INCLUDE_PATH}
|
||||
)
|
||||
|
||||
set_target_properties(TestBase PROPERTIES
|
||||
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/test/")
|
||||
|
||||
if (ISF_ENABLE_TEST_INTERNAL)
|
||||
file(GLOB_RECURSE INTERNAL_TEST_INTERNAL_FILES unit/base/*.cpp)
|
||||
add_executable(TestInternal ${CMAKE_CURRENT_SOURCE_DIR}/test_base.cpp ${INTERNAL_TEST_INTERNAL_FILES} ${TEST_COMMON_FILES})
|
||||
target_link_libraries(TestInternal InspireFace ${DEPEND})
|
||||
target_include_directories(TestInternal PUBLIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/
|
||||
${ISF_THIRD_PARTY_DIR}/spdlog/include
|
||||
${ISF_THIRD_PARTY_DIR}/Catch2/single_include/
|
||||
${ISF_THIRD_PARTY_DIR}/indicators/include/
|
||||
${SRC_DIR}
|
||||
${INSPIRECV_INCLUDE_PATH}
|
||||
)
|
||||
|
||||
set_target_properties(TestInternal PROPERTIES
|
||||
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/test/")
|
||||
endif()
|
||||
|
||||
# =======================External API Testing===========================
|
||||
file(GLOB_RECURSE TEST_INTERNAL_FILES unit/api/*.cpp)
|
||||
add_executable(Test ${CMAKE_CURRENT_SOURCE_DIR}/test.cpp ${TEST_INTERNAL_FILES} ${TEST_COMMON_FILES}
|
||||
unit/api/test_evaluation.cpp)
|
||||
add_executable(Test ${CMAKE_CURRENT_SOURCE_DIR}/test.cpp ${TEST_INTERNAL_FILES} ${TEST_COMMON_FILES})
|
||||
target_link_libraries(Test InspireFace ${DEPEND})
|
||||
target_include_directories(Test PUBLIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/
|
||||
@@ -84,6 +85,20 @@ target_include_directories(Test PUBLIC
|
||||
set_target_properties(Test PROPERTIES
|
||||
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/test/")
|
||||
|
||||
# =======================CPP API Testing===========================
|
||||
file(GLOB_RECURSE TEST_CPP_FILES unit/cpp_api/*.cpp)
|
||||
add_executable(TestCPP ${CMAKE_CURRENT_SOURCE_DIR}/test_cpp.cpp ${TEST_CPP_FILES} ${TEST_COMMON_FILES})
|
||||
target_link_libraries(TestCPP InspireFace ${DEPEND})
|
||||
target_include_directories(TestCPP PUBLIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/
|
||||
${ISF_THIRD_PARTY_DIR}/spdlog/include
|
||||
${ISF_THIRD_PARTY_DIR}/Catch2/single_include/
|
||||
${ISF_THIRD_PARTY_DIR}/indicators/include/
|
||||
${SRC_DIR}
|
||||
)
|
||||
|
||||
set_target_properties(TestCPP PROPERTIES
|
||||
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/test/")
|
||||
|
||||
# Print Message
|
||||
message(STATUS ">>>>>>>>>>>>>")
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include "enviro.h"
|
||||
#include "check.h"
|
||||
#include "inspireface/middleware/system.h"
|
||||
#include "inspireface/include/inspireface/spend_timer.h"
|
||||
|
||||
// Define the test model file
|
||||
#define TEST_MODEL_FILE Enviro::getInstance().getPackName()
|
||||
|
||||
@@ -118,7 +118,7 @@ int main(int argc, char* argv[]) {
|
||||
TEST_ERROR_PRINT("An error occurred while starting InspireFace: {}", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
// Set log level
|
||||
HFSetLogLevel(HF_LOG_INFO);
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#include "settings/test_settings.h"
|
||||
#include <spdlog/sinks/stdout_color_sinks.h>
|
||||
#include "spdlog/spdlog.h"
|
||||
#include "initialization_module/launch.h"
|
||||
#include <inspireface/include/inspireface/launch.h>
|
||||
|
||||
#define ENABLE_DRAW_SPLIT_LINE 1 // Whether dividers are printed during the test
|
||||
#define ENABLE_TEST_MSG 1 // TEST PRINT output
|
||||
@@ -30,7 +30,7 @@ int init_test_logger() {
|
||||
int main(int argc, char* argv[]) {
|
||||
init_test_logger();
|
||||
|
||||
auto ret = INSPIRE_LAUNCH->Load("test_res/pack/Pikachu");
|
||||
auto ret = INSPIREFACE_CONTEXT->Load("test_res/pack/Pikachu");
|
||||
if (ret != 0) {
|
||||
std::cerr << "Load error" << std::endl;
|
||||
return -1;
|
||||
|
||||
138
cpp-package/inspireface/cpp/test/test_cpp.cpp
Normal file
138
cpp-package/inspireface/cpp/test/test_cpp.cpp
Normal file
@@ -0,0 +1,138 @@
|
||||
/**
|
||||
* Created by Jingyu Yan
|
||||
* @date 2024-10-01
|
||||
*/
|
||||
#include <string>
|
||||
#define CATCH_CONFIG_RUNNER
|
||||
|
||||
#include <iostream>
|
||||
#include "settings/test_settings.h"
|
||||
#include <spdlog/sinks/stdout_color_sinks.h>
|
||||
#include "spdlog/spdlog.h"
|
||||
#include <inspireface/include/inspireface/inspireface.hpp>
|
||||
#include "unit/test_helper/simple_csv_writer.h"
|
||||
|
||||
int init_test_logger() {
|
||||
std::string name("TEST");
|
||||
auto stdout_sink = std::make_shared<spdlog::sinks::stdout_color_sink_mt>();
|
||||
auto logger = std::make_shared<spdlog::logger>(name, stdout_sink);
|
||||
#if ENABLE_TEST_MSG
|
||||
logger->set_level(spdlog::level::trace);
|
||||
#else
|
||||
logger->set_level(spdlog::level::off);
|
||||
#endif
|
||||
logger->set_pattern("%Y-%m-%d %H:%M:%S.%e [Test Message] ===> %v");
|
||||
spdlog::register_logger(logger);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int init_test_benchmark_record() {
|
||||
#ifdef ISF_ENABLE_BENCHMARK
|
||||
if (std::remove(getBenchmarkRecordFile().c_str()) != 0) {
|
||||
spdlog::trace("Error deleting file");
|
||||
}
|
||||
BenchmarkRecord record(getBenchmarkRecordFile(), TEST_MODEL_FILE);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
int init_test_evaluation_record() {
|
||||
#ifdef ISF_ENABLE_TEST_EVALUATION
|
||||
if (std::remove(getEvaluationRecordFile().c_str()) != 0) {
|
||||
spdlog::trace("Error deleting file");
|
||||
}
|
||||
EvaluationRecord record(getEvaluationRecordFile());
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
init_test_logger();
|
||||
init_test_benchmark_record();
|
||||
init_test_evaluation_record();
|
||||
TEST_PRINT_OUTPUT(true);
|
||||
|
||||
TEST_PRINT("InspireFace Version: v{}.{}.{}",
|
||||
INSPIRE_FACE_VERSION_MAJOR_STR,
|
||||
INSPIRE_FACE_VERSION_MINOR_STR,
|
||||
INSPIRE_FACE_VERSION_PATCH_STR);
|
||||
TEST_PRINT("Extended Information: {}", INSPIRE_FACE_EXTENDED_INFORMATION);
|
||||
|
||||
Catch::Session session;
|
||||
// Pack file name and test directory
|
||||
std::string pack;
|
||||
std::string testDir;
|
||||
std::string packPath;
|
||||
|
||||
int32_t ret;
|
||||
|
||||
// Add command line options
|
||||
auto cli = session.cli() | Catch::clara::Opt(pack, "value")["--pack"]("Resource pack filename") |
|
||||
Catch::clara::Opt(testDir, "value")["--test_dir"]("Test dir resource") |
|
||||
Catch::clara::Opt(packPath, "value")["--pack_path"]("The specified path to the pack file");
|
||||
|
||||
// Set combined CLI to the session
|
||||
session.cli(cli);
|
||||
|
||||
// Parse command line arguments
|
||||
int returnCode = session.applyCommandLine(argc, argv);
|
||||
if (returnCode != 0) // Indicate an error
|
||||
return returnCode;
|
||||
|
||||
if (!testDir.empty()) {
|
||||
SET_TEST_DIR(testDir);
|
||||
TEST_PRINT("Updated test dir to: {}", getTestDataDir());
|
||||
} else {
|
||||
TEST_PRINT("Using default test dir: {}", getTestDataDir());
|
||||
}
|
||||
|
||||
#if defined(ISF_ENABLE_TENSORRT)
|
||||
int32_t cuda_device_count;
|
||||
ret = inspire::GetCudaDeviceCount(&cuda_device_count);
|
||||
if (ret != InspireFace::HSUCCEED) {
|
||||
TEST_ERROR_PRINT("An error occurred while checking CUDA device support: {}", ret);
|
||||
return ret;
|
||||
}
|
||||
if (cuda_device_count == 0) {
|
||||
TEST_ERROR_PRINT("CUDA device support is not available");
|
||||
return HERR_DEVICE_CUDA_NOT_SUPPORT;
|
||||
}
|
||||
|
||||
inspire::PrintCudaDeviceInfo();
|
||||
#endif
|
||||
|
||||
std::string fullPath;
|
||||
// Check whether custom parameters are set
|
||||
if (!pack.empty()) {
|
||||
SET_PACK_NAME(pack);
|
||||
fullPath = GET_MODEL_FILE();
|
||||
TEST_PRINT("Updated global Pack to: {}", TEST_MODEL_FILE);
|
||||
SET_RUNTIME_FULLPATH_NAME(fullPath);
|
||||
} else if (!packPath.empty()) {
|
||||
fullPath = packPath;
|
||||
TEST_PRINT("Updated global Pack File to: {}", packPath);
|
||||
SET_RUNTIME_FULLPATH_NAME(packPath);
|
||||
} else {
|
||||
fullPath = GET_MODEL_FILE();
|
||||
TEST_PRINT("Using default global Pack: {}", TEST_MODEL_FILE);
|
||||
SET_RUNTIME_FULLPATH_NAME(fullPath);
|
||||
}
|
||||
|
||||
TEST_PRINT("Launching InspireFace with path: {}", fullPath);
|
||||
ret = INSPIREFACE_CONTEXT->Load(fullPath.c_str());
|
||||
if (ret != HSUCCEED) {
|
||||
TEST_ERROR_PRINT("An error occurred while starting InspireFace: {}", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Set log level
|
||||
INSPIRE_SET_LOG_LEVEL(inspire::LogLevel::ISF_LOG_INFO);
|
||||
|
||||
// Run the test
|
||||
ret = session.run();
|
||||
|
||||
// Terminate the InspireFace instance
|
||||
INSPIREFACE_CONTEXT->Unload();
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -34,7 +34,7 @@ TEST_CASE("test_BenchmarkFaceDetect", "[benchmark]") {
|
||||
ret = CVImageToImageStream(image, imgHandle);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
inspirecv::TimeSpend timeSpend("Face Detect@160");
|
||||
inspire::SpendTimer timeSpend("Face Detect@160");
|
||||
for (size_t i = 0; i < loop; i++) {
|
||||
timeSpend.Start();
|
||||
// Extract basic face information from photos
|
||||
@@ -68,7 +68,7 @@ TEST_CASE("test_BenchmarkFaceDetect", "[benchmark]") {
|
||||
ret = CVImageToImageStream(image, imgHandle);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
inspirecv::TimeSpend timeSpend("Face Detect@320");
|
||||
inspire::SpendTimer timeSpend("Face Detect@320");
|
||||
for (size_t i = 0; i < loop; i++) {
|
||||
timeSpend.Start();
|
||||
// Extract basic face information from photos
|
||||
@@ -102,7 +102,7 @@ TEST_CASE("test_BenchmarkFaceDetect", "[benchmark]") {
|
||||
ret = CVImageToImageStream(image, imgHandle);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
inspirecv::TimeSpend timeSpend("Face Detect@640");
|
||||
inspire::SpendTimer timeSpend("Face Detect@640");
|
||||
for (size_t i = 0; i < loop; i++) {
|
||||
timeSpend.Start();
|
||||
// Extract basic face information from photos
|
||||
@@ -141,7 +141,7 @@ TEST_CASE("test_BenchmarkFaceTrack", "[benchmark]") {
|
||||
ret = CVImageToImageStream(image, imgHandle);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
inspirecv::TimeSpend timeSpend("Face Track");
|
||||
inspire::SpendTimer timeSpend("Face Track");
|
||||
for (size_t i = 0; i < loop; i++) {
|
||||
timeSpend.Start();
|
||||
// Extract basic face information from photos
|
||||
@@ -186,7 +186,7 @@ TEST_CASE("test_BenchmarkFaceExtractWithAlign", "[benchmark]") {
|
||||
ret = HFExecuteFaceTrack(session, imgHandle, &multipleFaceData);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
inspirecv::TimeSpend timeSpend("Face Extract With Align");
|
||||
inspire::SpendTimer timeSpend("Face Extract With Align");
|
||||
for (size_t i = 0; i < loop; i++) {
|
||||
timeSpend.Start();
|
||||
// Extract basic face information from photos
|
||||
@@ -257,7 +257,7 @@ TEST_CASE("test_BenchmarkFaceComparison", "[benchmark]") {
|
||||
featureZyQuery.size = featureNum;
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
inspirecv::TimeSpend timeSpend("Face Comparison");
|
||||
inspire::SpendTimer timeSpend("Face Comparison");
|
||||
for (int i = 0; i < loop; ++i) {
|
||||
timeSpend.Start();
|
||||
HFloat compRes;
|
||||
@@ -333,7 +333,7 @@ TEST_CASE("test_BenchmarkFaceHubSearchPersistence", "[benchmark]") {
|
||||
searchFeature.data = searchFeat.data();
|
||||
HFloat confidence = 0.0f;
|
||||
HFFaceFeatureIdentity mostSimilar = {0};
|
||||
inspirecv::TimeSpend timeSpend("Face Search 1k@Persistence");
|
||||
inspire::SpendTimer timeSpend("Face Search 1k@Persistence");
|
||||
for (size_t i = 0; i < loop; i++) {
|
||||
timeSpend.Start();
|
||||
ret = HFFeatureHubFaceSearch(searchFeature, &confidence, &mostSimilar);
|
||||
@@ -401,7 +401,7 @@ TEST_CASE("test_BenchmarkFaceHubSearchPersistence", "[benchmark]") {
|
||||
searchFeature.data = searchFeat.data();
|
||||
HFloat confidence = 0.0f;
|
||||
HFFaceFeatureIdentity mostSimilar = {0};
|
||||
inspirecv::TimeSpend timeSpend("Face Search 5k@Persistence");
|
||||
inspire::SpendTimer timeSpend("Face Search 5k@Persistence");
|
||||
for (size_t i = 0; i < loop; i++) {
|
||||
timeSpend.Start();
|
||||
ret = HFFeatureHubFaceSearch(searchFeature, &confidence, &mostSimilar);
|
||||
@@ -469,7 +469,7 @@ TEST_CASE("test_BenchmarkFaceHubSearchPersistence", "[benchmark]") {
|
||||
searchFeature.data = searchFeat.data();
|
||||
HFloat confidence = 0.0f;
|
||||
HFFaceFeatureIdentity mostSimilar = {0};
|
||||
inspirecv::TimeSpend timeSpend("Face Search 10k@Persistence");
|
||||
inspire::SpendTimer timeSpend("Face Search 10k@Persistence");
|
||||
for (size_t i = 0; i < loop; i++) {
|
||||
timeSpend.Start();
|
||||
ret = HFFeatureHubFaceSearch(searchFeature, &confidence, &mostSimilar);
|
||||
@@ -534,7 +534,7 @@ TEST_CASE("test_BenchmarkFaceHubSearchMemory", "[benchmark]") {
|
||||
searchFeature.data = searchFeat.data();
|
||||
HFloat confidence = 0.0f;
|
||||
HFFaceFeatureIdentity mostSimilar = {0};
|
||||
inspirecv::TimeSpend timeSpend("Face Search 1k@Memory");
|
||||
inspire::SpendTimer timeSpend("Face Search 1k@Memory");
|
||||
for (size_t i = 0; i < loop; i++) {
|
||||
timeSpend.Start();
|
||||
ret = HFFeatureHubFaceSearch(searchFeature, &confidence, &mostSimilar);
|
||||
@@ -592,7 +592,7 @@ TEST_CASE("test_BenchmarkFaceHubSearchMemory", "[benchmark]") {
|
||||
searchFeature.data = searchFeat.data();
|
||||
HFloat confidence = 0.0f;
|
||||
HFFaceFeatureIdentity mostSimilar = {0};
|
||||
inspirecv::TimeSpend timeSpend("Face Search 5k@Memory");
|
||||
inspire::SpendTimer timeSpend("Face Search 5k@Memory");
|
||||
for (size_t i = 0; i < loop; i++) {
|
||||
timeSpend.Start();
|
||||
ret = HFFeatureHubFaceSearch(searchFeature, &confidence, &mostSimilar);
|
||||
@@ -651,7 +651,7 @@ TEST_CASE("test_BenchmarkFaceHubSearchMemory", "[benchmark]") {
|
||||
searchFeature.data = searchFeat.data();
|
||||
HFloat confidence = 0.0f;
|
||||
HFFaceFeatureIdentity mostSimilar = {0};
|
||||
inspirecv::TimeSpend timeSpend("Face Search 10k@Memory");
|
||||
inspire::SpendTimer timeSpend("Face Search 10k@Memory");
|
||||
for (size_t i = 0; i < loop; i++) {
|
||||
timeSpend.Start();
|
||||
ret = HFFeatureHubFaceSearch(searchFeature, &confidence, &mostSimilar);
|
||||
|
||||
@@ -147,7 +147,7 @@ TEST_CASE("test_FacePipeline", "[face_pipeline]") {
|
||||
TEST_PRINT("{}", confidence.confidence[0]);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
CHECK(confidence.num > 0);
|
||||
CHECK(confidence.confidence[0] > 0.8);
|
||||
CHECK(confidence.confidence[0] > 0.70f);
|
||||
|
||||
ret = HFReleaseImageStream(img1Handle);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
@@ -415,7 +415,7 @@ TEST_CASE("test_TrackModeFaceAction", "[face_action]") {
|
||||
ret = HFCreateInspireFaceSession(parameter, detMode, 3, -1, -1, &session);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
#if 0
|
||||
#if 0 // Temporarily shut down the processing of frame related cases to prevent excessive data from occupying the github memory
|
||||
SECTION("Action Blink") {
|
||||
auto start = 130, end = 150;
|
||||
std::vector<std::string> filenames = generateFilenames("frame-%04d.jpg", start, end);
|
||||
@@ -449,7 +449,7 @@ TEST_CASE("test_TrackModeFaceAction", "[face_action]") {
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
#if 0 // Temporarily shut down the processing of frame related cases to prevent excessive data from occupying the github memory
|
||||
SECTION("Action Jaw Open") {
|
||||
auto start = 110, end = 150;
|
||||
std::vector<std::string> filenames = generateFilenames("frame-%04d.jpg", start, end);
|
||||
|
||||
@@ -48,8 +48,8 @@ TEST_CASE("test_FaceTrack", "[face_track]") {
|
||||
auto cvRect = inspirecv::Rect<int>::Create(rect.x, rect.y, rect.width, rect.height);
|
||||
image.DrawRect(cvRect, {0, 0, 255}, 2);
|
||||
image.Write("ww.jpg");
|
||||
// The iou is allowed to have an error of 25%
|
||||
CHECK(iou == Approx(1.0f).epsilon(0.25));
|
||||
// The iou is allowed to have an error of 50%
|
||||
CHECK(iou == Approx(1.0f).epsilon(0.5));
|
||||
|
||||
ret = HFReleaseImageStream(imgHandle);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
@@ -70,6 +70,7 @@ TEST_CASE("test_FaceTrack", "[face_track]") {
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
}
|
||||
|
||||
// Temporarily shut down the processing of frame related cases to prevent excessive data from occupying the github memory
|
||||
#if 0
|
||||
SECTION("Face tracking stability from frames") {
|
||||
HResult ret;
|
||||
@@ -124,6 +125,7 @@ TEST_CASE("test_FaceTrack", "[face_track]") {
|
||||
SECTION("Head pose estimation") {
|
||||
HResult ret;
|
||||
HFSessionCustomParameter parameter = {0};
|
||||
parameter.enable_face_pose = true;
|
||||
HFDetectMode detMode = HF_DETECT_MODE_ALWAYS_DETECT;
|
||||
HFSession session;
|
||||
ret = HFCreateInspireFaceSession(parameter, detMode, 3, -1, -1, &session);
|
||||
@@ -318,6 +320,12 @@ TEST_CASE("test_MultipleLevelFaceDetect", "[face_detect]") {
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
HFSessionSetTrackPreviewSize(session, detectPixelLevel);
|
||||
HFSessionSetFilterMinimumFacePixelSize(session, 0);
|
||||
|
||||
// Check the preview size
|
||||
HInt32 previewSize;
|
||||
ret = HFSessionGetTrackPreviewSize(session, &previewSize);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
CHECK(previewSize == detectPixelLevel);
|
||||
|
||||
// Get a face picture
|
||||
HFImageStream imgHandle;
|
||||
@@ -351,6 +359,12 @@ TEST_CASE("test_MultipleLevelFaceDetect", "[face_detect]") {
|
||||
HFSessionSetTrackPreviewSize(session, detectPixelLevel);
|
||||
HFSessionSetFilterMinimumFacePixelSize(session, 0);
|
||||
|
||||
// Check the preview size
|
||||
HInt32 previewSize;
|
||||
ret = HFSessionGetTrackPreviewSize(session, &previewSize);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
CHECK(previewSize == detectPixelLevel);
|
||||
|
||||
// Get a face picture
|
||||
HFImageStream imgHandle;
|
||||
auto image = inspirecv::Image::Create(GET_DATA("data/bulk/pedestrian.png"));
|
||||
@@ -383,6 +397,12 @@ TEST_CASE("test_MultipleLevelFaceDetect", "[face_detect]") {
|
||||
HFSessionSetTrackPreviewSize(session, detectPixelLevel);
|
||||
HFSessionSetFilterMinimumFacePixelSize(session, 0);
|
||||
|
||||
// Check the preview size
|
||||
HInt32 previewSize;
|
||||
ret = HFSessionGetTrackPreviewSize(session, &previewSize);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
CHECK(previewSize == detectPixelLevel);
|
||||
|
||||
// Get a face picture
|
||||
HFImageStream imgHandle;
|
||||
auto image = inspirecv::Image::Create(GET_DATA("data/bulk/pedestrian.png"));
|
||||
@@ -403,4 +423,133 @@ TEST_CASE("test_MultipleLevelFaceDetect", "[face_detect]") {
|
||||
ret = HFReleaseInspireFaceSession(session);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("test_FaceTrackPreviewSizeSetting", "[face_track]") {
|
||||
DRAW_SPLIT_LINE
|
||||
TEST_PRINT_OUTPUT(true);
|
||||
|
||||
SECTION("Default preview size and detection level size") {
|
||||
HResult ret;
|
||||
HFSessionCustomParameter parameter = {0};
|
||||
HFDetectMode detMode = HF_DETECT_MODE_ALWAYS_DETECT;
|
||||
HFSession session;
|
||||
HInt32 levelSize = -1;
|
||||
ret = HFCreateInspireFaceSession(parameter, detMode, 20, levelSize, -1, &session);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
// Check the preview size
|
||||
HInt32 previewSize;
|
||||
ret = HFSessionGetTrackPreviewSize(session, &previewSize);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
CHECK(previewSize == 320);
|
||||
|
||||
// Get a face picture
|
||||
HFImageStream imgHandle;
|
||||
auto image = inspirecv::Image::Create(GET_DATA("data/bulk/pedestrian.png"));
|
||||
ret = CVImageToImageStream(image, imgHandle);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
// Extract basic face information from photos
|
||||
HFMultipleFaceData multipleFaceData = {0};
|
||||
ret = HFExecuteFaceTrack(session, imgHandle, &multipleFaceData);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
CHECK(multipleFaceData.detectedNum > 0);
|
||||
// Check the preview size
|
||||
HInt32 debugPreviewSize;
|
||||
ret = HFSessionLastFaceDetectionGetDebugPreviewImageSize(session, &debugPreviewSize);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
CHECK(debugPreviewSize == 320);
|
||||
|
||||
ret = HFReleaseImageStream(imgHandle);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
ret = HFReleaseInspireFaceSession(session);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
}
|
||||
|
||||
SECTION("Set preview size to 320px") {
|
||||
HResult ret;
|
||||
HFSessionCustomParameter parameter = {0};
|
||||
HFDetectMode detMode = HF_DETECT_MODE_ALWAYS_DETECT;
|
||||
HFSession session;
|
||||
HInt32 levelSize = 320;
|
||||
ret = HFCreateInspireFaceSession(parameter, detMode, 20, levelSize, -1, &session);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
// Check the preview size
|
||||
HInt32 previewSize;
|
||||
ret = HFSessionGetTrackPreviewSize(session, &previewSize);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
CHECK(previewSize == levelSize);
|
||||
|
||||
ret = HFReleaseInspireFaceSession(session);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
}
|
||||
|
||||
SECTION("Set the detect level to an invalid value") {
|
||||
HResult ret;
|
||||
HFSessionCustomParameter parameter = {0};
|
||||
HFDetectMode detMode = HF_DETECT_MODE_ALWAYS_DETECT;
|
||||
HFSession session;
|
||||
HInt32 levelSize = 1000;
|
||||
ret = HFCreateInspireFaceSession(parameter, detMode, 20, levelSize, -1, &session);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
// Check the preview size
|
||||
HInt32 previewSize;
|
||||
ret = HFSessionGetTrackPreviewSize(session, &previewSize);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
// If the detect level value is invalid, the value will be automatically adjusted to the nearest legal size.
|
||||
// If the default value of preview_size is -1, the value will also be adjusted
|
||||
CHECK(previewSize == 640);
|
||||
|
||||
// Get a face picture
|
||||
HFImageStream imgHandle;
|
||||
auto image = inspirecv::Image::Create(GET_DATA("data/bulk/pedestrian.png"));
|
||||
ret = CVImageToImageStream(image, imgHandle);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
// Extract basic face information from photos
|
||||
HFMultipleFaceData multipleFaceData = {0};
|
||||
ret = HFExecuteFaceTrack(session, imgHandle, &multipleFaceData);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
CHECK(multipleFaceData.detectedNum > 0);
|
||||
|
||||
// Check the preview size
|
||||
HInt32 debugPreviewSize;
|
||||
ret = HFSessionLastFaceDetectionGetDebugPreviewImageSize(session, &debugPreviewSize);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
CHECK(debugPreviewSize == 640);
|
||||
|
||||
// Set a value manually
|
||||
ret = HFSessionSetTrackPreviewSize(session, 192);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
// Check the preview size
|
||||
ret = HFSessionGetTrackPreviewSize(session, &previewSize);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
CHECK(previewSize == 192);
|
||||
|
||||
ret = HFExecuteFaceTrack(session, imgHandle, &multipleFaceData);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
CHECK(multipleFaceData.detectedNum > 0);
|
||||
|
||||
// Check the preview size
|
||||
ret = HFSessionLastFaceDetectionGetDebugPreviewImageSize(session, &debugPreviewSize);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
CHECK(debugPreviewSize == 192);
|
||||
|
||||
|
||||
ret = HFReleaseImageStream(imgHandle);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
ret = HFReleaseInspireFaceSession(session);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -43,7 +43,7 @@ TEST_CASE("test_SessionParallel", "[Session][Parallel]") {
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
float similarity = 0.0f;
|
||||
inspirecv::TimeSpend timeSpend("Serial loop: " + std::to_string(loop));
|
||||
inspire::SpendTimer timeSpend("Serial loop: " + std::to_string(loop));
|
||||
timeSpend.Start();
|
||||
for (int i = 0; i < loop; ++i) {
|
||||
ret = CompareTwoFaces(session, image1, image2, similarity);
|
||||
@@ -52,6 +52,7 @@ TEST_CASE("test_SessionParallel", "[Session][Parallel]") {
|
||||
}
|
||||
timeSpend.Stop();
|
||||
std::cout << timeSpend << std::endl;
|
||||
;
|
||||
|
||||
ret = HFReleaseInspireFaceSession(session);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
@@ -85,7 +86,7 @@ TEST_CASE("test_SessionParallel", "[Session][Parallel]") {
|
||||
float similaritySum = 0.0f;
|
||||
std::mutex similarityMutex;
|
||||
|
||||
inspirecv::TimeSpend timeSpend("Parallel loop: " + std::to_string(loop) + ", thread: " + std::to_string(N));
|
||||
inspire::SpendTimer timeSpend("Parallel loop: " + std::to_string(loop) + ", thread: " + std::to_string(N));
|
||||
timeSpend.Start();
|
||||
|
||||
// Start worker thread
|
||||
@@ -119,6 +120,7 @@ TEST_CASE("test_SessionParallel", "[Session][Parallel]") {
|
||||
|
||||
timeSpend.Stop();
|
||||
std::cout << timeSpend << std::endl;
|
||||
;
|
||||
|
||||
// Optional: Output average similarity(stability)
|
||||
TEST_PRINT("Average similarity: {}", (similaritySum / loop));
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#include <iostream>
|
||||
#include "settings/test_settings.h"
|
||||
#include "unit/test_helper/test_help.h"
|
||||
#include "inspireface/recognition_module/similarity_converter.h"
|
||||
#include "inspireface/include/inspireface/similarity_converter.h"
|
||||
|
||||
TEST_CASE("test_similarity_converter", "[similarity_converter]") {
|
||||
DRAW_SPLIT_LINE
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
#if 0
|
||||
#include <iostream>
|
||||
#include "settings/test_settings.h"
|
||||
#include "inspireface/c_api/inspireface.h"
|
||||
#include "inspireface/herror.h"
|
||||
#include "opencv2/opencv.hpp"
|
||||
#include "inspireface/include/inspireface/herror.h"
|
||||
#include "unit/test_helper/test_tools.h"
|
||||
#include <cstdio>
|
||||
|
||||
@@ -11,12 +9,17 @@ TEST_CASE("test_System", "[system]") {
|
||||
DRAW_SPLIT_LINE
|
||||
TEST_PRINT_OUTPUT(true);
|
||||
|
||||
// The global TEST environment has been started, so this side needs to be temporarily closed
|
||||
// before testing
|
||||
HFTerminateInspireFace();
|
||||
HResult ret;
|
||||
HInt32 status;
|
||||
ret = HFQueryInspireFaceLaunchStatus(&status);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
if (status == HF_STATUS_ENABLE) {
|
||||
// The global TEST environment has been started, so this side needs to be temporarily closed
|
||||
// before testing
|
||||
HFTerminateInspireFace();
|
||||
}
|
||||
|
||||
SECTION("Create a session test when it is not loaded") {
|
||||
HResult ret;
|
||||
HFSessionCustomParameter parameter = {0};
|
||||
HFDetectMode detMode = HF_DETECT_MODE_ALWAYS_DETECT;
|
||||
HFSession session;
|
||||
@@ -27,7 +30,7 @@ TEST_CASE("test_System", "[system]") {
|
||||
}
|
||||
|
||||
// Restart and start InspireFace
|
||||
auto ret = HFLaunchInspireFace(GET_RUNTIME_FULLPATH_NAME.c_str());
|
||||
ret = HFLaunchInspireFace(GET_RUNTIME_FULLPATH_NAME.c_str());
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
SECTION("Create a session test when it is reloaded") {
|
||||
@@ -178,7 +181,7 @@ TEST_CASE("test_SystemStreamReleaseCase", "[system]") {
|
||||
|
||||
for (int i = 0; i < createCount; ++i) {
|
||||
HFImageStream imgHandle;
|
||||
auto image = cv::imread(GET_DATA("data/bulk/pedestrian.png"));
|
||||
auto image = inspirecv::Image::Create(GET_DATA("data/bulk/pedestrian.png"));
|
||||
ret = CVImageToImageStream(image, imgHandle);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
streams[i] = imgHandle;
|
||||
@@ -267,5 +270,3 @@ TEST_CASE("test_SystemStreamReleaseCase", "[system]") {
|
||||
REQUIRE(count == 0);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -2,12 +2,11 @@
|
||||
#include <iostream>
|
||||
#include "settings/test_settings.h"
|
||||
#include "unit/test_helper/help.h"
|
||||
#include "feature_hub/feature_hub_db.h"
|
||||
#include "middleware/costman.h"
|
||||
#include "inspireface/initialization_module/launch.h"
|
||||
#include "middleware/inspirecv_image_process.h"
|
||||
#include "inspireface/face_session.h"
|
||||
#include "inspireface/feature_hub/feature_hub_db.h"
|
||||
#include <inspireface/include/inspireface/launch.h>
|
||||
#include "frame_process.h"
|
||||
#include "inspireface/engine/face_session.h"
|
||||
#include <inspireface/include/inspireface/feature_hub_db.h>
|
||||
|
||||
using namespace inspire;
|
||||
|
||||
@@ -29,12 +28,10 @@ TEST_CASE("test_FaceSession", "[face_session") {
|
||||
|
||||
inspirecv::Image kun1 = inspirecv::Image::Create(GET_DATA("data/bulk/kun.jpg"));
|
||||
inspirecv::Image kun2 = inspirecv::Image::Create(GET_DATA("data/bulk/jntm.jpg"));
|
||||
inspirecv::InspireImageProcess proc1 =
|
||||
inspirecv::InspireImageProcess::Create(kun1.Data(), kun1.Height(), kun1.Width(), inspirecv::BGR, inspirecv::ROTATION_0);
|
||||
inspirecv::InspireImageProcess proc2 =
|
||||
inspirecv::InspireImageProcess::Create(kun2.Data(), kun2.Height(), kun2.Width(), inspirecv::BGR, inspirecv::ROTATION_0);
|
||||
inspirecv::FrameProcess proc1 = inspirecv::FrameProcess::Create(kun1.Data(), kun1.Height(), kun1.Width(), inspirecv::BGR, inspirecv::ROTATION_0);
|
||||
inspirecv::FrameProcess proc2 = inspirecv::FrameProcess::Create(kun2.Data(), kun2.Height(), kun2.Width(), inspirecv::BGR, inspirecv::ROTATION_0);
|
||||
std::vector<std::vector<float>> features;
|
||||
std::vector<inspirecv::InspireImageProcess> processes = {proc1, proc2};
|
||||
std::vector<inspirecv::FrameProcess> processes = {proc1, proc2};
|
||||
for (auto &process : processes) {
|
||||
ret = session.FaceDetectAndTrack(process);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
@@ -45,7 +42,7 @@ TEST_CASE("test_FaceSession", "[face_session") {
|
||||
const auto &faces = session.GetTrackingFaceList();
|
||||
REQUIRE(faces.size() > 0);
|
||||
Embedded feature;
|
||||
HyperFaceData hyper_face_data = FaceObjectInternalToHyperFaceData(faces[0]);
|
||||
FaceTrackWrap hyper_face_data = FaceObjectInternalToHyperFaceData(faces[0]);
|
||||
float norm;
|
||||
ret = session.FaceRecognitionModule()->FaceExtract(process, hyper_face_data, feature, norm);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
@@ -59,8 +56,8 @@ TEST_CASE("test_FaceSession", "[face_session") {
|
||||
REQUIRE(res > 0.5f);
|
||||
|
||||
inspirecv::Image other = inspirecv::Image::Create(GET_DATA("data/bulk/woman.png"));
|
||||
inspirecv::InspireImageProcess proc3 =
|
||||
inspirecv::InspireImageProcess::Create(other.Data(), other.Height(), other.Width(), inspirecv::BGR, inspirecv::ROTATION_0);
|
||||
inspirecv::FrameProcess proc3 =
|
||||
inspirecv::FrameProcess::Create(other.Data(), other.Height(), other.Width(), inspirecv::BGR, inspirecv::ROTATION_0);
|
||||
ret = session.FaceDetectAndTrack(proc3);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
if (session.GetDetectCache().size() > 0) {
|
||||
@@ -69,7 +66,7 @@ TEST_CASE("test_FaceSession", "[face_session") {
|
||||
auto faces = session.GetTrackingFaceList();
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
Embedded feature;
|
||||
HyperFaceData hyper_face_data = FaceObjectInternalToHyperFaceData(faces[0]);
|
||||
FaceTrackWrap hyper_face_data = FaceObjectInternalToHyperFaceData(faces[0]);
|
||||
float norm;
|
||||
ret = session.FaceRecognitionModule()->FaceExtract(proc3, hyper_face_data, feature, norm);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#include "settings/test_settings.h"
|
||||
#include "inspireface/c_api/inspireface.h"
|
||||
#include "unit/test_helper/help.h"
|
||||
#include "feature_hub/feature_hub_db.h"
|
||||
#include <inspireface/include/inspireface/feature_hub_db.h>
|
||||
#include "middleware/costman.h"
|
||||
|
||||
using namespace inspire;
|
||||
@@ -16,11 +16,11 @@ TEST_CASE("test_FeatureHubBasic", "[feature_hub") {
|
||||
config.primary_key_mode = PrimaryKeyMode::AUTO_INCREMENT;
|
||||
config.enable_persistence = false; // memory mode
|
||||
int32_t ret;
|
||||
ret = FEATURE_HUB_DB->EnableHub(config);
|
||||
ret = INSPIREFACE_FEATURE_HUB->EnableHub(config);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
// Check if feature hub is enabled
|
||||
ret = FEATURE_HUB_DB->EnableHub(config);
|
||||
ret = INSPIREFACE_FEATURE_HUB->EnableHub(config);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
// Check number of features
|
||||
@@ -30,69 +30,69 @@ TEST_CASE("test_FeatureHubBasic", "[feature_hub") {
|
||||
for (int32_t i = 0; i < count; i++) {
|
||||
auto vec = GenerateRandomFeature(512, false);
|
||||
int64_t alloc_id;
|
||||
ret = FEATURE_HUB_DB->FaceFeatureInsert(vec, -1, alloc_id);
|
||||
ret = INSPIREFACE_FEATURE_HUB->FaceFeatureInsert(vec, -1, alloc_id);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
ids.push_back(alloc_id);
|
||||
expected_ids.push_back(i + 1);
|
||||
}
|
||||
REQUIRE(FEATURE_HUB_DB->GetFaceFeatureCount() == ids.size());
|
||||
REQUIRE(INSPIREFACE_FEATURE_HUB->GetFaceFeatureCount() == ids.size());
|
||||
REQUIRE(ids == expected_ids);
|
||||
|
||||
// Delete data
|
||||
std::vector<int64_t> delete_ids = {5, 20, 100};
|
||||
for (auto id : delete_ids) {
|
||||
FEATURE_HUB_DB->FaceFeatureRemove(id);
|
||||
INSPIREFACE_FEATURE_HUB->FaceFeatureRemove(id);
|
||||
}
|
||||
REQUIRE(FEATURE_HUB_DB->GetFaceFeatureCount() == ids.size() - delete_ids.size());
|
||||
REQUIRE(INSPIREFACE_FEATURE_HUB->GetFaceFeatureCount() == ids.size() - delete_ids.size());
|
||||
|
||||
// Check if the deleted data can be found
|
||||
std::vector<float> feature;
|
||||
ret = FEATURE_HUB_DB->GetFaceFeature(5, feature);
|
||||
ret = INSPIREFACE_FEATURE_HUB->GetFaceFeature(5, feature);
|
||||
REQUIRE(ret == HERR_FT_HUB_NOT_FOUND_FEATURE);
|
||||
|
||||
// Check if the data can be found
|
||||
ret = FEATURE_HUB_DB->GetFaceFeature(1, feature);
|
||||
ret = INSPIREFACE_FEATURE_HUB->GetFaceFeature(1, feature);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
REQUIRE(feature.size() == 512);
|
||||
|
||||
// Check if the cached data is correct
|
||||
ret = FEATURE_HUB_DB->GetFaceFeature(1);
|
||||
ret = INSPIREFACE_FEATURE_HUB->GetFaceFeature(1);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
auto cached_feature = FEATURE_HUB_DB->GetFaceFeaturePtrCache();
|
||||
auto cached_feature = INSPIREFACE_FEATURE_HUB->GetFaceFeaturePtrCache();
|
||||
for (size_t i = 0; i < cached_feature->dataSize; i++) {
|
||||
REQUIRE(feature[i] == cached_feature->data[i]);
|
||||
}
|
||||
|
||||
// Update data
|
||||
auto update_feature = GenerateRandomFeature(512, false);
|
||||
ret = FEATURE_HUB_DB->FaceFeatureUpdate(update_feature, 1);
|
||||
ret = INSPIREFACE_FEATURE_HUB->FaceFeatureUpdate(update_feature, 1);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
// Check if the updated data is correct
|
||||
ret = FEATURE_HUB_DB->GetFaceFeature(1, feature);
|
||||
ret = INSPIREFACE_FEATURE_HUB->GetFaceFeature(1, feature);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
for (size_t i = 0; i < feature.size(); i++) {
|
||||
REQUIRE(feature[i] == Approx(update_feature[i]).epsilon(0.0001));
|
||||
}
|
||||
|
||||
// Update removed data
|
||||
ret = FEATURE_HUB_DB->FaceFeatureUpdate(update_feature, 5);
|
||||
ret = INSPIREFACE_FEATURE_HUB->FaceFeatureUpdate(update_feature, 5);
|
||||
REQUIRE(ret == HERR_FT_HUB_NOT_FOUND_FEATURE);
|
||||
|
||||
// Disable feature hub
|
||||
FEATURE_HUB_DB->DisableHub();
|
||||
REQUIRE(FEATURE_HUB_DB->GetFaceFeatureCount() == 0);
|
||||
INSPIREFACE_FEATURE_HUB->DisableHub();
|
||||
REQUIRE(INSPIREFACE_FEATURE_HUB->GetFaceFeatureCount() == 0);
|
||||
|
||||
// Check if the data can be found
|
||||
ret = FEATURE_HUB_DB->GetFaceFeature(1, feature);
|
||||
ret = INSPIREFACE_FEATURE_HUB->GetFaceFeature(1, feature);
|
||||
REQUIRE(ret == HERR_FT_HUB_DISABLE);
|
||||
|
||||
ret = FEATURE_HUB_DB->EnableHub(config);
|
||||
ret = INSPIREFACE_FEATURE_HUB->EnableHub(config);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
// Because the memory mode is turned on, once the data is turned off, it goes back to empty
|
||||
REQUIRE(FEATURE_HUB_DB->GetFaceFeatureCount() == 0);
|
||||
REQUIRE(INSPIREFACE_FEATURE_HUB->GetFaceFeatureCount() == 0);
|
||||
|
||||
ret = FEATURE_HUB_DB->DisableHub();
|
||||
ret = INSPIREFACE_FEATURE_HUB->DisableHub();
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
}
|
||||
|
||||
@@ -104,7 +104,7 @@ TEST_CASE("test_PerformanceMemoryMode", "[feature_hub") {
|
||||
config.primary_key_mode = PrimaryKeyMode::AUTO_INCREMENT;
|
||||
config.enable_persistence = false; // memory mode
|
||||
int32_t ret;
|
||||
ret = FEATURE_HUB_DB->EnableHub(config);
|
||||
ret = INSPIREFACE_FEATURE_HUB->EnableHub(config);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
Timer t1;
|
||||
@@ -112,32 +112,32 @@ TEST_CASE("test_PerformanceMemoryMode", "[feature_hub") {
|
||||
for (int i = 0; i < num; i++) {
|
||||
auto vec = GenerateRandomFeature(512, false);
|
||||
int64_t alloc_id;
|
||||
ret = FEATURE_HUB_DB->FaceFeatureInsert(vec, -1, alloc_id);
|
||||
ret = INSPIREFACE_FEATURE_HUB->FaceFeatureInsert(vec, -1, alloc_id);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
}
|
||||
TEST_PRINT("[Memory Mode]Insert 10000 features cost: {:.2f} ms", t1.GetCostTime());
|
||||
|
||||
Timer t2;
|
||||
std::vector<float> feature;
|
||||
ret = FEATURE_HUB_DB->GetFaceFeature(1, feature);
|
||||
ret = INSPIREFACE_FEATURE_HUB->GetFaceFeature(1, feature);
|
||||
TEST_PRINT("[Memory Mode]Get feature from id cost: {:.2f} ms", t2.GetCostTime());
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
Timer t3;
|
||||
ret = FEATURE_HUB_DB->GetFaceFeature(9998, feature);
|
||||
ret = INSPIREFACE_FEATURE_HUB->GetFaceFeature(9998, feature);
|
||||
TEST_PRINT("[Memory Mode]Get feature from id cost: {:.2f} ms", t3.GetCostTime());
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
auto sim_vec = SimulateSimilarVector(feature, false);
|
||||
FaceSearchResult search_result;
|
||||
Timer t4;
|
||||
FEATURE_HUB_DB->SearchFaceFeature(sim_vec, search_result, true);
|
||||
INSPIREFACE_FEATURE_HUB->SearchFaceFeature(sim_vec, search_result, true);
|
||||
TEST_PRINT("[Memory Mode]Search feature cost: {:.2f} ms", t4.GetCostTime());
|
||||
REQUIRE(search_result.id == 9998);
|
||||
|
||||
ret = FEATURE_HUB_DB->FaceFeatureRemove(9998);
|
||||
ret = INSPIREFACE_FEATURE_HUB->FaceFeatureRemove(9998);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
FEATURE_HUB_DB->DisableHub();
|
||||
INSPIREFACE_FEATURE_HUB->DisableHub();
|
||||
}
|
||||
|
||||
TEST_CASE("test_PerformancePersistentMode", "[feature_hub") {
|
||||
@@ -153,7 +153,7 @@ TEST_CASE("test_PerformancePersistentMode", "[feature_hub") {
|
||||
config.persistence_db_path = db_path;
|
||||
|
||||
int32_t ret;
|
||||
ret = FEATURE_HUB_DB->EnableHub(config);
|
||||
ret = INSPIREFACE_FEATURE_HUB->EnableHub(config);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
Timer t1;
|
||||
@@ -161,38 +161,38 @@ TEST_CASE("test_PerformancePersistentMode", "[feature_hub") {
|
||||
for (int i = 0; i < num; i++) {
|
||||
auto vec = GenerateRandomFeature(512, false);
|
||||
int64_t alloc_id;
|
||||
ret = FEATURE_HUB_DB->FaceFeatureInsert(vec, -1, alloc_id);
|
||||
ret = INSPIREFACE_FEATURE_HUB->FaceFeatureInsert(vec, -1, alloc_id);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
}
|
||||
TEST_PRINT("[Persistent Mode]Insert 10000 features cost: {:.2f} ms", t1.GetCostTime());
|
||||
|
||||
Timer t2;
|
||||
std::vector<float> feature;
|
||||
ret = FEATURE_HUB_DB->GetFaceFeature(1, feature);
|
||||
ret = INSPIREFACE_FEATURE_HUB->GetFaceFeature(1, feature);
|
||||
TEST_PRINT("[Persistent Mode]Get feature from id cost: {:.2f} ms", t2.GetCostTime());
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
Timer t3;
|
||||
ret = FEATURE_HUB_DB->GetFaceFeature(9998, feature);
|
||||
ret = INSPIREFACE_FEATURE_HUB->GetFaceFeature(9998, feature);
|
||||
TEST_PRINT("[Persistent Mode]Get feature from id cost: {:.2f} ms", t3.GetCostTime());
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
auto sim_vec = SimulateSimilarVector(feature, false);
|
||||
FaceSearchResult search_result;
|
||||
Timer t4;
|
||||
FEATURE_HUB_DB->SearchFaceFeature(sim_vec, search_result, true);
|
||||
INSPIREFACE_FEATURE_HUB->SearchFaceFeature(sim_vec, search_result, true);
|
||||
TEST_PRINT("[Persistent Mode]Search feature cost: {:.2f} ms", t4.GetCostTime());
|
||||
REQUIRE(search_result.id == 9998);
|
||||
|
||||
ret = FEATURE_HUB_DB->FaceFeatureRemove(9998);
|
||||
ret = INSPIREFACE_FEATURE_HUB->FaceFeatureRemove(9998);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
auto remark_num = FEATURE_HUB_DB->GetFaceFeatureCount();
|
||||
auto remark_num = INSPIREFACE_FEATURE_HUB->GetFaceFeatureCount();
|
||||
REQUIRE(remark_num == num - 1);
|
||||
|
||||
// Verify important of persistence test
|
||||
ret = FEATURE_HUB_DB->EnableHub(config);
|
||||
ret = INSPIREFACE_FEATURE_HUB->EnableHub(config);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
REQUIRE(FEATURE_HUB_DB->GetFaceFeatureCount() == remark_num);
|
||||
REQUIRE(INSPIREFACE_FEATURE_HUB->GetFaceFeatureCount() == remark_num);
|
||||
|
||||
FEATURE_HUB_DB->DisableHub();
|
||||
INSPIREFACE_FEATURE_HUB->DisableHub();
|
||||
}
|
||||
|
||||
@@ -2,19 +2,18 @@
|
||||
#include <iostream>
|
||||
#include "settings/test_settings.h"
|
||||
#include "unit/test_helper/help.h"
|
||||
#include "feature_hub/feature_hub_db.h"
|
||||
#include <inspireface/include/inspireface/feature_hub_db.h>
|
||||
#include "middleware/costman.h"
|
||||
#include "track_module/face_detect/all.h"
|
||||
#include "inspireface/initialization_module/launch.h"
|
||||
#include "track_module/face_track_module.h"
|
||||
#include "middleware/inspirecv_image_process.h"
|
||||
#include <inspireface/include/inspireface/frame_process.h>
|
||||
|
||||
using namespace inspire;
|
||||
|
||||
TEST_CASE("test_FaceDetect", "[track_module") {
|
||||
DRAW_SPLIT_LINE
|
||||
TEST_PRINT_OUTPUT(true);
|
||||
auto archive = INSPIRE_LAUNCH->getMArchive();
|
||||
auto archive = INSPIREFACE_CONTEXT->getMArchive();
|
||||
const std::vector<int32_t> supported_sizes = {160, 320, 640};
|
||||
const std::vector<std::string> scheme_names = {"face_detect_160", "face_detect_320", "face_detect_640"};
|
||||
for (size_t i = 0; i < scheme_names.size(); i++) {
|
||||
@@ -22,7 +21,7 @@ TEST_CASE("test_FaceDetect", "[track_module") {
|
||||
auto ret = archive.LoadModel(scheme_names[i], model);
|
||||
REQUIRE(ret == 0);
|
||||
FaceDetectAdapt face_detector(supported_sizes[i]);
|
||||
face_detector.loadData(model, model.modelType, false);
|
||||
face_detector.LoadData(model, model.modelType, false);
|
||||
|
||||
inspirecv::Image img = inspirecv::Image::Create(GET_DATA("data/bulk/kun.jpg"));
|
||||
auto result = face_detector(img);
|
||||
@@ -33,12 +32,12 @@ TEST_CASE("test_FaceDetect", "[track_module") {
|
||||
TEST_CASE("test_RefineNet", "[track_module") {
|
||||
DRAW_SPLIT_LINE
|
||||
TEST_PRINT_OUTPUT(true);
|
||||
auto archive = INSPIRE_LAUNCH->getMArchive();
|
||||
auto archive = INSPIREFACE_CONTEXT->getMArchive();
|
||||
InspireModel model;
|
||||
auto ret = archive.LoadModel("refine_net", model);
|
||||
REQUIRE(ret == 0);
|
||||
RNetAdapt rnet;
|
||||
rnet.loadData(model, model.modelType, false);
|
||||
rnet.LoadData(model, model.modelType, false);
|
||||
|
||||
inspirecv::Image face = inspirecv::Image::Create(GET_DATA("data/crop/crop.png"));
|
||||
auto result1 = rnet(face);
|
||||
@@ -52,13 +51,13 @@ TEST_CASE("test_RefineNet", "[track_module") {
|
||||
TEST_CASE("test_Landmark", "[track_module") {
|
||||
DRAW_SPLIT_LINE
|
||||
TEST_PRINT_OUTPUT(true);
|
||||
auto archive = INSPIRE_LAUNCH->getMArchive();
|
||||
auto archive = INSPIREFACE_CONTEXT->getMArchive();
|
||||
InspireModel model;
|
||||
auto ret = archive.LoadModel("landmark", model);
|
||||
REQUIRE(ret == 0);
|
||||
|
||||
FaceLandmarkAdapt face_landmark(112);
|
||||
face_landmark.loadData(model, model.modelType);
|
||||
face_landmark.LoadData(model, model.modelType);
|
||||
|
||||
inspirecv::Image img = inspirecv::Image::Create(GET_DATA("data/crop/crop.png"));
|
||||
auto result = face_landmark(img);
|
||||
@@ -68,12 +67,12 @@ TEST_CASE("test_Landmark", "[track_module") {
|
||||
TEST_CASE("test_Quality", "[track_module") {
|
||||
DRAW_SPLIT_LINE
|
||||
TEST_PRINT_OUTPUT(true);
|
||||
auto archive = INSPIRE_LAUNCH->getMArchive();
|
||||
auto archive = INSPIREFACE_CONTEXT->getMArchive();
|
||||
InspireModel model;
|
||||
auto ret = archive.LoadModel("pose_quality", model);
|
||||
REQUIRE(ret == 0);
|
||||
FacePoseQualityAdapt quality;
|
||||
ret = quality.loadData(model, model.modelType);
|
||||
ret = quality.LoadData(model, model.modelType);
|
||||
REQUIRE(ret == 0);
|
||||
|
||||
inspirecv::Image img = inspirecv::Image::Create(GET_DATA("data/crop/crop.png"));
|
||||
@@ -85,7 +84,7 @@ TEST_CASE("test_Quality", "[track_module") {
|
||||
TEST_CASE("test_FaceTrackModule", "[track_module") {
|
||||
DRAW_SPLIT_LINE
|
||||
TEST_PRINT_OUTPUT(true);
|
||||
auto archive = INSPIRE_LAUNCH->getMArchive();
|
||||
auto archive = INSPIREFACE_CONTEXT->getMArchive();
|
||||
|
||||
SECTION("Test face detect rotate 0") {
|
||||
auto mode = DetectModuleMode::DETECT_MODE_ALWAYS_DETECT;
|
||||
@@ -93,7 +92,7 @@ TEST_CASE("test_FaceTrackModule", "[track_module") {
|
||||
FaceTrackModule face_track(mode, max_detected_faces);
|
||||
face_track.Configuration(archive);
|
||||
inspirecv::Image img = inspirecv::Image::Create(GET_DATA("data/bulk/kun.jpg"));
|
||||
inspirecv::InspireImageProcess image = inspirecv::InspireImageProcess::Create(img.Data(), img.Height(), img.Width(), inspirecv::BGR);
|
||||
inspirecv::FrameProcess image = inspirecv::FrameProcess::Create(img.Data(), img.Height(), img.Width(), inspirecv::BGR);
|
||||
face_track.UpdateStream(image);
|
||||
REQUIRE(face_track.trackingFace.size() == 1);
|
||||
}
|
||||
@@ -104,8 +103,8 @@ TEST_CASE("test_FaceTrackModule", "[track_module") {
|
||||
FaceTrackModule face_track(mode, max_detected_faces);
|
||||
face_track.Configuration(archive);
|
||||
inspirecv::Image img = inspirecv::Image::Create(GET_DATA("data/bulk/r90.jpg"));
|
||||
inspirecv::InspireImageProcess image =
|
||||
inspirecv::InspireImageProcess::Create(img.Data(), img.Height(), img.Width(), inspirecv::BGR, inspirecv::ROTATION_90);
|
||||
inspirecv::FrameProcess image =
|
||||
inspirecv::FrameProcess::Create(img.Data(), img.Height(), img.Width(), inspirecv::BGR, inspirecv::ROTATION_90);
|
||||
face_track.UpdateStream(image);
|
||||
REQUIRE(face_track.trackingFace.size() == 1);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,118 @@
|
||||
/**
|
||||
* Created by Jingyu Yan
|
||||
* @date 2025-03-29
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include "settings/test_settings.h"
|
||||
#include "unit/test_helper/simple_csv_writer.h"
|
||||
#include "unit/test_helper/test_help.h"
|
||||
#include "unit/test_helper/test_tools.h"
|
||||
#include <inspireface/include/inspireface/inspireface.hpp>
|
||||
|
||||
using namespace inspire;
|
||||
|
||||
TEST_CASE("test_SessionFaceTrack", "[session_face_track]") {
|
||||
DRAW_SPLIT_LINE
|
||||
TEST_PRINT_OUTPUT(true);
|
||||
|
||||
SECTION("Face detection from image") {
|
||||
CustomPipelineParameter param;
|
||||
int32_t ret;
|
||||
|
||||
std::shared_ptr<Session> session = std::shared_ptr<Session>(Session::CreatePtr(DetectModuleMode::DETECT_MODE_ALWAYS_DETECT, 3, param));
|
||||
REQUIRE(session != nullptr);
|
||||
|
||||
auto image = inspirecv::Image::Create(GET_DATA("data/bulk/kun.jpg"));
|
||||
auto process = inspirecv::FrameProcess::Create(image, inspirecv::DATA_FORMAT::BGR, inspirecv::ROTATION_MODE::ROTATION_0);
|
||||
|
||||
std::vector<FaceTrackWrap> results;
|
||||
ret = session->FaceDetectAndTrack(process, results);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
REQUIRE(results.size() == 1);
|
||||
}
|
||||
|
||||
SECTION("Head pose estimation") {
|
||||
CustomPipelineParameter param;
|
||||
int32_t ret;
|
||||
|
||||
std::shared_ptr<Session> session = std::shared_ptr<Session>(Session::CreatePtr(DetectModuleMode::DETECT_MODE_ALWAYS_DETECT, 3, param));
|
||||
REQUIRE(session != nullptr);
|
||||
|
||||
HFMultipleFaceData multipleFaceData = {0};
|
||||
std::vector<FaceTrackWrap> results;
|
||||
|
||||
// Left side face
|
||||
HFImageStream leftHandle;
|
||||
auto left = inspirecv::Image::Create(GET_DATA("data/pose/left_face.jpeg"));
|
||||
auto leftProcess = inspirecv::FrameProcess::Create(left, inspirecv::DATA_FORMAT::BGR, inspirecv::ROTATION_MODE::ROTATION_0);
|
||||
|
||||
ret = session->FaceDetectAndTrack(leftProcess, results);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
REQUIRE(results.size() == 1);
|
||||
|
||||
HFloat yaw, pitch, roll;
|
||||
bool checked;
|
||||
|
||||
// Left-handed rotation
|
||||
yaw = results[0].face3DAngle.yaw;
|
||||
checked = (yaw > -90 && yaw < -10);
|
||||
CHECK(checked);
|
||||
|
||||
// Right-handed rotation
|
||||
auto right = inspirecv::Image::Create(GET_DATA("data/pose/right_face.png"));
|
||||
auto rightProcess = inspirecv::FrameProcess::Create(right, inspirecv::DATA_FORMAT::BGR, inspirecv::ROTATION_MODE::ROTATION_0);
|
||||
|
||||
ret = session->FaceDetectAndTrack(rightProcess, results);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
REQUIRE(results.size() == 1);
|
||||
|
||||
yaw = results[0].face3DAngle.yaw;
|
||||
checked = (yaw > 10 && yaw < 90);
|
||||
CHECK(checked);
|
||||
|
||||
// Rise head
|
||||
auto rise = inspirecv::Image::Create(GET_DATA("data/pose/rise_face.jpeg"));
|
||||
auto riseProcess = inspirecv::FrameProcess::Create(rise, inspirecv::DATA_FORMAT::BGR, inspirecv::ROTATION_MODE::ROTATION_0);
|
||||
|
||||
ret = session->FaceDetectAndTrack(riseProcess, results);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
REQUIRE(results.size() == 1);
|
||||
|
||||
pitch = results[0].face3DAngle.pitch;
|
||||
CHECK(pitch > 3);
|
||||
|
||||
// Lower head
|
||||
auto lower = inspirecv::Image::Create(GET_DATA("data/pose/lower_face.jpeg"));
|
||||
auto lowerProcess = inspirecv::FrameProcess::Create(lower, inspirecv::DATA_FORMAT::BGR, inspirecv::ROTATION_MODE::ROTATION_0);
|
||||
|
||||
ret = session->FaceDetectAndTrack(lowerProcess, results);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
REQUIRE(results.size() == 1);
|
||||
|
||||
pitch = results[0].face3DAngle.pitch;
|
||||
CHECK(pitch < -10);
|
||||
|
||||
// Roll head
|
||||
auto leftWryneck = inspirecv::Image::Create(GET_DATA("data/pose/left_wryneck.png"));
|
||||
auto leftWryneckProcess = inspirecv::FrameProcess::Create(leftWryneck, inspirecv::DATA_FORMAT::BGR, inspirecv::ROTATION_MODE::ROTATION_0);
|
||||
|
||||
ret = session->FaceDetectAndTrack(leftWryneckProcess, results);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
REQUIRE(results.size() == 1);
|
||||
|
||||
roll = results[0].face3DAngle.roll;
|
||||
CHECK(roll < -30);
|
||||
|
||||
// Roll head
|
||||
auto rightWryneck = inspirecv::Image::Create(GET_DATA("data/pose/right_wryneck.png"));
|
||||
auto rightWryneckProcess = inspirecv::FrameProcess::Create(rightWryneck, inspirecv::DATA_FORMAT::BGR, inspirecv::ROTATION_MODE::ROTATION_0);
|
||||
|
||||
ret = session->FaceDetectAndTrack(rightWryneckProcess, results);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
REQUIRE(results.size() == 1);
|
||||
|
||||
roll = results[0].face3DAngle.roll;
|
||||
CHECK(roll > 25);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user