mirror of
https://github.com/deepinsight/insightface.git
synced 2026-06-13 01:37:54 +00:00
Update inspireface to 1.2.0
This commit is contained in:
670
cpp-package/inspireface/cpp/test/unit/api/test_benchmark.cpp
Normal file
670
cpp-package/inspireface/cpp/test/unit/api/test_benchmark.cpp
Normal file
@@ -0,0 +1,670 @@
|
||||
/**
|
||||
* Created by Jingyu Yan
|
||||
* @date 2025-01-12
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include "settings/test_settings.h"
|
||||
#include "inspireface/c_api/inspireface.h"
|
||||
#include "unit/test_helper/simple_csv_writer.h"
|
||||
#include "unit/test_helper/test_help.h"
|
||||
#include "unit/test_helper/test_tools.h"
|
||||
#include "middleware/costman.h"
|
||||
|
||||
#ifdef ISF_ENABLE_BENCHMARK
|
||||
|
||||
TEST_CASE("test_BenchmarkFaceDetect", "[benchmark]") {
|
||||
DRAW_SPLIT_LINE
|
||||
TEST_PRINT_OUTPUT(true);
|
||||
|
||||
const int loop = 1000;
|
||||
|
||||
SECTION("Benchmark face detection@160") {
|
||||
auto pixLevel = 160;
|
||||
HResult ret;
|
||||
HFSessionCustomParameter parameter = {0};
|
||||
HFDetectMode detMode = HF_DETECT_MODE_ALWAYS_DETECT;
|
||||
HFSession session;
|
||||
ret = HFCreateInspireFaceSession(parameter, detMode, 3, pixLevel, -1, &session);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
// Get a face picture
|
||||
HFImageStream imgHandle;
|
||||
auto image = inspirecv::Image::Create(GET_DATA("data/bulk/kun.jpg"));
|
||||
ret = CVImageToImageStream(image, imgHandle);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
inspirecv::TimeSpend timeSpend("Face Detect@160");
|
||||
for (size_t i = 0; i < loop; i++) {
|
||||
timeSpend.Start();
|
||||
// Extract basic face information from photos
|
||||
HFMultipleFaceData multipleFaceData = {0};
|
||||
ret = HFExecuteFaceTrack(session, imgHandle, &multipleFaceData);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
REQUIRE(multipleFaceData.detectedNum == 1);
|
||||
timeSpend.Stop();
|
||||
}
|
||||
std::cout << timeSpend << std::endl;
|
||||
|
||||
ret = HFReleaseImageStream(imgHandle);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
ret = HFReleaseInspireFaceSession(session);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
}
|
||||
|
||||
SECTION("Benchmark face detection@320") {
|
||||
auto pixLevel = 320;
|
||||
HResult ret;
|
||||
HFSessionCustomParameter parameter = {0};
|
||||
HFDetectMode detMode = HF_DETECT_MODE_ALWAYS_DETECT;
|
||||
HFSession session;
|
||||
ret = HFCreateInspireFaceSession(parameter, detMode, 3, pixLevel, -1, &session);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
// Get a face picture
|
||||
HFImageStream imgHandle;
|
||||
auto image = inspirecv::Image::Create(GET_DATA("data/bulk/kun.jpg"));
|
||||
ret = CVImageToImageStream(image, imgHandle);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
inspirecv::TimeSpend timeSpend("Face Detect@320");
|
||||
for (size_t i = 0; i < loop; i++) {
|
||||
timeSpend.Start();
|
||||
// Extract basic face information from photos
|
||||
HFMultipleFaceData multipleFaceData = {0};
|
||||
ret = HFExecuteFaceTrack(session, imgHandle, &multipleFaceData);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
REQUIRE(multipleFaceData.detectedNum == 1);
|
||||
timeSpend.Stop();
|
||||
}
|
||||
std::cout << timeSpend << std::endl;
|
||||
|
||||
ret = HFReleaseImageStream(imgHandle);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
ret = HFReleaseInspireFaceSession(session);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
}
|
||||
|
||||
SECTION("Benchmark face detection@640") {
|
||||
auto pixLevel = 640;
|
||||
HResult ret;
|
||||
HFSessionCustomParameter parameter = {0};
|
||||
HFDetectMode detMode = HF_DETECT_MODE_ALWAYS_DETECT;
|
||||
HFSession session;
|
||||
ret = HFCreateInspireFaceSession(parameter, detMode, 3, pixLevel, -1, &session);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
// Get a face picture
|
||||
HFImageStream imgHandle;
|
||||
auto image = inspirecv::Image::Create(GET_DATA("data/bulk/kun.jpg"));
|
||||
ret = CVImageToImageStream(image, imgHandle);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
inspirecv::TimeSpend timeSpend("Face Detect@640");
|
||||
for (size_t i = 0; i < loop; i++) {
|
||||
timeSpend.Start();
|
||||
// Extract basic face information from photos
|
||||
HFMultipleFaceData multipleFaceData = {0};
|
||||
ret = HFExecuteFaceTrack(session, imgHandle, &multipleFaceData);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
REQUIRE(multipleFaceData.detectedNum == 1);
|
||||
timeSpend.Stop();
|
||||
}
|
||||
std::cout << timeSpend << std::endl;
|
||||
|
||||
ret = HFReleaseImageStream(imgHandle);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
ret = HFReleaseInspireFaceSession(session);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("test_BenchmarkFaceTrack", "[benchmark]") {
|
||||
DRAW_SPLIT_LINE
|
||||
TEST_PRINT_OUTPUT(true);
|
||||
|
||||
const int loop = 1000;
|
||||
auto pixLevel = 160;
|
||||
HResult ret;
|
||||
HFSessionCustomParameter parameter = {0};
|
||||
HFDetectMode detMode = HF_DETECT_MODE_LIGHT_TRACK;
|
||||
HFSession session;
|
||||
ret = HFCreateInspireFaceSession(parameter, detMode, 3, pixLevel, -1, &session);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
// Get a face picture
|
||||
HFImageStream imgHandle;
|
||||
auto image = inspirecv::Image::Create(GET_DATA("data/bulk/kun.jpg"));
|
||||
ret = CVImageToImageStream(image, imgHandle);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
inspirecv::TimeSpend timeSpend("Face Track");
|
||||
for (size_t i = 0; i < loop; i++) {
|
||||
timeSpend.Start();
|
||||
// Extract basic face information from photos
|
||||
HFMultipleFaceData multipleFaceData = {0};
|
||||
ret = HFExecuteFaceTrack(session, imgHandle, &multipleFaceData);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
REQUIRE(multipleFaceData.detectedNum == 1);
|
||||
timeSpend.Stop();
|
||||
}
|
||||
std::cout << timeSpend << std::endl;
|
||||
|
||||
ret = HFReleaseImageStream(imgHandle);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
ret = HFReleaseInspireFaceSession(session);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
}
|
||||
|
||||
TEST_CASE("test_BenchmarkFaceExtractWithAlign", "[benchmark]") {
|
||||
DRAW_SPLIT_LINE
|
||||
TEST_PRINT_OUTPUT(true);
|
||||
|
||||
const int loop = 1000;
|
||||
auto pixLevel = 160;
|
||||
HResult ret;
|
||||
HFSessionCustomParameter parameter = {0};
|
||||
HFDetectMode detMode = HF_DETECT_MODE_LIGHT_TRACK;
|
||||
HFSession session;
|
||||
|
||||
ret = HFCreateInspireFaceSessionOptional(HF_ENABLE_FACE_RECOGNITION, detMode, 3, -1, -1, &session);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
// Face track
|
||||
auto dstImage = inspirecv::Image::Create(GET_DATA("data/search/Teresa_Williams_0001_1k.jpg"));
|
||||
|
||||
// Get a face picture
|
||||
HFImageStream imgHandle;
|
||||
ret = CVImageToImageStream(dstImage, imgHandle);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
HFMultipleFaceData multipleFaceData = {0};
|
||||
ret = HFExecuteFaceTrack(session, imgHandle, &multipleFaceData);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
inspirecv::TimeSpend timeSpend("Face Extract With Align");
|
||||
for (size_t i = 0; i < loop; i++) {
|
||||
timeSpend.Start();
|
||||
// Extract basic face information from photos
|
||||
HFMultipleFaceData multipleFaceData = {0};
|
||||
ret = HFExecuteFaceTrack(session, imgHandle, &multipleFaceData);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
timeSpend.Stop();
|
||||
}
|
||||
std::cout << timeSpend << std::endl;
|
||||
|
||||
ret = HFReleaseImageStream(imgHandle);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
ret = HFReleaseInspireFaceSession(session);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
}
|
||||
|
||||
TEST_CASE("test_BenchmarkFaceComparison", "[benchmark]") {
|
||||
DRAW_SPLIT_LINE
|
||||
TEST_PRINT_OUTPUT(true);
|
||||
|
||||
int loop = 1000;
|
||||
HResult ret;
|
||||
HFSessionCustomParameter parameter = {0};
|
||||
parameter.enable_recognition = 1;
|
||||
HFDetectMode detMode = HF_DETECT_MODE_ALWAYS_DETECT;
|
||||
HFSession session;
|
||||
ret = HFCreateInspireFaceSession(parameter, detMode, 3, -1, -1, &session);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
auto image = inspirecv::Image::Create(GET_DATA("data/bulk/woman.png"));
|
||||
HFImageStream imgHandle;
|
||||
ret = CVImageToImageStream(image, imgHandle);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
// Extract basic face information from photos
|
||||
HFMultipleFaceData multipleFaceDataZy = {0};
|
||||
ret = HFExecuteFaceTrack(session, imgHandle, &multipleFaceDataZy);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
REQUIRE(multipleFaceDataZy.detectedNum > 0);
|
||||
|
||||
HInt32 featureNum;
|
||||
HFGetFeatureLength(&featureNum);
|
||||
|
||||
// Extract face feature
|
||||
HFloat featureCacheZy[featureNum];
|
||||
ret = HFFaceFeatureExtractCpy(session, imgHandle, multipleFaceDataZy.tokens[0], featureCacheZy);
|
||||
HFFaceFeature featureZy = {0};
|
||||
featureZy.size = featureNum;
|
||||
featureZy.data = featureCacheZy;
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
auto imageQuery = inspirecv::Image::Create(GET_DATA("data/bulk/woman_search.jpeg"));
|
||||
HFImageStream imgHandleQuery;
|
||||
ret = CVImageToImageStream(imageQuery, imgHandleQuery);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
HFMultipleFaceData multipleFaceDataQuery = {0};
|
||||
ret = HFExecuteFaceTrack(session, imgHandleQuery, &multipleFaceDataQuery);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
REQUIRE(multipleFaceDataQuery.detectedNum > 0);
|
||||
|
||||
// Extract face feature
|
||||
HFloat featureCacheZyQuery[featureNum];
|
||||
ret = HFFaceFeatureExtractCpy(session, imgHandleQuery, multipleFaceDataQuery.tokens[0], featureCacheZyQuery);
|
||||
HFFaceFeature featureZyQuery = {0};
|
||||
featureZyQuery.data = featureCacheZyQuery;
|
||||
featureZyQuery.size = featureNum;
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
inspirecv::TimeSpend timeSpend("Face Comparison");
|
||||
for (int i = 0; i < loop; ++i) {
|
||||
timeSpend.Start();
|
||||
HFloat compRes;
|
||||
ret = HFFaceComparison(featureZy, featureZyQuery, &compRes);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
timeSpend.Stop();
|
||||
}
|
||||
std::cout << timeSpend << std::endl;
|
||||
|
||||
ret = HFReleaseImageStream(imgHandle);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
ret = HFReleaseImageStream(imgHandleQuery);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
// Finish
|
||||
ret = HFReleaseInspireFaceSession(session);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
}
|
||||
|
||||
TEST_CASE("test_BenchmarkFaceHubSearchPersistence", "[benchmark]") {
|
||||
DRAW_SPLIT_LINE
|
||||
TEST_PRINT_OUTPUT(true);
|
||||
|
||||
SECTION("Benchmark search 1k@Persistence") {
|
||||
const int loop = 1000;
|
||||
HResult ret;
|
||||
HFFeatureHubConfiguration configuration;
|
||||
auto dbPath = GET_SAVE_DATA(".test");
|
||||
HString dbPathStr = new char[dbPath.size() + 1];
|
||||
std::strcpy(dbPathStr, dbPath.c_str());
|
||||
configuration.primaryKeyMode = HF_PK_AUTO_INCREMENT;
|
||||
configuration.enablePersistence = 1;
|
||||
configuration.persistenceDbPath = dbPathStr;
|
||||
configuration.searchMode = HF_SEARCH_MODE_EXHAUSTIVE;
|
||||
configuration.searchThreshold = 0.48f;
|
||||
// Delete the previous data before testing
|
||||
if (std::remove(configuration.persistenceDbPath) != 0) {
|
||||
spdlog::trace("Error deleting file");
|
||||
}
|
||||
ret = HFFeatureHubDataEnable(configuration);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
std::vector<std::vector<HFloat>> baseFeatures;
|
||||
size_t genSizeOfBase = 1000;
|
||||
HInt32 featureLength;
|
||||
HFGetFeatureLength(&featureLength);
|
||||
REQUIRE(featureLength > 0);
|
||||
for (int i = 0; i < genSizeOfBase; ++i) {
|
||||
auto feat = GenerateRandomFeature(featureLength);
|
||||
baseFeatures.push_back(feat);
|
||||
// Construct face feature
|
||||
HFFaceFeature feature = {0};
|
||||
feature.size = feat.size();
|
||||
feature.data = feat.data();
|
||||
HFFaceFeatureIdentity identity = {0};
|
||||
identity.feature = &feature;
|
||||
HFaceId allocId;
|
||||
ret = HFFeatureHubInsertFeature(identity, &allocId);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
}
|
||||
HInt32 totalFace;
|
||||
ret = HFFeatureHubGetFaceCount(&totalFace);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
REQUIRE(totalFace == genSizeOfBase);
|
||||
|
||||
HInt32 targetId = 800;
|
||||
auto targetFeature = baseFeatures[targetId - 1];
|
||||
|
||||
auto searchFeat = SimulateSimilarVector(targetFeature);
|
||||
HFFaceFeature searchFeature = {0};
|
||||
searchFeature.size = searchFeat.size();
|
||||
searchFeature.data = searchFeat.data();
|
||||
HFloat confidence = 0.0f;
|
||||
HFFaceFeatureIdentity mostSimilar = {0};
|
||||
inspirecv::TimeSpend timeSpend("Face Search 1k@Persistence");
|
||||
for (size_t i = 0; i < loop; i++) {
|
||||
timeSpend.Start();
|
||||
ret = HFFeatureHubFaceSearch(searchFeature, &confidence, &mostSimilar);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
REQUIRE(mostSimilar.id == targetId);
|
||||
REQUIRE(confidence > 0.88f);
|
||||
timeSpend.Stop();
|
||||
}
|
||||
std::cout << timeSpend << std::endl;
|
||||
|
||||
ret = HFFeatureHubDataDisable();
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
delete[] dbPathStr;
|
||||
}
|
||||
|
||||
SECTION("Benchmark search 5k@Persistence") {
|
||||
const int loop = 1000;
|
||||
HResult ret;
|
||||
HFFeatureHubConfiguration configuration;
|
||||
auto dbPath = GET_SAVE_DATA(".test");
|
||||
HString dbPathStr = new char[dbPath.size() + 1];
|
||||
std::strcpy(dbPathStr, dbPath.c_str());
|
||||
configuration.primaryKeyMode = HF_PK_AUTO_INCREMENT;
|
||||
configuration.enablePersistence = 1;
|
||||
configuration.persistenceDbPath = dbPathStr;
|
||||
configuration.searchMode = HF_SEARCH_MODE_EXHAUSTIVE;
|
||||
configuration.searchThreshold = 0.48f;
|
||||
// Delete the previous data before testing
|
||||
if (std::remove(configuration.persistenceDbPath) != 0) {
|
||||
spdlog::trace("Error deleting file");
|
||||
}
|
||||
ret = HFFeatureHubDataEnable(configuration);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
std::vector<std::vector<HFloat>> baseFeatures;
|
||||
size_t genSizeOfBase = 5000;
|
||||
HInt32 featureLength;
|
||||
HFGetFeatureLength(&featureLength);
|
||||
REQUIRE(featureLength > 0);
|
||||
for (int i = 0; i < genSizeOfBase; ++i) {
|
||||
auto feat = GenerateRandomFeature(featureLength);
|
||||
baseFeatures.push_back(feat);
|
||||
// Construct face feature
|
||||
HFFaceFeature feature = {0};
|
||||
feature.size = feat.size();
|
||||
feature.data = feat.data();
|
||||
HFFaceFeatureIdentity identity = {0};
|
||||
identity.feature = &feature;
|
||||
HFaceId allocId;
|
||||
ret = HFFeatureHubInsertFeature(identity, &allocId);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
}
|
||||
HInt32 totalFace;
|
||||
ret = HFFeatureHubGetFaceCount(&totalFace);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
REQUIRE(totalFace == genSizeOfBase);
|
||||
|
||||
HInt32 targetId = 4800;
|
||||
auto targetFeature = baseFeatures[targetId - 1];
|
||||
|
||||
auto searchFeat = SimulateSimilarVector(targetFeature);
|
||||
HFFaceFeature searchFeature = {0};
|
||||
searchFeature.size = searchFeat.size();
|
||||
searchFeature.data = searchFeat.data();
|
||||
HFloat confidence = 0.0f;
|
||||
HFFaceFeatureIdentity mostSimilar = {0};
|
||||
inspirecv::TimeSpend timeSpend("Face Search 5k@Persistence");
|
||||
for (size_t i = 0; i < loop; i++) {
|
||||
timeSpend.Start();
|
||||
ret = HFFeatureHubFaceSearch(searchFeature, &confidence, &mostSimilar);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
REQUIRE(mostSimilar.id == targetId);
|
||||
REQUIRE(confidence > 0.88f);
|
||||
timeSpend.Stop();
|
||||
}
|
||||
std::cout << timeSpend << std::endl;
|
||||
|
||||
ret = HFFeatureHubDataDisable();
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
delete[] dbPathStr;
|
||||
}
|
||||
|
||||
SECTION("Benchmark search 10k@Persistence") {
|
||||
const int loop = 1000;
|
||||
HResult ret;
|
||||
HFFeatureHubConfiguration configuration;
|
||||
auto dbPath = GET_SAVE_DATA(".test");
|
||||
HString dbPathStr = new char[dbPath.size() + 1];
|
||||
std::strcpy(dbPathStr, dbPath.c_str());
|
||||
configuration.primaryKeyMode = HF_PK_AUTO_INCREMENT;
|
||||
configuration.enablePersistence = 1;
|
||||
configuration.persistenceDbPath = dbPathStr;
|
||||
configuration.searchMode = HF_SEARCH_MODE_EXHAUSTIVE;
|
||||
configuration.searchThreshold = 0.48f;
|
||||
// Delete the previous data before testing
|
||||
if (std::remove(configuration.persistenceDbPath) != 0) {
|
||||
spdlog::trace("Error deleting file");
|
||||
}
|
||||
ret = HFFeatureHubDataEnable(configuration);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
std::vector<std::vector<HFloat>> baseFeatures;
|
||||
size_t genSizeOfBase = 10000;
|
||||
HInt32 featureLength;
|
||||
HFGetFeatureLength(&featureLength);
|
||||
REQUIRE(featureLength > 0);
|
||||
for (int i = 0; i < genSizeOfBase; ++i) {
|
||||
auto feat = GenerateRandomFeature(featureLength);
|
||||
baseFeatures.push_back(feat);
|
||||
// Construct face feature
|
||||
HFFaceFeature feature = {0};
|
||||
feature.size = feat.size();
|
||||
feature.data = feat.data();
|
||||
HFFaceFeatureIdentity identity = {0};
|
||||
identity.feature = &feature;
|
||||
HFaceId allocId;
|
||||
ret = HFFeatureHubInsertFeature(identity, &allocId);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
}
|
||||
HInt32 totalFace;
|
||||
ret = HFFeatureHubGetFaceCount(&totalFace);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
REQUIRE(totalFace == genSizeOfBase);
|
||||
|
||||
HInt32 targetId = 9800;
|
||||
auto targetFeature = baseFeatures[targetId - 1];
|
||||
|
||||
auto searchFeat = SimulateSimilarVector(targetFeature);
|
||||
HFFaceFeature searchFeature = {0};
|
||||
searchFeature.size = searchFeat.size();
|
||||
searchFeature.data = searchFeat.data();
|
||||
HFloat confidence = 0.0f;
|
||||
HFFaceFeatureIdentity mostSimilar = {0};
|
||||
inspirecv::TimeSpend timeSpend("Face Search 10k@Persistence");
|
||||
for (size_t i = 0; i < loop; i++) {
|
||||
timeSpend.Start();
|
||||
ret = HFFeatureHubFaceSearch(searchFeature, &confidence, &mostSimilar);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
REQUIRE(mostSimilar.id == targetId);
|
||||
REQUIRE(confidence > 0.88f);
|
||||
timeSpend.Stop();
|
||||
}
|
||||
std::cout << timeSpend << std::endl;
|
||||
|
||||
ret = HFFeatureHubDataDisable();
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
delete[] dbPathStr;
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("test_BenchmarkFaceHubSearchMemory", "[benchmark]") {
|
||||
DRAW_SPLIT_LINE
|
||||
TEST_PRINT_OUTPUT(true);
|
||||
|
||||
SECTION("Benchmark search 1k@Memory") {
|
||||
const int loop = 1000;
|
||||
HResult ret;
|
||||
HFFeatureHubConfiguration configuration;
|
||||
configuration.primaryKeyMode = HF_PK_AUTO_INCREMENT;
|
||||
configuration.enablePersistence = 0;
|
||||
configuration.searchMode = HF_SEARCH_MODE_EXHAUSTIVE;
|
||||
configuration.searchThreshold = 0.48f;
|
||||
ret = HFFeatureHubDataEnable(configuration);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
std::vector<std::vector<HFloat>> baseFeatures;
|
||||
size_t genSizeOfBase = 1000;
|
||||
HInt32 featureLength;
|
||||
HFGetFeatureLength(&featureLength);
|
||||
REQUIRE(featureLength > 0);
|
||||
for (int i = 0; i < genSizeOfBase; ++i) {
|
||||
auto feat = GenerateRandomFeature(featureLength);
|
||||
baseFeatures.push_back(feat);
|
||||
// Construct face feature
|
||||
HFFaceFeature feature = {0};
|
||||
feature.size = feat.size();
|
||||
feature.data = feat.data();
|
||||
HFFaceFeatureIdentity identity = {0};
|
||||
identity.feature = &feature;
|
||||
HFaceId allocId;
|
||||
ret = HFFeatureHubInsertFeature(identity, &allocId);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
}
|
||||
HInt32 totalFace;
|
||||
ret = HFFeatureHubGetFaceCount(&totalFace);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
REQUIRE(totalFace == genSizeOfBase);
|
||||
|
||||
HInt32 targetId = 800;
|
||||
auto targetFeature = baseFeatures[targetId - 1];
|
||||
|
||||
auto searchFeat = SimulateSimilarVector(targetFeature);
|
||||
HFFaceFeature searchFeature = {0};
|
||||
searchFeature.size = searchFeat.size();
|
||||
searchFeature.data = searchFeat.data();
|
||||
HFloat confidence = 0.0f;
|
||||
HFFaceFeatureIdentity mostSimilar = {0};
|
||||
inspirecv::TimeSpend timeSpend("Face Search 1k@Memory");
|
||||
for (size_t i = 0; i < loop; i++) {
|
||||
timeSpend.Start();
|
||||
ret = HFFeatureHubFaceSearch(searchFeature, &confidence, &mostSimilar);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
REQUIRE(mostSimilar.id == targetId);
|
||||
REQUIRE(confidence > 0.88f);
|
||||
timeSpend.Stop();
|
||||
}
|
||||
std::cout << timeSpend << std::endl;
|
||||
|
||||
ret = HFFeatureHubDataDisable();
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
}
|
||||
|
||||
SECTION("Benchmark search 5k@Persistence") {
|
||||
const int loop = 1000;
|
||||
HResult ret;
|
||||
HFFeatureHubConfiguration configuration;
|
||||
configuration.primaryKeyMode = HF_PK_AUTO_INCREMENT;
|
||||
configuration.enablePersistence = 0;
|
||||
configuration.searchMode = HF_SEARCH_MODE_EXHAUSTIVE;
|
||||
configuration.searchThreshold = 0.48f;
|
||||
ret = HFFeatureHubDataEnable(configuration);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
std::vector<std::vector<HFloat>> baseFeatures;
|
||||
size_t genSizeOfBase = 5000;
|
||||
HInt32 featureLength;
|
||||
HFGetFeatureLength(&featureLength);
|
||||
REQUIRE(featureLength > 0);
|
||||
for (int i = 0; i < genSizeOfBase; ++i) {
|
||||
auto feat = GenerateRandomFeature(featureLength);
|
||||
baseFeatures.push_back(feat);
|
||||
// Construct face feature
|
||||
HFFaceFeature feature = {0};
|
||||
feature.size = feat.size();
|
||||
feature.data = feat.data();
|
||||
HFFaceFeatureIdentity identity = {0};
|
||||
identity.feature = &feature;
|
||||
HFaceId allocId;
|
||||
ret = HFFeatureHubInsertFeature(identity, &allocId);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
}
|
||||
HInt32 totalFace;
|
||||
ret = HFFeatureHubGetFaceCount(&totalFace);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
REQUIRE(totalFace == genSizeOfBase);
|
||||
|
||||
HInt32 targetId = 4800;
|
||||
auto targetFeature = baseFeatures[targetId - 1];
|
||||
|
||||
auto searchFeat = SimulateSimilarVector(targetFeature);
|
||||
HFFaceFeature searchFeature = {0};
|
||||
searchFeature.size = searchFeat.size();
|
||||
searchFeature.data = searchFeat.data();
|
||||
HFloat confidence = 0.0f;
|
||||
HFFaceFeatureIdentity mostSimilar = {0};
|
||||
inspirecv::TimeSpend timeSpend("Face Search 5k@Memory");
|
||||
for (size_t i = 0; i < loop; i++) {
|
||||
timeSpend.Start();
|
||||
ret = HFFeatureHubFaceSearch(searchFeature, &confidence, &mostSimilar);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
REQUIRE(mostSimilar.id == targetId);
|
||||
REQUIRE(confidence > 0.88f);
|
||||
timeSpend.Stop();
|
||||
}
|
||||
std::cout << timeSpend << std::endl;
|
||||
|
||||
ret = HFFeatureHubDataDisable();
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
}
|
||||
|
||||
SECTION("Benchmark search 10k@Persistence") {
|
||||
const int loop = 1000;
|
||||
HResult ret;
|
||||
HFFeatureHubConfiguration configuration;
|
||||
configuration.primaryKeyMode = HF_PK_AUTO_INCREMENT;
|
||||
configuration.enablePersistence = 0;
|
||||
configuration.searchMode = HF_SEARCH_MODE_EXHAUSTIVE;
|
||||
configuration.searchThreshold = 0.48f;
|
||||
|
||||
ret = HFFeatureHubDataEnable(configuration);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
std::vector<std::vector<HFloat>> baseFeatures;
|
||||
size_t genSizeOfBase = 10000;
|
||||
HInt32 featureLength;
|
||||
HFGetFeatureLength(&featureLength);
|
||||
REQUIRE(featureLength > 0);
|
||||
for (int i = 0; i < genSizeOfBase; ++i) {
|
||||
auto feat = GenerateRandomFeature(featureLength);
|
||||
baseFeatures.push_back(feat);
|
||||
// Construct face feature
|
||||
HFFaceFeature feature = {0};
|
||||
feature.size = feat.size();
|
||||
feature.data = feat.data();
|
||||
HFFaceFeatureIdentity identity = {0};
|
||||
identity.feature = &feature;
|
||||
HFaceId allocId;
|
||||
ret = HFFeatureHubInsertFeature(identity, &allocId);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
}
|
||||
HInt32 totalFace;
|
||||
ret = HFFeatureHubGetFaceCount(&totalFace);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
REQUIRE(totalFace == genSizeOfBase);
|
||||
|
||||
HInt32 targetId = 9800;
|
||||
auto targetFeature = baseFeatures[targetId - 1];
|
||||
|
||||
auto searchFeat = SimulateSimilarVector(targetFeature);
|
||||
HFFaceFeature searchFeature = {0};
|
||||
searchFeature.size = searchFeat.size();
|
||||
searchFeature.data = searchFeat.data();
|
||||
HFloat confidence = 0.0f;
|
||||
HFFaceFeatureIdentity mostSimilar = {0};
|
||||
inspirecv::TimeSpend timeSpend("Face Search 10k@Memory");
|
||||
for (size_t i = 0; i < loop; i++) {
|
||||
timeSpend.Start();
|
||||
ret = HFFeatureHubFaceSearch(searchFeature, &confidence, &mostSimilar);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
REQUIRE(mostSimilar.id == targetId);
|
||||
REQUIRE(confidence > 0.88f);
|
||||
timeSpend.Stop();
|
||||
}
|
||||
std::cout << timeSpend << std::endl;
|
||||
|
||||
ret = HFFeatureHubDataDisable();
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,11 +1,10 @@
|
||||
//
|
||||
// Created by Tunm-Air13 on 2024/3/26.
|
||||
//
|
||||
|
||||
/**
|
||||
* Created by Jingyu Yan
|
||||
* @date 2024-10-01
|
||||
*/
|
||||
#include <iostream>
|
||||
#include "settings/test_settings.h"
|
||||
#include "inspireface/c_api/inspireface.h"
|
||||
#include "opencv2/opencv.hpp"
|
||||
#include "unit/test_helper/simple_csv_writer.h"
|
||||
#include "unit/test_helper/test_help.h"
|
||||
#include "unit/test_helper/test_tools.h"
|
||||
@@ -24,24 +23,15 @@ TEST_CASE("test_Evaluation", "[face_evaluation") {
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
float mostSim = -1.0f;
|
||||
auto succ = FindMostSimilarScoreFromTwoPic(session,
|
||||
GET_DATA("data/bulk/jntm.jpg"),
|
||||
GET_DATA("data/bulk/kun.jpg"),
|
||||
mostSim);
|
||||
auto succ = FindMostSimilarScoreFromTwoPic(session, GET_DATA("data/bulk/jntm.jpg"), GET_DATA("data/bulk/kun.jpg"), mostSim);
|
||||
CHECK(succ);
|
||||
TEST_PRINT("kun v kun :{}", mostSim);
|
||||
|
||||
succ = FindMostSimilarScoreFromTwoPic(session,
|
||||
GET_DATA("data/bulk/jntm.jpg"),
|
||||
GET_DATA("data/bulk/Rob_Lowe_0001.jpg"),
|
||||
mostSim);
|
||||
succ = FindMostSimilarScoreFromTwoPic(session, GET_DATA("data/bulk/jntm.jpg"), GET_DATA("data/bulk/Rob_Lowe_0001.jpg"), mostSim);
|
||||
CHECK(succ);
|
||||
TEST_PRINT("kun v other :{}", mostSim);
|
||||
|
||||
succ = FindMostSimilarScoreFromTwoPic(session,
|
||||
GET_DATA("data/bulk/kun.jpg"),
|
||||
GET_DATA("data/bulk/view.jpg"),
|
||||
mostSim);
|
||||
succ = FindMostSimilarScoreFromTwoPic(session, GET_DATA("data/bulk/kun.jpg"), GET_DATA("data/bulk/view.jpg"), mostSim);
|
||||
CHECK(!succ);
|
||||
TEST_PRINT("kun v other :{}", mostSim);
|
||||
|
||||
@@ -50,7 +40,6 @@ TEST_CASE("test_Evaluation", "[face_evaluation") {
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
}
|
||||
|
||||
|
||||
SECTION("Test LFW evaluation") {
|
||||
#ifdef ISF_ENABLE_TEST_EVALUATION
|
||||
HResult ret;
|
||||
@@ -65,14 +54,12 @@ TEST_CASE("test_Evaluation", "[face_evaluation") {
|
||||
auto pairs = ReadPairs(getTestLFWFunneledEvaTxt());
|
||||
// Hide cursor
|
||||
show_console_cursor(false);
|
||||
BlockProgressBar bar{
|
||||
option::BarWidth{60},
|
||||
option::Start{"["},
|
||||
option::End{"]"},
|
||||
option::PostfixText{"Extracting face features"},
|
||||
option::ForegroundColor{Color::white} ,
|
||||
option::FontStyles{std::vector<FontStyle>{FontStyle::bold}}
|
||||
};
|
||||
BlockProgressBar bar{option::BarWidth{60},
|
||||
option::Start{"["},
|
||||
option::End{"]"},
|
||||
option::PostfixText{"Extracting face features"},
|
||||
option::ForegroundColor{Color::white},
|
||||
option::FontStyles{std::vector<FontStyle>{FontStyle::bold}}};
|
||||
auto progress = 0.0f;
|
||||
|
||||
for (int i = 0; i < pairs.size(); ++i) {
|
||||
@@ -87,20 +74,16 @@ TEST_CASE("test_Evaluation", "[face_evaluation") {
|
||||
person1 = pair[0];
|
||||
imgNum1 = std::stoi(pair[1]);
|
||||
imgNum2 = std::stoi(pair[2]);
|
||||
imgPath1 = PathJoin(PathJoin(getLFWFunneledDir(), person1),
|
||||
person1 + "_" + zfill(imgNum1, 4) + ".jpg");
|
||||
imgPath2 = PathJoin(PathJoin(getLFWFunneledDir(), person1),
|
||||
person1 + "_" + zfill(imgNum2, 4) + ".jpg");
|
||||
imgPath1 = PathJoin(PathJoin(getLFWFunneledDir(), person1), person1 + "_" + zfill(imgNum1, 4) + ".jpg");
|
||||
imgPath2 = PathJoin(PathJoin(getLFWFunneledDir(), person1), person1 + "_" + zfill(imgNum2, 4) + ".jpg");
|
||||
match = 1;
|
||||
} else {
|
||||
person1 = pair[0];
|
||||
imgNum1 = std::stoi(pair[1]);
|
||||
person2 = pair[2];
|
||||
imgNum2 = std::stoi(pair[3]);
|
||||
imgPath1 = PathJoin(PathJoin(getLFWFunneledDir(), person1),
|
||||
person1 + "_" + zfill(imgNum1, 4) + ".jpg");
|
||||
imgPath2 = PathJoin(PathJoin(getLFWFunneledDir(), person2),
|
||||
person2 + "_" + zfill(imgNum2, 4) + ".jpg");
|
||||
imgPath1 = PathJoin(PathJoin(getLFWFunneledDir(), person1), person1 + "_" + zfill(imgNum1, 4) + ".jpg");
|
||||
imgPath2 = PathJoin(PathJoin(getLFWFunneledDir(), person2), person2 + "_" + zfill(imgNum2, 4) + ".jpg");
|
||||
match = 0;
|
||||
}
|
||||
|
||||
@@ -132,5 +115,4 @@ TEST_CASE("test_Evaluation", "[face_evaluation") {
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
//
|
||||
// Created by tunm on 2023/10/11.
|
||||
//
|
||||
/**
|
||||
* Created by Jingyu Yan
|
||||
* @date 2024-10-01
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include "settings/test_settings.h"
|
||||
@@ -21,6 +22,4 @@ TEST_CASE("test_FeatureContext", "[face_context]") {
|
||||
ret = HFReleaseInspireFaceSession(session);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,11 +1,12 @@
|
||||
//
|
||||
// Created by tunm on 2023/10/12.
|
||||
//
|
||||
|
||||
/**
|
||||
* Created by Jingyu Yan
|
||||
* @date 2024-10-01
|
||||
*/
|
||||
#include <iostream>
|
||||
#include "settings/test_settings.h"
|
||||
#include "inspireface/c_api/inspireface.h"
|
||||
#include "../test_helper/test_tools.h"
|
||||
#include "../test_helper/test_help.h"
|
||||
|
||||
TEST_CASE("test_FacePipelineAttribute", "[face_pipeline_attribute]") {
|
||||
DRAW_SPLIT_LINE
|
||||
@@ -39,14 +40,14 @@ TEST_CASE("test_FacePipelineAttribute", "[face_pipeline_attribute]") {
|
||||
parameter.enable_face_attribute = 1;
|
||||
HFDetectMode detMode = HF_DETECT_MODE_ALWAYS_DETECT;
|
||||
HFSession session;
|
||||
HInt32 faceDetectPixelLevel = 160;
|
||||
HInt32 faceDetectPixelLevel = 320;
|
||||
ret = HFCreateInspireFaceSession(parameter, detMode, 5, faceDetectPixelLevel, -1, &session);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
SECTION("a black girl") {
|
||||
HFImageStream imgHandle;
|
||||
auto img = cv::imread(GET_DATA("data/attribute/1423.jpg"));
|
||||
REQUIRE(!img.empty());
|
||||
auto img = inspirecv::Image::Create(GET_DATA("data/attribute/1423.jpg"));
|
||||
REQUIRE(!img.Empty());
|
||||
ret = CVImageToImageStream(img, imgHandle);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
@@ -56,8 +57,7 @@ TEST_CASE("test_FacePipelineAttribute", "[face_pipeline_attribute]") {
|
||||
REQUIRE(multipleFaceData.detectedNum == 1);
|
||||
|
||||
// Run pipeline
|
||||
ret = HFMultipleFacePipelineProcessOptional(session, imgHandle, &multipleFaceData,
|
||||
HF_ENABLE_FACE_ATTRIBUTE);
|
||||
ret = HFMultipleFacePipelineProcessOptional(session, imgHandle, &multipleFaceData, HF_ENABLE_FACE_ATTRIBUTE);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
HFFaceAttributeResult result = {0};
|
||||
@@ -77,8 +77,8 @@ TEST_CASE("test_FacePipelineAttribute", "[face_pipeline_attribute]") {
|
||||
|
||||
SECTION("two young white women") {
|
||||
HFImageStream imgHandle;
|
||||
auto img = cv::imread(GET_DATA("data/attribute/7242.jpg"));
|
||||
REQUIRE(!img.empty());
|
||||
auto img = inspirecv::Image::Create(GET_DATA("data/attribute/7242.jpg"));
|
||||
REQUIRE(!img.Empty());
|
||||
ret = CVImageToImageStream(img, imgHandle);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
@@ -88,8 +88,7 @@ TEST_CASE("test_FacePipelineAttribute", "[face_pipeline_attribute]") {
|
||||
REQUIRE(multipleFaceData.detectedNum == 2);
|
||||
|
||||
// Run pipeline
|
||||
ret = HFMultipleFacePipelineProcessOptional(session, imgHandle, &multipleFaceData,
|
||||
HF_ENABLE_FACE_ATTRIBUTE);
|
||||
ret = HFMultipleFacePipelineProcessOptional(session, imgHandle, &multipleFaceData, HF_ENABLE_FACE_ATTRIBUTE);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
HFFaceAttributeResult result = {0};
|
||||
@@ -114,65 +113,24 @@ TEST_CASE("test_FacePipelineAttribute", "[face_pipeline_attribute]") {
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
}
|
||||
|
||||
TEST_CASE("test_FacePipelineRobustness", "[robustness]") {
|
||||
DRAW_SPLIT_LINE
|
||||
TEST_PRINT_OUTPUT(true);
|
||||
|
||||
SECTION("Exception") {
|
||||
HResult ret;
|
||||
HFSessionCustomParameter parameter = {0};
|
||||
HFDetectMode detMode = HF_DETECT_MODE_ALWAYS_DETECT;
|
||||
HFSession session;
|
||||
ret = HFCreateInspireFaceSession(parameter, detMode, 3, -1, -1, &session);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
// Input exception data
|
||||
HFImageStream nullHandle = {0};
|
||||
HFMultipleFaceData nullfaces = {0};
|
||||
ret =
|
||||
HFMultipleFacePipelineProcessOptional(session, nullHandle, &nullfaces, HF_ENABLE_NONE);
|
||||
REQUIRE(ret == HERR_INVALID_IMAGE_STREAM_HANDLE);
|
||||
|
||||
// Get a face picture
|
||||
HFImageStream img1Handle;
|
||||
auto img1 = cv::imread(GET_DATA("data/bulk/image_T1.jpeg"));
|
||||
ret = CVImageToImageStream(img1, img1Handle);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
// Input correct Image and exception faces struct
|
||||
ret =
|
||||
HFMultipleFacePipelineProcessOptional(session, img1Handle, &nullfaces, HF_ENABLE_NONE);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
ret = HFReleaseImageStream(img1Handle);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
ret = HFReleaseInspireFaceSession(session);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
// Multiple release
|
||||
ret = HFReleaseInspireFaceSession(session);
|
||||
REQUIRE(ret == HERR_INVALID_CONTEXT_HANDLE);
|
||||
|
||||
HFDeBugShowResourceStatistics();
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("test_FacePipeline", "[face_pipeline]") {
|
||||
DRAW_SPLIT_LINE
|
||||
TEST_PRINT_OUTPUT(true);
|
||||
|
||||
SECTION("rgb liveness detect") {
|
||||
#ifndef INFERENCE_WRAPPER_ENABLE_RKNN2
|
||||
/** The anti spoofing model based on RGB faces seems to have some problems with quantization under RKNPU2, so it is not started yet */
|
||||
HResult ret;
|
||||
HFSessionCustomParameter parameter = {0};
|
||||
parameter.enable_liveness = 1;
|
||||
HFDetectMode detMode = HF_DETECT_MODE_ALWAYS_DETECT;
|
||||
HFSession session;
|
||||
ret = HFCreateInspireFaceSession(parameter, detMode, 3, -1, -1, &session);
|
||||
ret = HFCreateInspireFaceSession(parameter, detMode, 3, 320, -1, &session);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
// Get a face picture
|
||||
HFImageStream img1Handle;
|
||||
auto img1 = cv::imread(GET_DATA("data/bulk/image_T1.jpeg"));
|
||||
auto img1 = inspirecv::Image::Create(GET_DATA("data/bulk/image_T1.jpeg"));
|
||||
ret = CVImageToImageStream(img1, img1Handle);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
@@ -189,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.9);
|
||||
CHECK(confidence.confidence[0] > 0.8);
|
||||
|
||||
ret = HFReleaseImageStream(img1Handle);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
@@ -197,7 +155,7 @@ TEST_CASE("test_FacePipeline", "[face_pipeline]") {
|
||||
|
||||
// fake face
|
||||
HFImageStream img2Handle;
|
||||
auto img2 = cv::imread(GET_DATA("data/bulk/rgb_fake.jpg"));
|
||||
auto img2 = inspirecv::Image::Create(GET_DATA("data/bulk/rgb_fake.jpg"));
|
||||
ret = CVImageToImageStream(img2, img2Handle);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
ret = HFExecuteFaceTrack(session, img2Handle, &multipleFaceData);
|
||||
@@ -216,6 +174,9 @@ TEST_CASE("test_FacePipeline", "[face_pipeline]") {
|
||||
ret = HFReleaseInspireFaceSession(session);
|
||||
session = nullptr;
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
#else
|
||||
TEST_PRINT("The anti spoofing model based on RGB faces seems to have some problems with quantization under RKNPU2, so we skip this test.");
|
||||
#endif
|
||||
}
|
||||
|
||||
SECTION("face mask detect") {
|
||||
@@ -229,7 +190,7 @@ TEST_CASE("test_FacePipeline", "[face_pipeline]") {
|
||||
|
||||
// Get a face picture
|
||||
HFImageStream img1Handle;
|
||||
auto img1 = cv::imread(GET_DATA("data/bulk/mask2.jpg"));
|
||||
auto img1 = inspirecv::Image::Create(GET_DATA("data/bulk/mask2.jpg"));
|
||||
ret = CVImageToImageStream(img1, img1Handle);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
@@ -253,7 +214,7 @@ TEST_CASE("test_FacePipeline", "[face_pipeline]") {
|
||||
|
||||
// no mask face
|
||||
HFImageStream img2Handle;
|
||||
auto img2 = cv::imread(GET_DATA("data/bulk/face_sample.png"));
|
||||
auto img2 = inspirecv::Image::Create(GET_DATA("data/bulk/face_sample.png"));
|
||||
ret = CVImageToImageStream(img2, img2Handle);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
ret = HFExecuteFaceTrack(session, img2Handle, &multipleFaceData);
|
||||
@@ -280,12 +241,12 @@ TEST_CASE("test_FacePipeline", "[face_pipeline]") {
|
||||
HFDetectMode detMode = HF_DETECT_MODE_ALWAYS_DETECT;
|
||||
HInt32 option = HF_ENABLE_QUALITY;
|
||||
HFSession session;
|
||||
ret = HFCreateInspireFaceSessionOptional(option, detMode, 3, -1, -1, &session);
|
||||
ret = HFCreateInspireFaceSessionOptional(option, detMode, 3, 320, -1, &session);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
// Get a face picture
|
||||
HFImageStream superiorHandle;
|
||||
auto superior = cv::imread(GET_DATA("data/bulk/yifei.jpg"));
|
||||
auto superior = inspirecv::Image::Create(GET_DATA("data/bulk/yifei.jpg"));
|
||||
ret = CVImageToImageStream(superior, superiorHandle);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
@@ -295,18 +256,17 @@ TEST_CASE("test_FacePipeline", "[face_pipeline]") {
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
REQUIRE(multipleFaceData.detectedNum > 0);
|
||||
|
||||
ret =
|
||||
HFMultipleFacePipelineProcessOptional(session, superiorHandle, &multipleFaceData, option);
|
||||
ret = HFMultipleFacePipelineProcessOptional(session, superiorHandle, &multipleFaceData, option);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
HFloat quality;
|
||||
ret = HFFaceQualityDetect(session, multipleFaceData.tokens[0], &quality);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
CHECK(quality > 0.85);
|
||||
CHECK(quality > 0.8);
|
||||
|
||||
// blur image
|
||||
HFImageStream blurHandle;
|
||||
auto blur = cv::imread(GET_DATA("data/bulk/blur.jpg"));
|
||||
auto blur = inspirecv::Image::Create(GET_DATA("data/bulk/blur.jpg"));
|
||||
ret = CVImageToImageStream(blur, blurHandle);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
@@ -349,7 +309,7 @@ TEST_CASE("test_FaceReaction", "[face_reaction]") {
|
||||
SECTION("open eyes") {
|
||||
// Get a face picture
|
||||
HFImageStream imgHandle;
|
||||
auto img = cv::imread(GET_DATA("data/reaction/open_eyes.png"));
|
||||
auto img = inspirecv::Image::Create(GET_DATA("data/reaction/open_eyes.png"));
|
||||
ret = CVImageToImageStream(img, imgHandle);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
@@ -364,8 +324,8 @@ TEST_CASE("test_FaceReaction", "[face_reaction]") {
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
// Get results
|
||||
HFFaceIntereactionState result;
|
||||
ret = HFGetFaceIntereactionStateResult(session, &result);
|
||||
HFFaceInteractionState result;
|
||||
ret = HFGetFaceInteractionStateResult(session, &result);
|
||||
REQUIRE(multipleFaceData.detectedNum == result.num);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
@@ -380,7 +340,7 @@ TEST_CASE("test_FaceReaction", "[face_reaction]") {
|
||||
SECTION("close eyes") {
|
||||
// Get a face picture
|
||||
HFImageStream imgHandle;
|
||||
auto img = cv::imread(GET_DATA("data/reaction/close_eyes.jpeg"));
|
||||
auto img = inspirecv::Image::Create(GET_DATA("data/reaction/close_eyes.jpeg"));
|
||||
ret = CVImageToImageStream(img, imgHandle);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
@@ -395,8 +355,8 @@ TEST_CASE("test_FaceReaction", "[face_reaction]") {
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
// Get results
|
||||
HFFaceIntereactionState result;
|
||||
ret = HFGetFaceIntereactionStateResult(session, &result);
|
||||
HFFaceInteractionState result;
|
||||
ret = HFGetFaceInteractionStateResult(session, &result);
|
||||
REQUIRE(multipleFaceData.detectedNum == result.num);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
@@ -411,7 +371,7 @@ TEST_CASE("test_FaceReaction", "[face_reaction]") {
|
||||
SECTION("Close one eye and open the other") {
|
||||
// Get a face picture
|
||||
HFImageStream imgHandle;
|
||||
auto img = cv::imread(GET_DATA("data/reaction/close_open_eyes.jpeg"));
|
||||
auto img = inspirecv::Image::Create(GET_DATA("data/reaction/close_open_eyes.jpeg"));
|
||||
ret = CVImageToImageStream(img, imgHandle);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
@@ -426,8 +386,8 @@ TEST_CASE("test_FaceReaction", "[face_reaction]") {
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
// Get results
|
||||
HFFaceIntereactionState result;
|
||||
ret = HFGetFaceIntereactionStateResult(session, &result);
|
||||
HFFaceInteractionState result;
|
||||
ret = HFGetFaceInteractionStateResult(session, &result);
|
||||
REQUIRE(multipleFaceData.detectedNum == result.num);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
@@ -441,4 +401,87 @@ TEST_CASE("test_FaceReaction", "[face_reaction]") {
|
||||
|
||||
ret = HFReleaseInspireFaceSession(session);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("test_TrackModeFaceAction", "[face_action]") {
|
||||
DRAW_SPLIT_LINE
|
||||
TEST_PRINT_OUTPUT(true);
|
||||
|
||||
HResult ret;
|
||||
HFSessionCustomParameter parameter = {0};
|
||||
parameter.enable_interaction_liveness = 1;
|
||||
HFDetectMode detMode = HF_DETECT_MODE_LIGHT_TRACK;
|
||||
HFSession session;
|
||||
ret = HFCreateInspireFaceSession(parameter, detMode, 3, -1, -1, &session);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
#if 0
|
||||
SECTION("Action Blink") {
|
||||
auto start = 130, end = 150;
|
||||
std::vector<std::string> filenames = generateFilenames("frame-%04d.jpg", start, end);
|
||||
int count = 0;
|
||||
for (size_t i = 0; i < filenames.size(); i++) {
|
||||
auto filename = filenames[i];
|
||||
HFImageStream imgHandle;
|
||||
auto image = inspirecv::Image::Create(GET_DATA("data/video_frames/" + filename));
|
||||
ret = CVImageToImageStream(image, imgHandle);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
HFMultipleFaceData multipleFaceData = {0};
|
||||
ret = HFExecuteFaceTrack(session, imgHandle, &multipleFaceData);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
REQUIRE(multipleFaceData.detectedNum > 0);
|
||||
|
||||
ret = HFMultipleFacePipelineProcessOptional(session, imgHandle, &multipleFaceData, HF_ENABLE_INTERACTION);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
HFFaceInteractionsActions result;
|
||||
ret = HFGetFaceInteractionActionsResult(session, &result);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
REQUIRE(multipleFaceData.detectedNum == result.num);
|
||||
|
||||
count += result.blink[0];
|
||||
ret = HFReleaseImageStream(imgHandle);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
}
|
||||
// Blink at least once
|
||||
REQUIRE(count > 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
SECTION("Action Jaw Open") {
|
||||
auto start = 110, end = 150;
|
||||
std::vector<std::string> filenames = generateFilenames("frame-%04d.jpg", start, end);
|
||||
int count = 0;
|
||||
for (size_t i = 0; i < filenames.size(); i++) {
|
||||
auto filename = filenames[i];
|
||||
HFImageStream imgHandle;
|
||||
auto image = inspirecv::Image::Create(GET_DATA("data/video_frames/" + filename));
|
||||
ret = CVImageToImageStream(image, imgHandle);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
HFMultipleFaceData multipleFaceData = {0};
|
||||
ret = HFExecuteFaceTrack(session, imgHandle, &multipleFaceData);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
REQUIRE(multipleFaceData.detectedNum > 0);
|
||||
|
||||
ret = HFMultipleFacePipelineProcessOptional(session, imgHandle, &multipleFaceData, HF_ENABLE_INTERACTION);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
HFFaceInteractionsActions result;
|
||||
ret = HFGetFaceInteractionActionsResult(session, &result);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
REQUIRE(multipleFaceData.detectedNum == result.num);
|
||||
|
||||
count += result.jawOpen[0];
|
||||
ret = HFReleaseImageStream(imgHandle);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
}
|
||||
// Jaw open at least once
|
||||
REQUIRE(count > 0);
|
||||
}
|
||||
#endif
|
||||
ret = HFReleaseInspireFaceSession(session);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
}
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
//
|
||||
// Created by tunm on 2023/10/11.
|
||||
//
|
||||
/**
|
||||
* Created by Jingyu Yan
|
||||
* @date 2024-10-01
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include "settings/test_settings.h"
|
||||
#include "inspireface/c_api/inspireface.h"
|
||||
#include "opencv2/opencv.hpp"
|
||||
#include "unit/test_helper/simple_csv_writer.h"
|
||||
#include "unit/test_helper/test_help.h"
|
||||
#include "unit/test_helper/test_tools.h"
|
||||
#include "middleware/costman.h"
|
||||
|
||||
TEST_CASE("test_FaceTrack", "[face_track]") {
|
||||
DRAW_SPLIT_LINE
|
||||
@@ -20,11 +21,12 @@ TEST_CASE("test_FaceTrack", "[face_track]") {
|
||||
HFDetectMode detMode = HF_DETECT_MODE_ALWAYS_DETECT;
|
||||
HFSession session;
|
||||
ret = HFCreateInspireFaceSession(parameter, detMode, 3, -1, -1, &session);
|
||||
TEST_ERROR_PRINT("error ret :{}", ret);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
// Get a face picture
|
||||
HFImageStream imgHandle;
|
||||
auto image = cv::imread(GET_DATA("data/bulk/kun.jpg"));
|
||||
auto image = inspirecv::Image::Create(GET_DATA("data/bulk/kun.jpg"));
|
||||
ret = CVImageToImageStream(image, imgHandle);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
@@ -37,24 +39,24 @@ TEST_CASE("test_FaceTrack", "[face_track]") {
|
||||
// Detect face position
|
||||
auto rect = multipleFaceData.rects[0];
|
||||
HFaceRect expect = {0};
|
||||
expect.x = 98;
|
||||
expect.y = 146;
|
||||
expect.width = 233 - expect.x;
|
||||
expect.height = 272 - expect.y;
|
||||
expect.x = 79;
|
||||
expect.y = 104;
|
||||
expect.width = 168;
|
||||
expect.height = 167;
|
||||
|
||||
auto iou = CalculateOverlap(rect, expect);
|
||||
cv::Rect cvRect(rect.x, rect.y, rect.width, rect.height);
|
||||
cv::rectangle(image, cvRect, cv::Scalar(255, 0, 124), 2);
|
||||
cv::imwrite("ww.jpg", image);
|
||||
// The iou is allowed to have an error of 10%
|
||||
CHECK(iou == Approx(1.0f).epsilon(0.3));
|
||||
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));
|
||||
|
||||
ret = HFReleaseImageStream(imgHandle);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
// Prepare non-face images
|
||||
HFImageStream viewHandle;
|
||||
auto view = cv::imread(GET_DATA("data/bulk/view.jpg"));
|
||||
auto view = inspirecv::Image::Create(GET_DATA("data/bulk/view.jpg"));
|
||||
ret = CVImageToImageStream(view, viewHandle);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
ret = HFExecuteFaceTrack(session, viewHandle, &multipleFaceData);
|
||||
@@ -68,6 +70,7 @@ TEST_CASE("test_FaceTrack", "[face_track]") {
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
}
|
||||
|
||||
#if 0
|
||||
SECTION("Face tracking stability from frames") {
|
||||
HResult ret;
|
||||
HFSessionCustomParameter parameter = {0};
|
||||
@@ -83,7 +86,7 @@ TEST_CASE("test_FaceTrack", "[face_track]") {
|
||||
for (int i = 0; i < filenames.size(); ++i) {
|
||||
auto filename = filenames[i];
|
||||
HFImageStream imgHandle;
|
||||
auto image = cv::imread(GET_DATA("data/video_frames/" + filename));
|
||||
auto image = inspirecv::Image::Create(GET_DATA("data/video_frames/" + filename));
|
||||
ret = CVImageToImageStream(image, imgHandle);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
@@ -96,10 +99,10 @@ TEST_CASE("test_FaceTrack", "[face_track]") {
|
||||
continue;
|
||||
}
|
||||
auto rect = multipleFaceData.rects[0];
|
||||
cv::Rect cvRect(rect.x, rect.y, rect.width, rect.height);
|
||||
cv::rectangle(image, cvRect, cv::Scalar(255, 0, 124), 2);
|
||||
std::string save = GET_SAVE_DATA("data/video_frames") + "/" + std::to_string(i) + ".jpg";
|
||||
cv::imwrite(save, image);
|
||||
auto cvRect = inspirecv::Rect<int>::Create(rect.x, rect.y, rect.width, rect.height);
|
||||
image.DrawRect(cvRect, {0, 0, 255}, 2);
|
||||
std::string save = GET_SAVE_DATA("video_frames") + "/" + std::to_string(i) + ".jpg";
|
||||
image.Write(save);
|
||||
auto id = multipleFaceData.trackIds[0];
|
||||
// TEST_PRINT("{}", id);
|
||||
if (id != expectedId) {
|
||||
@@ -116,6 +119,7 @@ TEST_CASE("test_FaceTrack", "[face_track]") {
|
||||
ret = HFReleaseInspireFaceSession(session);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
}
|
||||
#endif
|
||||
|
||||
SECTION("Head pose estimation") {
|
||||
HResult ret;
|
||||
@@ -130,7 +134,7 @@ TEST_CASE("test_FaceTrack", "[face_track]") {
|
||||
|
||||
// Left side face
|
||||
HFImageStream leftHandle;
|
||||
auto left = cv::imread(GET_DATA("data/pose/left_face.jpeg"));
|
||||
auto left = inspirecv::Image::Create(GET_DATA("data/pose/left_face.jpeg"));
|
||||
ret = CVImageToImageStream(left, leftHandle);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
@@ -150,7 +154,7 @@ TEST_CASE("test_FaceTrack", "[face_track]") {
|
||||
|
||||
// Right-handed rotation
|
||||
HFImageStream rightHandle;
|
||||
auto right = cv::imread(GET_DATA("data/pose/right_face.png"));
|
||||
auto right = inspirecv::Image::Create(GET_DATA("data/pose/right_face.png"));
|
||||
ret = CVImageToImageStream(right, rightHandle);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
@@ -165,7 +169,7 @@ TEST_CASE("test_FaceTrack", "[face_track]") {
|
||||
|
||||
// Rise head
|
||||
HFImageStream riseHandle;
|
||||
auto rise = cv::imread(GET_DATA("data/pose/rise_face.jpeg"));
|
||||
auto rise = inspirecv::Image::Create(GET_DATA("data/pose/rise_face.jpeg"));
|
||||
ret = CVImageToImageStream(rise, riseHandle);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
@@ -173,12 +177,12 @@ TEST_CASE("test_FaceTrack", "[face_track]") {
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
REQUIRE(multipleFaceData.detectedNum == 1);
|
||||
pitch = multipleFaceData.angles.pitch[0];
|
||||
CHECK(pitch > 5);
|
||||
CHECK(pitch > 3);
|
||||
HFReleaseImageStream(riseHandle);
|
||||
|
||||
// Lower head
|
||||
HFImageStream lowerHandle;
|
||||
auto lower = cv::imread(GET_DATA("data/pose/lower_face.jpeg"));
|
||||
auto lower = inspirecv::Image::Create(GET_DATA("data/pose/lower_face.jpeg"));
|
||||
ret = CVImageToImageStream(lower, lowerHandle);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
@@ -191,7 +195,7 @@ TEST_CASE("test_FaceTrack", "[face_track]") {
|
||||
|
||||
// Roll head
|
||||
HFImageStream leftWryneckHandle;
|
||||
auto leftWryneck = cv::imread(GET_DATA("data/pose/left_wryneck.png"));
|
||||
auto leftWryneck = inspirecv::Image::Create(GET_DATA("data/pose/left_wryneck.png"));
|
||||
ret = CVImageToImageStream(leftWryneck, leftWryneckHandle);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
@@ -204,7 +208,7 @@ TEST_CASE("test_FaceTrack", "[face_track]") {
|
||||
|
||||
// Roll head
|
||||
HFImageStream rightWryneckHandle;
|
||||
auto rightWryneck = cv::imread(GET_DATA("data/pose/right_wryneck.png"));
|
||||
auto rightWryneck = inspirecv::Image::Create(GET_DATA("data/pose/right_wryneck.png"));
|
||||
ret = CVImageToImageStream(rightWryneck, rightWryneckHandle);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
@@ -212,7 +216,7 @@ TEST_CASE("test_FaceTrack", "[face_track]") {
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
REQUIRE(multipleFaceData.detectedNum == 1);
|
||||
roll = multipleFaceData.angles.roll[0];
|
||||
CHECK(roll > 30);
|
||||
CHECK(roll > 25);
|
||||
HFReleaseImageStream(rightWryneckHandle);
|
||||
|
||||
// finish
|
||||
@@ -220,117 +224,44 @@ TEST_CASE("test_FaceTrack", "[face_track]") {
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
}
|
||||
|
||||
SECTION("Face detection benchmark") {
|
||||
#ifdef ISF_ENABLE_BENCHMARK
|
||||
SECTION("Face detection benchmark@160") {
|
||||
int loop = 1000;
|
||||
HResult ret;
|
||||
HFSessionCustomParameter parameter = {0};
|
||||
HFDetectMode detMode = HF_DETECT_MODE_ALWAYS_DETECT;
|
||||
HFSession session;
|
||||
HInt32 pixLevel = 160;
|
||||
ret = HFCreateInspireFaceSession(parameter, detMode, 3, pixLevel, -1, &session);
|
||||
ret = HFCreateInspireFaceSession(parameter, detMode, 3, -1, -1, &session);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
// Prepare an image
|
||||
HFImageStream imgHandle;
|
||||
auto image = cv::imread(GET_DATA("data/bulk/kun.jpg"));
|
||||
auto image = inspirecv::Image::Create(GET_DATA("data/bulk/kun.jpg"));
|
||||
ret = CVImageToImageStream(image, imgHandle);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
BenchmarkRecord record(getBenchmarkRecordFile());
|
||||
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
HFMultipleFaceData multipleFaceData = {0};
|
||||
auto start = (double)cv::getTickCount();
|
||||
auto timer = inspire::Timer();
|
||||
for (int i = 0; i < loop; ++i) {
|
||||
ret = HFExecuteFaceTrack(session, imgHandle, &multipleFaceData);
|
||||
}
|
||||
auto cost = ((double)cv::getTickCount() - start) / cv::getTickFrequency() * 1000;
|
||||
auto cost = timer.GetCostTime();
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
REQUIRE(multipleFaceData.detectedNum == 1);
|
||||
TEST_PRINT("<Benchmark> Face Detect@160 -> Loop: {}, Total Time: {:.5f}ms, Average Time: {:.5f}ms", loop, cost, cost / loop);
|
||||
record.insertBenchmarkData("Face Detect@160", loop, cost, cost / loop);
|
||||
TEST_PRINT("<Benchmark> Face Detect -> Loop: {}, Total Time: {:.5f}ms, Average Time: {:.5f}ms", loop, cost, cost / loop);
|
||||
record.insertBenchmarkData("Face Detect", loop, cost, cost / loop);
|
||||
|
||||
ret = HFReleaseImageStream(imgHandle);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
ret = HFReleaseInspireFaceSession(session);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
}
|
||||
|
||||
SECTION("Face detection benchmark@320") {
|
||||
int loop = 1000;
|
||||
HResult ret;
|
||||
HFSessionCustomParameter parameter = {0};
|
||||
HFDetectMode detMode = HF_DETECT_MODE_ALWAYS_DETECT;
|
||||
HFSession session;
|
||||
HInt32 pixLevel = 320;
|
||||
ret = HFCreateInspireFaceSession(parameter, detMode, 3, pixLevel, -1, &session);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
// Prepare an image
|
||||
HFImageStream imgHandle;
|
||||
auto image = cv::imread(GET_DATA("data/bulk/kun.jpg"));
|
||||
ret = CVImageToImageStream(image, imgHandle);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
BenchmarkRecord record(getBenchmarkRecordFile());
|
||||
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
HFMultipleFaceData multipleFaceData = {0};
|
||||
auto start = (double)cv::getTickCount();
|
||||
for (int i = 0; i < loop; ++i) {
|
||||
ret = HFExecuteFaceTrack(session, imgHandle, &multipleFaceData);
|
||||
}
|
||||
auto cost = ((double)cv::getTickCount() - start) / cv::getTickFrequency() * 1000;
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
REQUIRE(multipleFaceData.detectedNum == 1);
|
||||
TEST_PRINT("<Benchmark> Face Detect@320 -> Loop: {}, Total Time: {:.5f}ms, Average Time: {:.5f}ms", loop, cost, cost / loop);
|
||||
record.insertBenchmarkData("Face Detect@320", loop, cost, cost / loop);
|
||||
|
||||
ret = HFReleaseImageStream(imgHandle);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
ret = HFReleaseInspireFaceSession(session);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
}
|
||||
|
||||
SECTION("Face detection benchmark@640") {
|
||||
int loop = 1000;
|
||||
HResult ret;
|
||||
HFSessionCustomParameter parameter = {0};
|
||||
HFDetectMode detMode = HF_DETECT_MODE_ALWAYS_DETECT;
|
||||
HFSession session;
|
||||
HInt32 pixLevel = 640;
|
||||
ret = HFCreateInspireFaceSession(parameter, detMode, 3, pixLevel, -1, &session);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
// Prepare an image
|
||||
HFImageStream imgHandle;
|
||||
auto image = cv::imread(GET_DATA("data/bulk/kun.jpg"));
|
||||
ret = CVImageToImageStream(image, imgHandle);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
BenchmarkRecord record(getBenchmarkRecordFile());
|
||||
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
HFMultipleFaceData multipleFaceData = {0};
|
||||
auto start = (double)cv::getTickCount();
|
||||
for (int i = 0; i < loop; ++i) {
|
||||
ret = HFExecuteFaceTrack(session, imgHandle, &multipleFaceData);
|
||||
}
|
||||
auto cost = ((double)cv::getTickCount() - start) / cv::getTickFrequency() * 1000;
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
REQUIRE(multipleFaceData.detectedNum == 1);
|
||||
TEST_PRINT("<Benchmark> Face Detect@640 -> Loop: {}, Total Time: {:.5f}ms, Average Time: {:.5f}ms", loop, cost, cost / loop);
|
||||
record.insertBenchmarkData("Face Detect@640", loop, cost, cost / loop);
|
||||
|
||||
ret = HFReleaseImageStream(imgHandle);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
ret = HFReleaseInspireFaceSession(session);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
}
|
||||
#else
|
||||
TEST_PRINT("Skip the face detection benchmark test. To run it, you need to turn on the benchmark test.");
|
||||
TEST_PRINT("Skip the face detection benchmark test. To run it, you need to turn on the benchmark test.");
|
||||
#endif
|
||||
}
|
||||
|
||||
SECTION("Face light track benchmark") {
|
||||
#ifdef ISF_ENABLE_BENCHMARK
|
||||
@@ -344,7 +275,7 @@ TEST_CASE("test_FaceTrack", "[face_track]") {
|
||||
|
||||
// Prepare an image
|
||||
HFImageStream imgHandle;
|
||||
auto image = cv::imread(GET_DATA("data/bulk/kun.jpg"));
|
||||
auto image = inspirecv::Image::Create(GET_DATA("data/bulk/kun.jpg"));
|
||||
ret = CVImageToImageStream(image, imgHandle);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
BenchmarkRecord record(getBenchmarkRecordFile());
|
||||
@@ -352,13 +283,13 @@ TEST_CASE("test_FaceTrack", "[face_track]") {
|
||||
// Case: Execute the benchmark using the VIDEO mode(Track)
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
HFMultipleFaceData multipleFaceData = {0};
|
||||
auto start = (double)cv::getTickCount();
|
||||
auto timer = inspire::Timer();
|
||||
for (int i = 0; i < loop; ++i) {
|
||||
ret = HFExecuteFaceTrack(session, imgHandle, &multipleFaceData);
|
||||
}
|
||||
auto cost = ((double)cv::getTickCount() - start) / cv::getTickFrequency() * 1000;
|
||||
auto cost = timer.GetCostTime();
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
REQUIRE(multipleFaceData.detectedNum > 0);
|
||||
REQUIRE(multipleFaceData.detectedNum >= 1);
|
||||
TEST_PRINT("<Benchmark> Face Track -> Loop: {}, Total Time: {:.5f}ms, Average Time: {:.5f}ms", loop, cost, cost / loop);
|
||||
record.insertBenchmarkData("Face Track", loop, cost, cost / loop);
|
||||
|
||||
@@ -377,12 +308,12 @@ TEST_CASE("test_MultipleLevelFaceDetect", "[face_detect]") {
|
||||
DRAW_SPLIT_LINE
|
||||
TEST_PRINT_OUTPUT(true);
|
||||
|
||||
SECTION("Detect input 160px") {
|
||||
SECTION("Detect input 192px") {
|
||||
HResult ret;
|
||||
HFSessionCustomParameter parameter = {0};
|
||||
HFDetectMode detMode = HF_DETECT_MODE_ALWAYS_DETECT;
|
||||
HFSession session;
|
||||
HInt32 detectPixelLevel = 160;
|
||||
HInt32 detectPixelLevel = 192;
|
||||
ret = HFCreateInspireFaceSession(parameter, detMode, 20, detectPixelLevel, -1, &session);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
HFSessionSetTrackPreviewSize(session, detectPixelLevel);
|
||||
@@ -390,7 +321,7 @@ TEST_CASE("test_MultipleLevelFaceDetect", "[face_detect]") {
|
||||
|
||||
// Get a face picture
|
||||
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);
|
||||
|
||||
@@ -422,7 +353,7 @@ TEST_CASE("test_MultipleLevelFaceDetect", "[face_detect]") {
|
||||
|
||||
// Get a face picture
|
||||
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);
|
||||
|
||||
@@ -432,7 +363,7 @@ TEST_CASE("test_MultipleLevelFaceDetect", "[face_detect]") {
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
CHECK(multipleFaceData.detectedNum > 9);
|
||||
CHECK(multipleFaceData.detectedNum < 15);
|
||||
CHECK(multipleFaceData.detectedNum < 12);
|
||||
|
||||
ret = HFReleaseImageStream(imgHandle);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
@@ -454,7 +385,7 @@ TEST_CASE("test_MultipleLevelFaceDetect", "[face_detect]") {
|
||||
|
||||
// Get a face picture
|
||||
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);
|
||||
|
||||
@@ -464,167 +395,11 @@ TEST_CASE("test_MultipleLevelFaceDetect", "[face_detect]") {
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
CHECK(multipleFaceData.detectedNum > 15);
|
||||
CHECK(multipleFaceData.detectedNum < 25);
|
||||
CHECK(multipleFaceData.detectedNum < 21);
|
||||
|
||||
ret = HFReleaseImageStream(imgHandle);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
ret = HFReleaseInspireFaceSession(session);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("test_FaceShowLandmark", "[face_landmark]") {
|
||||
DRAW_SPLIT_LINE
|
||||
TEST_PRINT_OUTPUT(true);
|
||||
|
||||
std::vector<std::string> images_path = {
|
||||
GET_DATA("data/reaction/close_open_eyes.jpeg"),
|
||||
GET_DATA("data/reaction/open_eyes.png"),
|
||||
GET_DATA("data/reaction/close_eyes.jpeg"),
|
||||
};
|
||||
|
||||
HResult ret;
|
||||
HFSessionCustomParameter parameter = {0};
|
||||
HFDetectMode detMode = HF_DETECT_MODE_ALWAYS_DETECT;
|
||||
HFSession session;
|
||||
HInt32 detectPixelLevel = 160;
|
||||
ret = HFCreateInspireFaceSession(parameter, detMode, 20, detectPixelLevel, -1, &session);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
HFSessionSetTrackPreviewSize(session, detectPixelLevel);
|
||||
HFSessionSetFilterMinimumFacePixelSize(session, 0);
|
||||
|
||||
for (size_t i = 0; i < images_path.size(); i++) {
|
||||
HFImageStream imgHandle;
|
||||
auto image = cv::imread(images_path[i]);
|
||||
ret = CVImageToImageStream(image, imgHandle);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
// Extract basic face information from photos
|
||||
HFMultipleFaceData multipleFaceData = {0};
|
||||
ret = HFExecuteFaceTrack(session, imgHandle, &multipleFaceData);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
REQUIRE(multipleFaceData.detectedNum > 0);
|
||||
|
||||
HInt32 numOfLmk;
|
||||
HFGetNumOfFaceDenseLandmark(&numOfLmk);
|
||||
HPoint2f denseLandmarkPoints[numOfLmk];
|
||||
ret = HFGetFaceDenseLandmarkFromFaceToken(multipleFaceData.tokens[0], denseLandmarkPoints, numOfLmk);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
for (size_t i = 0; i < numOfLmk; i++) {
|
||||
cv::Point2f p(denseLandmarkPoints[i].x, denseLandmarkPoints[i].y);
|
||||
cv::circle(image, p, 0, (0, 0, 255), 2);
|
||||
}
|
||||
|
||||
cv::imwrite("lml_" + std::to_string(i) + ".jpg", image);
|
||||
|
||||
ret = HFReleaseImageStream(imgHandle);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
}
|
||||
ret = HFReleaseInspireFaceSession(session);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
}
|
||||
|
||||
TEST_CASE("test_FaceDetectConfidence", "[face_track]") {
|
||||
DRAW_SPLIT_LINE
|
||||
TEST_PRINT_OUTPUT(true);
|
||||
|
||||
SECTION("DetectConfidenceSchedule-1") {
|
||||
// Schedule 1:
|
||||
HFloat threshold = 0.4f;
|
||||
HInt32 detectPixelLevel = 160;
|
||||
HInt32 maxDetectNum = 20;
|
||||
|
||||
HResult ret;
|
||||
HFSessionCustomParameter parameter = {0};
|
||||
HFDetectMode detMode = HF_DETECT_MODE_ALWAYS_DETECT;
|
||||
HFSession session;
|
||||
ret = HFCreateInspireFaceSession(parameter, detMode, maxDetectNum, detectPixelLevel, -1, &session);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
ret = HFSessionSetFaceDetectThreshold(session, threshold);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
// Prepare an image
|
||||
HFImageStream imgHandle;
|
||||
auto image = cv::imread(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);
|
||||
for (int i = 0; i < multipleFaceData.detectedNum; i++) {
|
||||
CHECK(multipleFaceData.detConfidence[i] >= threshold);
|
||||
}
|
||||
ret = HFReleaseImageStream(imgHandle);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
ret = HFReleaseInspireFaceSession(session);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
}
|
||||
|
||||
SECTION("DetectConfidenceSchedule-2") {
|
||||
// Schedule 2:
|
||||
HFloat threshold = 0.7f;
|
||||
HInt32 detectPixelLevel = 320;
|
||||
HInt32 maxDetectNum = 10;
|
||||
|
||||
HResult ret;
|
||||
HFSessionCustomParameter parameter = {0};
|
||||
HFDetectMode detMode = HF_DETECT_MODE_ALWAYS_DETECT;
|
||||
HFSession session;
|
||||
ret = HFCreateInspireFaceSession(parameter, detMode, maxDetectNum, detectPixelLevel, -1, &session);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
ret = HFSessionSetFaceDetectThreshold(session, threshold);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
// Prepare an image
|
||||
HFImageStream imgHandle;
|
||||
auto image = cv::imread(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);
|
||||
for (int i = 0; i < multipleFaceData.detectedNum; i++) {
|
||||
CHECK(multipleFaceData.detConfidence[i] >= threshold);
|
||||
}
|
||||
ret = HFReleaseImageStream(imgHandle);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
ret = HFReleaseInspireFaceSession(session);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
}
|
||||
|
||||
SECTION("DetectConfidenceSchedule-3") {
|
||||
// Schedule 3:
|
||||
HFloat threshold = 0.80f;
|
||||
HInt32 detectPixelLevel = 640;
|
||||
HInt32 maxDetectNum = 20;
|
||||
|
||||
HResult ret;
|
||||
HFSessionCustomParameter parameter = {0};
|
||||
HFDetectMode detMode = HF_DETECT_MODE_ALWAYS_DETECT;
|
||||
HFSession session;
|
||||
ret = HFCreateInspireFaceSession(parameter, detMode, maxDetectNum, detectPixelLevel, -1, &session);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
ret = HFSessionSetFaceDetectThreshold(session, threshold);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
// Prepare an image
|
||||
HFImageStream imgHandle;
|
||||
auto image = cv::imread(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);
|
||||
for (int i = 0; i < multipleFaceData.detectedNum; i++) {
|
||||
CHECK(multipleFaceData.detConfidence[i] >= threshold);
|
||||
}
|
||||
ret = HFReleaseImageStream(imgHandle);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
ret = HFReleaseInspireFaceSession(session);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
//
|
||||
// Created by tunm on 2024/4/13.
|
||||
//
|
||||
/**
|
||||
* Created by Jingyu Yan
|
||||
* @date 2024-10-01
|
||||
*/
|
||||
#include <iostream>
|
||||
#include "settings/test_settings.h"
|
||||
#include "inspireface/c_api/inspireface.h"
|
||||
@@ -13,17 +14,17 @@ TEST_CASE("test_FeatureHubBase", "[FeatureHub][BasicFunction]") {
|
||||
|
||||
SECTION("FeatureHub basic function") {
|
||||
HResult ret;
|
||||
HFFeatureHubConfiguration configuration = {0};
|
||||
HFFeatureHubConfiguration configuration;
|
||||
auto dbPath = GET_SAVE_DATA(".test");
|
||||
HString dbPathStr = new char[dbPath.size() + 1];
|
||||
std::strcpy(dbPathStr, dbPath.c_str());
|
||||
configuration.primaryKeyMode = HF_PK_AUTO_INCREMENT;
|
||||
configuration.enablePersistence = 1;
|
||||
configuration.dbPath = dbPathStr;
|
||||
configuration.featureBlockNum = 20;
|
||||
configuration.persistenceDbPath = dbPathStr;
|
||||
configuration.searchMode = HF_SEARCH_MODE_EXHAUSTIVE;
|
||||
configuration.searchThreshold = 0.48f;
|
||||
// Delete the previous data before testing
|
||||
if (std::remove(configuration.dbPath) != 0) {
|
||||
if (std::remove(configuration.persistenceDbPath) != 0) {
|
||||
spdlog::trace("Error deleting file");
|
||||
}
|
||||
ret = HFFeatureHubDataEnable(configuration);
|
||||
@@ -37,17 +38,17 @@ TEST_CASE("test_FeatureHubBase", "[FeatureHub][BasicFunction]") {
|
||||
|
||||
SECTION("FeatureHub search top-k") {
|
||||
HResult ret;
|
||||
HFFeatureHubConfiguration configuration = {0};
|
||||
HFFeatureHubConfiguration configuration;
|
||||
auto dbPath = GET_SAVE_DATA(".test");
|
||||
HString dbPathStr = new char[dbPath.size() + 1];
|
||||
std::strcpy(dbPathStr, dbPath.c_str());
|
||||
configuration.primaryKeyMode = HF_PK_AUTO_INCREMENT;
|
||||
configuration.enablePersistence = 1;
|
||||
configuration.dbPath = dbPathStr;
|
||||
configuration.featureBlockNum = 20;
|
||||
configuration.persistenceDbPath = dbPathStr;
|
||||
configuration.searchMode = HF_SEARCH_MODE_EXHAUSTIVE;
|
||||
configuration.searchThreshold = 0.48f;
|
||||
// Delete the previous data before testing
|
||||
if (std::remove(configuration.dbPath) != 0) {
|
||||
if (std::remove(configuration.persistenceDbPath) != 0) {
|
||||
spdlog::trace("Error deleting file");
|
||||
}
|
||||
ret = HFFeatureHubDataEnable(configuration);
|
||||
@@ -61,19 +62,14 @@ TEST_CASE("test_FeatureHubBase", "[FeatureHub][BasicFunction]") {
|
||||
for (int i = 0; i < genSizeOfBase; ++i) {
|
||||
auto feat = GenerateRandomFeature(featureLength);
|
||||
baseFeatures.push_back(feat);
|
||||
auto name = std::to_string(i);
|
||||
// Establish a security buffer
|
||||
std::vector<char> nameBuffer(name.begin(), name.end());
|
||||
nameBuffer.push_back('\0');
|
||||
// Construct face feature
|
||||
HFFaceFeature feature = {0};
|
||||
feature.size = feat.size();
|
||||
feature.data = feat.data();
|
||||
HFFaceFeatureIdentity identity = {0};
|
||||
identity.feature = &feature;
|
||||
identity.customId = i;
|
||||
identity.tag = nameBuffer.data();
|
||||
ret = HFFeatureHubInsertFeature(identity);
|
||||
HFaceId allocId;
|
||||
ret = HFFeatureHubInsertFeature(identity, &allocId);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
}
|
||||
HInt32 totalFace;
|
||||
@@ -82,8 +78,8 @@ TEST_CASE("test_FeatureHubBase", "[FeatureHub][BasicFunction]") {
|
||||
REQUIRE(totalFace == genSizeOfBase);
|
||||
|
||||
// 2000 data was imported
|
||||
HInt32 targetId = 523;
|
||||
auto targetFeature = baseFeatures[targetId];
|
||||
HInt32 targetId = 524;
|
||||
auto targetFeature = baseFeatures[targetId - 1];
|
||||
|
||||
std::vector<std::vector<HFloat>> similarVectors;
|
||||
std::vector<HInt32> coverIds = {2, 300, 524, 789, 1024, 1995};
|
||||
@@ -95,8 +91,7 @@ TEST_CASE("test_FeatureHubBase", "[FeatureHub][BasicFunction]") {
|
||||
feature.data = feat.data();
|
||||
HFFaceFeatureIdentity identity = {0};
|
||||
identity.feature = &feature;
|
||||
identity.customId = coverIds[i];
|
||||
identity.tag = "HOLD";
|
||||
identity.id = coverIds[i];
|
||||
ret = HFFeatureHubFaceUpdate(identity);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
}
|
||||
@@ -111,12 +106,9 @@ TEST_CASE("test_FeatureHubBase", "[FeatureHub][BasicFunction]") {
|
||||
ret = HFFeatureHubFaceSearchTopK(searchFeature, topK, &results);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
coverIds.push_back(targetId);
|
||||
|
||||
REQUIRE(coverIds.size() == results.size);
|
||||
for (int i = 0; i < results.size; ++i) {
|
||||
REQUIRE(std::find(coverIds.begin(), coverIds.end(), results.customIds[i]) !=
|
||||
coverIds.end());
|
||||
REQUIRE(std::find(coverIds.begin(), coverIds.end(), results.ids[i]) != coverIds.end());
|
||||
}
|
||||
|
||||
ret = HFFeatureHubDataDisable();
|
||||
@@ -129,10 +121,10 @@ TEST_CASE("test_FeatureHubBase", "[FeatureHub][BasicFunction]") {
|
||||
HResult ret;
|
||||
auto dbPath = GET_SAVE_DATA(".test");
|
||||
HString dbPathStr = new char[dbPath.size() + 1];
|
||||
HFFeatureHubConfiguration configuration = {0};
|
||||
HFFeatureHubConfiguration configuration;
|
||||
configuration.primaryKeyMode = HF_PK_AUTO_INCREMENT;
|
||||
configuration.enablePersistence = 0;
|
||||
configuration.dbPath = dbPathStr;
|
||||
configuration.featureBlockNum = 20;
|
||||
configuration.persistenceDbPath = dbPathStr;
|
||||
configuration.searchMode = HF_SEARCH_MODE_EXHAUSTIVE;
|
||||
configuration.searchThreshold = 0.48f;
|
||||
|
||||
@@ -140,20 +132,20 @@ TEST_CASE("test_FeatureHubBase", "[FeatureHub][BasicFunction]") {
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
ret = HFFeatureHubDataEnable(configuration);
|
||||
REQUIRE(ret == HERR_FT_HUB_ENABLE_REPETITION);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
ret = HFFeatureHubDataDisable();
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
ret = HFFeatureHubDataDisable();
|
||||
REQUIRE(ret == HERR_FT_HUB_DISABLE_REPETITION);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
delete[] dbPathStr;
|
||||
}
|
||||
|
||||
SECTION("Only memory storage is used") {
|
||||
HResult ret;
|
||||
HFFeatureHubConfiguration configuration = {0};
|
||||
HFFeatureHubConfiguration configuration;
|
||||
configuration.enablePersistence = 0;
|
||||
ret = HFFeatureHubDataEnable(configuration);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
@@ -170,17 +162,17 @@ TEST_CASE("test_ConcurrencyInsertion", "[FeatureHub][Concurrency]") {
|
||||
TEST_PRINT_OUTPUT(true);
|
||||
|
||||
HResult ret;
|
||||
HFFeatureHubConfiguration configuration = {0};
|
||||
HFFeatureHubConfiguration configuration;
|
||||
auto dbPath = GET_SAVE_DATA(".test");
|
||||
HString dbPathStr = new char[dbPath.size() + 1];
|
||||
std::strcpy(dbPathStr, dbPath.c_str());
|
||||
configuration.primaryKeyMode = HF_PK_AUTO_INCREMENT;
|
||||
configuration.enablePersistence = 1;
|
||||
configuration.dbPath = dbPathStr;
|
||||
configuration.featureBlockNum = 20;
|
||||
configuration.persistenceDbPath = dbPathStr;
|
||||
configuration.searchMode = HF_SEARCH_MODE_EXHAUSTIVE;
|
||||
configuration.searchThreshold = 0.48f;
|
||||
// Delete the previous data before testing
|
||||
if (std::remove(configuration.dbPath) != 0) {
|
||||
if (std::remove(configuration.persistenceDbPath) != 0) {
|
||||
spdlog::trace("Error deleting file");
|
||||
}
|
||||
ret = HFFeatureHubDataEnable(configuration);
|
||||
@@ -199,7 +191,7 @@ TEST_CASE("test_ConcurrencyInsertion", "[FeatureHub][Concurrency]") {
|
||||
auto beginGenId = 2000;
|
||||
|
||||
for (int i = 0; i < numThreads; ++i) {
|
||||
threads.emplace_back([=]() { // 使用值捕获以避免捕获引用后变量改变
|
||||
threads.emplace_back([=]() {
|
||||
for (int j = 0; j < insertsPerThread; ++j) {
|
||||
auto feat = GenerateRandomFeature(featureLength);
|
||||
auto name = std::to_string(beginGenId + j + i * insertsPerThread);
|
||||
@@ -210,10 +202,10 @@ TEST_CASE("test_ConcurrencyInsertion", "[FeatureHub][Concurrency]") {
|
||||
feature.data = feat.data();
|
||||
HFFaceFeatureIdentity featureIdentity = {0};
|
||||
featureIdentity.feature = &feature;
|
||||
featureIdentity.customId =
|
||||
beginGenId + j + i * insertsPerThread; // 确保 customId 唯一
|
||||
featureIdentity.tag = nameBuffer.data();
|
||||
auto ret = HFFeatureHubInsertFeature(featureIdentity);
|
||||
// featureIdentity.customId = beginGenId + j + i * insertsPerThread;
|
||||
// featureIdentity.tag = nameBuffer.data();
|
||||
HFaceId allocId;
|
||||
auto ret = HFFeatureHubInsertFeature(featureIdentity, &allocId);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
}
|
||||
});
|
||||
@@ -226,9 +218,7 @@ TEST_CASE("test_ConcurrencyInsertion", "[FeatureHub][Concurrency]") {
|
||||
HInt32 count;
|
||||
ret = HFFeatureHubGetFaceCount(&count);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
REQUIRE(count ==
|
||||
baseNum + numThreads * insertsPerThread); // Ensure that the previous base data is
|
||||
// added to the newly inserted data
|
||||
REQUIRE(count == baseNum + numThreads * insertsPerThread); // Ensure that the previous base data is added to the newly inserted data
|
||||
|
||||
ret = HFFeatureHubDataDisable();
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
@@ -241,17 +231,17 @@ TEST_CASE("test_ConcurrencyRemove", "[FeatureHub][Concurrency]") {
|
||||
TEST_PRINT_OUTPUT(true);
|
||||
|
||||
HResult ret;
|
||||
HFFeatureHubConfiguration configuration = {0};
|
||||
HFFeatureHubConfiguration configuration;
|
||||
auto dbPath = GET_SAVE_DATA(".test");
|
||||
HString dbPathStr = new char[dbPath.size() + 1];
|
||||
std::strcpy(dbPathStr, dbPath.c_str());
|
||||
configuration.primaryKeyMode = HF_PK_AUTO_INCREMENT;
|
||||
configuration.enablePersistence = 1;
|
||||
configuration.dbPath = dbPathStr;
|
||||
configuration.featureBlockNum = 20;
|
||||
configuration.persistenceDbPath = dbPathStr;
|
||||
configuration.searchMode = HF_SEARCH_MODE_EXHAUSTIVE;
|
||||
configuration.searchThreshold = 0.48f;
|
||||
// Delete the previous data before testing
|
||||
if (std::remove(configuration.dbPath) != 0) {
|
||||
if (std::remove(configuration.persistenceDbPath) != 0) {
|
||||
spdlog::trace("Error deleting file");
|
||||
}
|
||||
ret = HFFeatureHubDataEnable(configuration);
|
||||
@@ -276,9 +266,10 @@ TEST_CASE("test_ConcurrencyRemove", "[FeatureHub][Concurrency]") {
|
||||
feature.data = feat.data();
|
||||
HFFaceFeatureIdentity identity = {0};
|
||||
identity.feature = &feature;
|
||||
identity.customId = i;
|
||||
identity.tag = nameBuffer.data();
|
||||
ret = HFFeatureHubInsertFeature(identity);
|
||||
// identity.customId = i;
|
||||
// identity.tag = nameBuffer.data();
|
||||
HFaceId allocId;
|
||||
ret = HFFeatureHubInsertFeature(identity, &allocId);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
}
|
||||
HInt32 totalFace;
|
||||
@@ -305,7 +296,8 @@ TEST_CASE("test_ConcurrencyRemove", "[FeatureHub][Concurrency]") {
|
||||
HInt32 remainingCount;
|
||||
ret = HFFeatureHubGetFaceCount(&remainingCount);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
REQUIRE(remainingCount == genSizeOfBase - numThreads * removePerThread);
|
||||
// need exclude id=0
|
||||
REQUIRE(remainingCount - 1 == genSizeOfBase - numThreads * removePerThread);
|
||||
TEST_PRINT("Remaining Count: {}", remainingCount);
|
||||
|
||||
ret = HFFeatureHubDataDisable();
|
||||
@@ -319,17 +311,17 @@ TEST_CASE("test_ConcurrencySearch", "[FeatureHub][Concurrency]") {
|
||||
TEST_PRINT_OUTPUT(true);
|
||||
|
||||
HResult ret;
|
||||
HFFeatureHubConfiguration configuration = {0};
|
||||
HFFeatureHubConfiguration configuration;
|
||||
auto dbPath = GET_SAVE_DATA(".test");
|
||||
HString dbPathStr = new char[dbPath.size() + 1];
|
||||
std::strcpy(dbPathStr, dbPath.c_str());
|
||||
configuration.primaryKeyMode = HF_PK_AUTO_INCREMENT;
|
||||
configuration.enablePersistence = 1;
|
||||
configuration.dbPath = dbPathStr;
|
||||
configuration.featureBlockNum = 20;
|
||||
configuration.persistenceDbPath = dbPathStr;
|
||||
configuration.searchMode = HF_SEARCH_MODE_EXHAUSTIVE;
|
||||
configuration.searchThreshold = 0.48f;
|
||||
// Delete the previous data before testing
|
||||
if (std::remove(configuration.dbPath) != 0) {
|
||||
if (std::remove(configuration.persistenceDbPath) != 0) {
|
||||
spdlog::trace("Error deleting file");
|
||||
}
|
||||
ret = HFFeatureHubDataEnable(configuration);
|
||||
@@ -353,9 +345,10 @@ TEST_CASE("test_ConcurrencySearch", "[FeatureHub][Concurrency]") {
|
||||
feature.data = feat.data();
|
||||
HFFaceFeatureIdentity identity = {0};
|
||||
identity.feature = &feature;
|
||||
identity.customId = i;
|
||||
identity.tag = nameBuffer.data();
|
||||
ret = HFFeatureHubInsertFeature(identity);
|
||||
// identity.customId = i;
|
||||
// identity.tag = nameBuffer.data();
|
||||
HFaceId allocId;
|
||||
ret = HFFeatureHubInsertFeature(identity, &allocId);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
}
|
||||
HInt32 totalFace;
|
||||
@@ -372,10 +365,9 @@ TEST_CASE("test_ConcurrencySearch", "[FeatureHub][Concurrency]") {
|
||||
for (int i = 0; i < numberOfSimilar; ++i) {
|
||||
auto index = targetIds[i];
|
||||
HFFaceFeatureIdentity identity = {0};
|
||||
ret = HFFeatureHubGetFaceIdentity(index, &identity);
|
||||
ret = HFFeatureHubGetFaceIdentity(index + 1, &identity);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
std::vector<HFloat> feature(identity.feature->data,
|
||||
identity.feature->data + identity.feature->size);
|
||||
std::vector<HFloat> feature(identity.feature->data, identity.feature->data + identity.feature->size);
|
||||
auto simFeat = SimulateSimilarVector(feature);
|
||||
HFFaceFeature simFeature = {0};
|
||||
simFeature.data = simFeat.data();
|
||||
@@ -427,7 +419,7 @@ TEST_CASE("test_ConcurrencySearch", "[FeatureHub][Concurrency]") {
|
||||
HFloat score;
|
||||
HFFaceFeatureIdentity identity = {0};
|
||||
HFFeatureHubFaceSearch(feature, &score, &identity);
|
||||
CHECK(identity.customId == targetId);
|
||||
REQUIRE(identity.id == targetId + 1);
|
||||
}
|
||||
for (int j = 0; j < 50; ++j) {
|
||||
int idx = dis(gen);
|
||||
@@ -437,7 +429,7 @@ TEST_CASE("test_ConcurrencySearch", "[FeatureHub][Concurrency]") {
|
||||
HFloat score;
|
||||
HFFaceFeatureIdentity identity = {0};
|
||||
HFFeatureHubFaceSearch(feature, &score, &identity);
|
||||
CHECK(identity.customId == -1);
|
||||
REQUIRE(identity.id == -1);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -456,17 +448,17 @@ TEST_CASE("test_FeatureCache", "[FeatureHub][Concurrency]") {
|
||||
TEST_PRINT_OUTPUT(true);
|
||||
|
||||
HResult ret;
|
||||
HFFeatureHubConfiguration configuration = {0};
|
||||
HFFeatureHubConfiguration configuration;
|
||||
auto dbPath = GET_SAVE_DATA(".test");
|
||||
HString dbPathStr = new char[dbPath.size() + 1];
|
||||
std::strcpy(dbPathStr, dbPath.c_str());
|
||||
configuration.primaryKeyMode = HF_PK_AUTO_INCREMENT;
|
||||
configuration.enablePersistence = 1;
|
||||
configuration.dbPath = dbPathStr;
|
||||
configuration.featureBlockNum = 20;
|
||||
configuration.persistenceDbPath = dbPathStr;
|
||||
configuration.searchMode = HF_SEARCH_MODE_EXHAUSTIVE;
|
||||
configuration.searchThreshold = 0.48f;
|
||||
// Delete the previous data before testing
|
||||
if (std::remove(configuration.dbPath) != 0) {
|
||||
if (std::remove(configuration.persistenceDbPath) != 0) {
|
||||
spdlog::trace("Error deleting file");
|
||||
}
|
||||
ret = HFFeatureHubDataEnable(configuration);
|
||||
@@ -478,10 +470,8 @@ TEST_CASE("test_FeatureCache", "[FeatureHub][Concurrency]") {
|
||||
feature.size = randomVec.size();
|
||||
HFFaceFeatureIdentity identity = {0};
|
||||
identity.feature = &feature;
|
||||
identity.tag = "FK";
|
||||
identity.customId = 12;
|
||||
|
||||
ret = HFFeatureHubInsertFeature(identity);
|
||||
HFaceId allocId;
|
||||
ret = HFFeatureHubInsertFeature(identity, &allocId);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
auto simVec = SimulateSimilarVector(randomVec);
|
||||
@@ -491,7 +481,7 @@ TEST_CASE("test_FeatureCache", "[FeatureHub][Concurrency]") {
|
||||
|
||||
for (int i = 0; i < 10; ++i) {
|
||||
HFFaceFeatureIdentity capture = {0};
|
||||
ret = HFFeatureHubGetFaceIdentity(12, &capture);
|
||||
ret = HFFeatureHubGetFaceIdentity(allocId, &capture);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
HFFaceFeature target = {0};
|
||||
@@ -510,108 +500,53 @@ TEST_CASE("test_FeatureCache", "[FeatureHub][Concurrency]") {
|
||||
delete[] dbPathStr;
|
||||
}
|
||||
|
||||
TEST_CASE("test_DataPersistence", "[feature_manage]") {
|
||||
TEST_CASE("test_FeatureHubManualInput", "[FeatureHub][ManualInput]") {
|
||||
DRAW_SPLIT_LINE
|
||||
TEST_PRINT_OUTPUT(true);
|
||||
HResult ret;
|
||||
HFFeatureHubConfiguration configuration;
|
||||
configuration.primaryKeyMode = HF_PK_MANUAL_INPUT;
|
||||
configuration.enablePersistence = 0;
|
||||
TEST_PRINT("Start enable feature hub");
|
||||
ret = HFFeatureHubDataEnable(configuration);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
TEST_PRINT("Enable feature hub success");
|
||||
|
||||
// Generate 10 random feature
|
||||
std::vector<std::vector<HFloat>> features;
|
||||
std::vector<std::string> identities;
|
||||
for (int i = 0; i < 10; ++i) {
|
||||
auto feat = GenerateRandomFeature(512);
|
||||
features.push_back(feat);
|
||||
identities.push_back("id_" + std::to_string(i));
|
||||
std::vector<HFaceId> ids = {10086, 23541, 2124, 24, 204};
|
||||
|
||||
for (auto id : ids) {
|
||||
auto randomVec = GenerateRandomFeature(512);
|
||||
HFFaceFeature feature = {0};
|
||||
feature.data = randomVec.data();
|
||||
feature.size = randomVec.size();
|
||||
HFFaceFeatureIdentity identity = {0};
|
||||
identity.feature = &feature;
|
||||
identity.id = id;
|
||||
HFaceId allocId;
|
||||
ret = HFFeatureHubInsertFeature(identity, &allocId);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
}
|
||||
|
||||
SECTION("Insert") {
|
||||
HResult ret;
|
||||
HFFeatureHubConfiguration configuration = {0};
|
||||
auto dbPath = GET_SAVE_DATA(".test");
|
||||
HString dbPathStr = new char[dbPath.size() + 1];
|
||||
std::strcpy(dbPathStr, dbPath.c_str());
|
||||
configuration.enablePersistence = 1;
|
||||
configuration.dbPath = dbPathStr;
|
||||
configuration.featureBlockNum = 20;
|
||||
configuration.searchMode = HF_SEARCH_MODE_EXHAUSTIVE;
|
||||
configuration.searchThreshold = 0.48f;
|
||||
|
||||
if (std::remove(configuration.dbPath) != 0) {
|
||||
spdlog::trace("Maybe the file does not exist");
|
||||
}
|
||||
|
||||
ret = HFFeatureHubDataEnable(configuration);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
for (size_t i = 0; i < features.size(); i++) {
|
||||
HFFaceFeature feature = {0};
|
||||
feature.data = features[i].data();
|
||||
feature.size = features[i].size();
|
||||
HFFaceFeatureIdentity identity = {0};
|
||||
identity.feature = &feature;
|
||||
identity.tag = const_cast<char *>(identities[i].c_str());
|
||||
identity.customId = i;
|
||||
|
||||
ret = HFFeatureHubInsertFeature(identity);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
// Get the feature from the database
|
||||
HFFaceFeatureIdentity capture = {0};
|
||||
ret = HFFeatureHubGetFaceIdentity(i, &capture);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
// Check the feature
|
||||
HFFaceFeature target = {0};
|
||||
target.data = capture.feature->data;
|
||||
target.size = capture.feature->size;
|
||||
HFloat cosine;
|
||||
ret = HFFaceComparison(target, feature, &cosine);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
REQUIRE(cosine > 0.99f);
|
||||
}
|
||||
// Check number of faces
|
||||
HInt32 count;
|
||||
ret = HFFeatureHubGetFaceCount(&count);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
REQUIRE(count == features.size());
|
||||
|
||||
ret = HFFeatureHubDataDisable();
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
delete[] dbPathStr;
|
||||
HFFeatureHubExistingIds existingIds = {0};
|
||||
ret = HFFeatureHubGetExistingIds(&existingIds);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
REQUIRE(existingIds.size == ids.size());
|
||||
for (int i = 0; i < existingIds.size; ++i) {
|
||||
TEST_PRINT("Existing ID: {}", existingIds.ids[i]);
|
||||
REQUIRE(existingIds.ids[i] == ids[i]);
|
||||
}
|
||||
|
||||
SECTION("Check") {
|
||||
HResult ret;
|
||||
HFFeatureHubConfiguration configuration = {0};
|
||||
auto dbPath = GET_SAVE_DATA(".test");
|
||||
HString dbPathStr = new char[dbPath.size() + 1];
|
||||
std::strcpy(dbPathStr, dbPath.c_str());
|
||||
configuration.enablePersistence = 1;
|
||||
configuration.dbPath = dbPathStr;
|
||||
configuration.featureBlockNum = 20;
|
||||
ret = HFFeatureHubViewDBTable();
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
ret = HFFeatureHubDataEnable(configuration);
|
||||
// query
|
||||
for (auto id : ids) {
|
||||
HFFaceFeatureIdentity query = {0};
|
||||
ret = HFFeatureHubGetFaceIdentity(id, &query);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
// Check number of faces
|
||||
HInt32 count;
|
||||
ret = HFFeatureHubGetFaceCount(&count);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
REQUIRE(count == features.size());
|
||||
|
||||
// Check every face vector
|
||||
for (size_t i = 0; i < features.size(); i++) {
|
||||
HFFaceFeatureIdentity identity = {0};
|
||||
ret = HFFeatureHubGetFaceIdentity(i, &identity);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
REQUIRE(identity.customId == i);
|
||||
REQUIRE(std::string(identity.tag) == identities[i]);
|
||||
REQUIRE(identity.feature->size == features[i].size());
|
||||
}
|
||||
|
||||
ret = HFFeatureHubDataDisable();
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
delete[] dbPathStr;
|
||||
REQUIRE(query.id == id);
|
||||
}
|
||||
|
||||
ret = HFFeatureHubDataDisable();
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
}
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
//
|
||||
// Created by tunm on 2023/10/11.
|
||||
//
|
||||
|
||||
/**
|
||||
* Created by Jingyu Yan
|
||||
* @date 2024-10-01
|
||||
*/
|
||||
#if 0
|
||||
#include <iostream>
|
||||
#include "settings/test_settings.h"
|
||||
#include "inspireface/c_api/inspireface.h"
|
||||
@@ -978,3 +979,4 @@ TEST_CASE("test_FeatureBenchmark", "[feature_benchmark]") {
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -1,14 +1,15 @@
|
||||
//
|
||||
// Created by Tunm-Air13 on 2024/3/20.
|
||||
//
|
||||
/**
|
||||
* Created by Jingyu Yan
|
||||
* @date 2024-10-01
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include "settings/test_settings.h"
|
||||
#include "../test_helper/test_help.h"
|
||||
|
||||
TEST_CASE("test_HelpTools", "[help_tools]") {
|
||||
DRAW_SPLIT_LINE
|
||||
TEST_PRINT_OUTPUT(true);
|
||||
DRAW_SPLIT_LINE
|
||||
TEST_PRINT_OUTPUT(true);
|
||||
|
||||
SECTION("Load lfw funneled data") {
|
||||
#ifdef ISF_ENABLE_USE_LFW_DATA
|
||||
@@ -19,17 +20,17 @@ TEST_CASE("test_HelpTools", "[help_tools]") {
|
||||
HFSession session;
|
||||
ret = HFCreateInspireFaceSession(parameter, detMode, 3, -1, -1, &session);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
HFFeatureHubConfiguration configuration = {0};
|
||||
HFFeatureHubConfiguration configuration;
|
||||
auto dbPath = GET_SAVE_DATA(".test");
|
||||
HString dbPathStr = new char[dbPath.size() + 1];
|
||||
std::strcpy(dbPathStr, dbPath.c_str());
|
||||
configuration.primaryKeyMode = HF_PK_AUTO_INCREMENT;
|
||||
configuration.enablePersistence = 1;
|
||||
configuration.dbPath = dbPathStr;
|
||||
configuration.featureBlockNum = 20;
|
||||
configuration.persistenceDbPath = dbPathStr;
|
||||
configuration.searchMode = HF_SEARCH_MODE_EXHAUSTIVE;
|
||||
configuration.searchThreshold = 0.48f;
|
||||
// Delete the previous data before testing
|
||||
if (std::remove(configuration.dbPath) != 0) {
|
||||
if (std::remove(configuration.persistenceDbPath) != 0) {
|
||||
spdlog::trace("Error deleting file");
|
||||
}
|
||||
ret = HFFeatureHubDataEnable(configuration);
|
||||
@@ -46,8 +47,8 @@ TEST_CASE("test_HelpTools", "[help_tools]") {
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
CHECK(count == numOfNeedImport);
|
||||
|
||||
// ret = HF_ViewFaceDBTable(session);
|
||||
// REQUIRE(ret == HSUCCEED);
|
||||
// ret = HF_ViewFaceDBTable(session);
|
||||
// REQUIRE(ret == HSUCCEED);
|
||||
|
||||
// Finish
|
||||
ret = HFReleaseInspireFaceSession(session);
|
||||
@@ -56,7 +57,7 @@ TEST_CASE("test_HelpTools", "[help_tools]") {
|
||||
ret = HFFeatureHubDataDisable();
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
delete []dbPathStr;
|
||||
delete[] dbPathStr;
|
||||
|
||||
#else
|
||||
TEST_PRINT("The test case that uses LFW is not enabled, so it will be skipped.");
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
|
||||
#include <iostream>
|
||||
#include "settings/test_settings.h"
|
||||
#include "inspireface/c_api/inspireface.h"
|
||||
#include <cstdio>
|
||||
|
||||
TEST_CASE("test_ImageBitmap", "[image_bitmap]") {
|
||||
DRAW_SPLIT_LINE
|
||||
TEST_PRINT_OUTPUT(true);
|
||||
|
||||
HFImageBitmap handle;
|
||||
HResult ret = HFCreateImageBitmapFromFilePath(GET_DATA("data/bulk/r90.jpg").c_str(), 3, &handle);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
HFImageStream stream;
|
||||
ret = HFCreateImageStreamFromImageBitmap(handle, HF_CAMERA_ROTATION_90, &stream);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
HFSessionCustomParameter parameter = {0};
|
||||
HFDetectMode detMode = HF_DETECT_MODE_ALWAYS_DETECT;
|
||||
HFSession session;
|
||||
ret = HFCreateInspireFaceSession(parameter, detMode, 3, -1, -1, &session);
|
||||
TEST_ERROR_PRINT("error ret :{}", ret);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
// Extract basic face information from photos
|
||||
HFMultipleFaceData multipleFaceData = {0};
|
||||
ret = HFExecuteFaceTrack(session, stream, &multipleFaceData);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
REQUIRE(multipleFaceData.detectedNum == 1);
|
||||
|
||||
auto rect = multipleFaceData.rects[0];
|
||||
HColor color = {0, 0, 255};
|
||||
HFImageBitmapDrawRect(handle, rect, color, 2);
|
||||
HFImageBitmapWriteToFile(handle, "bitmap_draw_test.jpg");
|
||||
|
||||
ret = HFReleaseInspireFaceSession(session);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
ret = HFReleaseImageStream(stream);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
ret = HFReleaseImageBitmap(handle);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
}
|
||||
215
cpp-package/inspireface/cpp/test/unit/api/test_image_process.cpp
Normal file
215
cpp-package/inspireface/cpp/test/unit/api/test_image_process.cpp
Normal file
@@ -0,0 +1,215 @@
|
||||
#include <iostream>
|
||||
#include "settings/test_settings.h"
|
||||
#include "inspireface/c_api/inspireface.h"
|
||||
#include <cstdio>
|
||||
|
||||
uint8_t* ReadNV21File(const char* filepath, size_t* fileSize) {
|
||||
FILE* fp = fopen(filepath, "rb");
|
||||
if (!fp) {
|
||||
if (fileSize)
|
||||
*fileSize = 0;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
fseek(fp, 0, SEEK_END);
|
||||
size_t size = ftell(fp);
|
||||
fseek(fp, 0, SEEK_SET);
|
||||
|
||||
uint8_t* data = new uint8_t[size];
|
||||
|
||||
size_t read_size = fread(data, 1, size, fp);
|
||||
fclose(fp);
|
||||
|
||||
if (read_size != size) {
|
||||
delete[] data;
|
||||
if (fileSize)
|
||||
*fileSize = 0;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (fileSize)
|
||||
*fileSize = size;
|
||||
return data;
|
||||
}
|
||||
|
||||
TEST_CASE("test_ImageProcessRotateNV21", "[image_process]") {
|
||||
DRAW_SPLIT_LINE
|
||||
TEST_PRINT_OUTPUT(true);
|
||||
|
||||
HFImageBitmap originBmp;
|
||||
size_t fileSize;
|
||||
uint8_t* data = ReadNV21File(GET_DATA("data/bulk/r0_w330_h409_c3.nv21").c_str(), &fileSize);
|
||||
REQUIRE(data != nullptr);
|
||||
|
||||
HFImageData imageData;
|
||||
imageData.data = data;
|
||||
imageData.width = 330;
|
||||
imageData.height = 409;
|
||||
imageData.rotation = HF_CAMERA_ROTATION_0;
|
||||
imageData.format = HF_STREAM_YUV_NV21;
|
||||
|
||||
HFImageStream stream;
|
||||
HResult ret = HFCreateImageStream(&imageData, &stream);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
ret = HFCreateImageBitmapFromImageStreamProcess(stream, &originBmp, 1, 1.0f);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
HFImageBitmapData originData;
|
||||
ret = HFImageBitmapGetData(originBmp, &originData);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
// compare with eps(0~1)
|
||||
float eps = 0.01;
|
||||
|
||||
SECTION("rotate 90") {
|
||||
size_t fileSize;
|
||||
uint8_t* r90nv21 = ReadNV21File(GET_DATA("data/bulk/r90_w409_h330_c3.nv21").c_str(), &fileSize);
|
||||
REQUIRE(r90nv21 != nullptr);
|
||||
|
||||
HFImageData imageData;
|
||||
imageData.data = r90nv21;
|
||||
imageData.width = 409;
|
||||
imageData.height = 330;
|
||||
imageData.rotation = HF_CAMERA_ROTATION_90;
|
||||
imageData.format = HF_STREAM_YUV_NV21;
|
||||
|
||||
HFImageStream stream;
|
||||
ret = HFCreateImageStream(&imageData, &stream);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
HFImageBitmap rot90;
|
||||
ret = HFCreateImageBitmapFromImageStreamProcess(stream, &rot90, 1, 1.0f);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
// HFImageBitmapShow(rot90, "w", 0);
|
||||
|
||||
HFImageBitmapData rot90Data;
|
||||
ret = HFImageBitmapGetData(rot90, &rot90Data);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
REQUIRE_EQ_IMAGE_WITH_EPS(originData.data, rot90Data.data, originData.height, originData.width, originData.channels, eps);
|
||||
|
||||
ret = HFReleaseImageBitmap(rot90);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
ret = HFReleaseImageStream(stream);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
delete[] r90nv21;
|
||||
}
|
||||
|
||||
ret = HFReleaseImageStream(stream);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
ret = HFReleaseImageBitmap(originBmp);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
delete[] data;
|
||||
}
|
||||
|
||||
TEST_CASE("test_ImageProcessRotate", "[image_process]") {
|
||||
DRAW_SPLIT_LINE
|
||||
TEST_PRINT_OUTPUT(true);
|
||||
|
||||
HFImageBitmap originBmp;
|
||||
HResult ret = HFCreateImageBitmapFromFilePath(GET_DATA("data/bulk/r0.jpg").c_str(), 3, &originBmp);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
HFImageBitmapData originData;
|
||||
ret = HFImageBitmapGetData(originBmp, &originData);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
// compare with eps(0~1)
|
||||
float eps = 0.001;
|
||||
|
||||
SECTION("rotate 90") {
|
||||
HFImageBitmap bitmap;
|
||||
HResult ret = HFCreateImageBitmapFromFilePath(GET_DATA("data/bulk/r90.jpg").c_str(), 3, &bitmap);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
HFImageStream stream;
|
||||
ret = HFCreateImageStreamFromImageBitmap(bitmap, HF_CAMERA_ROTATION_90, &stream);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
HFImageBitmap rot90;
|
||||
ret = HFCreateImageBitmapFromImageStreamProcess(stream, &rot90, 1, 1.0f);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
HFImageBitmapData rot90Data;
|
||||
ret = HFImageBitmapGetData(rot90, &rot90Data);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
REQUIRE_EQ_IMAGE_WITH_EPS(originData.data, rot90Data.data, originData.height, originData.width, originData.channels, eps);
|
||||
|
||||
ret = HFReleaseImageBitmap(rot90);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
ret = HFReleaseImageStream(stream);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
ret = HFReleaseImageBitmap(bitmap);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
}
|
||||
|
||||
SECTION("rotate 180") {
|
||||
HFImageBitmap bitmap;
|
||||
HResult ret = HFCreateImageBitmapFromFilePath(GET_DATA("data/bulk/r180.jpg").c_str(), 3, &bitmap);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
HFImageStream stream;
|
||||
ret = HFCreateImageStreamFromImageBitmap(bitmap, HF_CAMERA_ROTATION_180, &stream);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
HFImageBitmap rot180;
|
||||
ret = HFCreateImageBitmapFromImageStreamProcess(stream, &rot180, 1, 1.0f);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
HFImageBitmapData rot180Data;
|
||||
ret = HFImageBitmapGetData(rot180, &rot180Data);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
REQUIRE_EQ_IMAGE_WITH_EPS(originData.data, rot180Data.data, originData.height, originData.width, originData.channels, eps);
|
||||
|
||||
ret = HFReleaseImageBitmap(rot180);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
ret = HFReleaseImageStream(stream);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
ret = HFReleaseImageBitmap(bitmap);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
}
|
||||
|
||||
SECTION("rotate 270") {
|
||||
HFImageBitmap bitmap;
|
||||
HResult ret = HFCreateImageBitmapFromFilePath(GET_DATA("data/bulk/r270.jpg").c_str(), 3, &bitmap);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
HFImageStream stream;
|
||||
ret = HFCreateImageStreamFromImageBitmap(bitmap, HF_CAMERA_ROTATION_270, &stream);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
HFImageBitmap rot270;
|
||||
ret = HFCreateImageBitmapFromImageStreamProcess(stream, &rot270, 1, 1.0f);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
HFImageBitmapData rot270Data;
|
||||
ret = HFImageBitmapGetData(rot270, &rot270Data);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
REQUIRE_EQ_IMAGE_WITH_EPS(originData.data, rot270Data.data, originData.height, originData.width, originData.channels, eps);
|
||||
|
||||
ret = HFReleaseImageBitmap(rot270);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
ret = HFReleaseImageStream(stream);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
ret = HFReleaseImageBitmap(bitmap);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
}
|
||||
|
||||
ret = HFReleaseImageBitmap(originBmp);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
}
|
||||
@@ -0,0 +1,153 @@
|
||||
/**
|
||||
* Created by Jingyu Yan
|
||||
* @date 2024-10-01
|
||||
*/
|
||||
#include <iostream>
|
||||
#include "settings/test_settings.h"
|
||||
#include "inspireface/c_api/inspireface.h"
|
||||
#include "unit/test_helper/test_help.h"
|
||||
#include "inspireface/middleware/thread/resource_pool.h"
|
||||
#include <thread>
|
||||
|
||||
TEST_CASE("test_SessionParallel", "[Session][Parallel]") {
|
||||
DRAW_SPLIT_LINE
|
||||
TEST_PRINT_OUTPUT(true);
|
||||
|
||||
auto image1 = inspirecv::Image::Create(GET_DATA("data/bulk/kun.jpg"));
|
||||
auto image2 = inspirecv::Image::Create(GET_DATA("data/bulk/jntm.jpg"));
|
||||
|
||||
int loop = 100;
|
||||
|
||||
// Run it once to make sure the similarity is stable
|
||||
HFSessionCustomParameter parameter = {0};
|
||||
parameter.enable_recognition = 1;
|
||||
HFDetectMode detMode = HF_DETECT_MODE_ALWAYS_DETECT;
|
||||
HFSession session;
|
||||
HResult ret = HFCreateInspireFaceSession(parameter, detMode, 3, -1, -1, &session);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
float expectedSimilarity = GenerateRandomNumbers(1, 0, 100)[0] / 100.0f;
|
||||
ret = CompareTwoFaces(session, image1, image2, expectedSimilarity);
|
||||
REQUIRE(ret);
|
||||
TEST_PRINT("Expected similarity: {}", expectedSimilarity);
|
||||
|
||||
ret = HFReleaseInspireFaceSession(session);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
SECTION("Serial") {
|
||||
HResult ret;
|
||||
HFSessionCustomParameter parameter = {0};
|
||||
parameter.enable_recognition = 1;
|
||||
HFDetectMode detMode = HF_DETECT_MODE_ALWAYS_DETECT;
|
||||
HFSession session;
|
||||
ret = HFCreateInspireFaceSession(parameter, detMode, 3, -1, -1, &session);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
float similarity = 0.0f;
|
||||
inspirecv::TimeSpend timeSpend("Serial loop: " + std::to_string(loop));
|
||||
timeSpend.Start();
|
||||
for (int i = 0; i < loop; ++i) {
|
||||
ret = CompareTwoFaces(session, image1, image2, similarity);
|
||||
REQUIRE(ret);
|
||||
REQUIRE(similarity == Approx(expectedSimilarity).epsilon(0.01));
|
||||
}
|
||||
timeSpend.Stop();
|
||||
std::cout << timeSpend << std::endl;
|
||||
|
||||
ret = HFReleaseInspireFaceSession(session);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
}
|
||||
|
||||
SECTION("Parallel") {
|
||||
int N = 4; // Use 4 sessions in parallel
|
||||
#ifdef ISF_RKNPU_RV1106
|
||||
N = 1; // Use 1 session in parallel
|
||||
#endif
|
||||
inspire::parallel::ResourcePool<HFSession> sessionPool(N, [](HFSession& session) {
|
||||
auto ret = HFReleaseInspireFaceSession(session);
|
||||
if (ret != HSUCCEED) {
|
||||
TEST_ERROR_PRINT("Failed to release session: {}", ret);
|
||||
}
|
||||
});
|
||||
|
||||
// Example Initialize N sessions to the resource pool
|
||||
for (int i = 0; i < N; ++i) {
|
||||
HFSessionCustomParameter parameter = {0};
|
||||
parameter.enable_recognition = 1;
|
||||
HFSession session;
|
||||
HResult ret = HFCreateInspireFaceSession(parameter, HF_DETECT_MODE_ALWAYS_DETECT, 3, -1, -1, &session);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
sessionPool.AddResource(std::move(session));
|
||||
}
|
||||
|
||||
// Create a thread pool to execute a task
|
||||
std::vector<std::thread> threads;
|
||||
std::atomic<int> completed(0);
|
||||
float similaritySum = 0.0f;
|
||||
std::mutex similarityMutex;
|
||||
|
||||
inspirecv::TimeSpend timeSpend("Parallel loop: " + std::to_string(loop) + ", thread: " + std::to_string(N));
|
||||
timeSpend.Start();
|
||||
|
||||
// Start worker thread
|
||||
int tasksPerThread = loop / N;
|
||||
int remainingTasks = loop % N;
|
||||
|
||||
for (int i = 0; i < N; ++i) {
|
||||
int taskCount = tasksPerThread + (i < remainingTasks ? 1 : 0);
|
||||
threads.emplace_back([&, taskCount]() {
|
||||
for (int j = 0; j < taskCount; ++j) {
|
||||
auto sessionGuard = sessionPool.AcquireResource();
|
||||
float similarity = 0.0f;
|
||||
HResult ret = CompareTwoFaces(*sessionGuard, image1, image2, similarity);
|
||||
REQUIRE(ret);
|
||||
|
||||
REQUIRE(similarity == Approx(expectedSimilarity).epsilon(0.01));
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(similarityMutex);
|
||||
similaritySum += similarity;
|
||||
}
|
||||
|
||||
completed++;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Wait for all threads to complete
|
||||
for (auto& thread : threads) {
|
||||
thread.join();
|
||||
}
|
||||
|
||||
timeSpend.Stop();
|
||||
std::cout << timeSpend << std::endl;
|
||||
|
||||
// Optional: Output average similarity(stability)
|
||||
TEST_PRINT("Average similarity: {}", (similaritySum / loop));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("test_SessionParallel_Memory", "[Session][Parallel][Memory]") {
|
||||
size_t memoryUsage = getCurrentMemoryUsage();
|
||||
TEST_PRINT("Current memory usage: {}MB", memoryUsage);
|
||||
int loop = 4;
|
||||
#ifdef ISF_RKNPU_RV1106
|
||||
loop = 1;
|
||||
#endif
|
||||
std::vector<HFSession> sessions;
|
||||
for (int i = 0; i < loop; ++i) {
|
||||
HFSessionCustomParameter parameter = {0};
|
||||
parameter.enable_recognition = 1;
|
||||
HFSession session;
|
||||
HResult ret = HFCreateInspireFaceSession(parameter, HF_DETECT_MODE_ALWAYS_DETECT, 3, -1, -1, &session);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
sessions.push_back(session);
|
||||
size_t memoryUsage = getCurrentMemoryUsage();
|
||||
TEST_PRINT("[alloc{}] Current memory usage: {}MB", i + 1, memoryUsage);
|
||||
}
|
||||
// Release all sessions
|
||||
for (int i = 0; i < loop; ++i) {
|
||||
auto ret = HFReleaseInspireFaceSession(sessions[i]);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
size_t memoryUsage = getCurrentMemoryUsage();
|
||||
TEST_PRINT("[free{}] Current memory usage: {}MB", i + 1, memoryUsage);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
/**
|
||||
* Created by Jingyu Yan
|
||||
* @date 2025-01-20
|
||||
*/
|
||||
#include <iostream>
|
||||
#include "settings/test_settings.h"
|
||||
#include "unit/test_helper/test_help.h"
|
||||
#include "inspireface/recognition_module/similarity_converter.h"
|
||||
|
||||
TEST_CASE("test_similarity_converter", "[similarity_converter]") {
|
||||
DRAW_SPLIT_LINE
|
||||
TEST_PRINT_OUTPUT(true);
|
||||
|
||||
SECTION("test_similarity_converter_0.42") {
|
||||
inspire::SimilarityConverterConfig config;
|
||||
config.threshold = 0.42;
|
||||
config.middleScore = 0.6;
|
||||
config.steepness = 8.0;
|
||||
config.outputMin = 0.01;
|
||||
config.outputMax = 1.0;
|
||||
inspire::SimilarityConverter similarity_converter(config);
|
||||
std::vector<double> test_points = {-0.80, -0.20, 0.02, 0.10, 0.25, 0.30, 0.48, 0.70, 0.80, 0.90, 1.00};
|
||||
std::vector<double> expected_scores = {0.0101, 0.0201, 0.0661, 0.1113, 0.2819, 0.3673, 0.7074, 0.9334, 0.9689, 0.9858, 0.9936};
|
||||
REQUIRE(test_points.size() == expected_scores.size());
|
||||
|
||||
for (size_t i = 0; i < test_points.size(); ++i) {
|
||||
double cosine = test_points[i];
|
||||
double similarity = similarity_converter.convert(cosine);
|
||||
REQUIRE(similarity == Approx(expected_scores[i]).epsilon(0.01));
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("test_similarity_converter_0.32") {
|
||||
inspire::SimilarityConverterConfig config;
|
||||
config.threshold = 0.32;
|
||||
config.middleScore = 0.6;
|
||||
config.steepness = 10.0;
|
||||
config.outputMin = 0.02;
|
||||
config.outputMax = 1.0;
|
||||
inspire::SimilarityConverter similarity_converter(config);
|
||||
std::vector<double> test_points = {-0.80, -0.20, 0.02, 0.10, 0.25, 0.32, 0.50, 0.70, 0.80, 0.90, 1.00};
|
||||
std::vector<double> expected_scores = {0.0200, 0.0278, 0.0860, 0.1557, 0.4302, 0.6000, 0.8997, 0.9851, 0.9945, 0.9980, 0.9992};
|
||||
REQUIRE(test_points.size() == expected_scores.size());
|
||||
|
||||
for (size_t i = 0; i < test_points.size(); ++i) {
|
||||
double cosine = test_points[i];
|
||||
double similarity = similarity_converter.convert(cosine);
|
||||
REQUIRE(similarity == Approx(expected_scores[i]).epsilon(0.01));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
#if 0
|
||||
#include <iostream>
|
||||
#include "settings/test_settings.h"
|
||||
#include "inspireface/c_api/inspireface.h"
|
||||
@@ -265,4 +266,6 @@ TEST_CASE("test_SystemStreamReleaseCase", "[system]") {
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
REQUIRE(count == 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user