mirror of
https://github.com/deepinsight/insightface.git
synced 2026-07-18 03:47:52 +00:00
Add the inspireface project to cpp-package.
This commit is contained in:
@@ -0,0 +1,75 @@
|
||||
//
|
||||
// Created by Tunm-Air13 on 2024/2/2.
|
||||
//
|
||||
|
||||
#include "settings/test_settings.h"
|
||||
#include "inspireface/face_context.h"
|
||||
#include "common/face_data/data_tools.h"
|
||||
#include "../test_helper/test_tools.h"
|
||||
#include "herror.h"
|
||||
|
||||
using namespace inspire;
|
||||
|
||||
TEST_CASE("test_CameraStream", "[camera_stream") {
|
||||
DRAW_SPLIT_LINE
|
||||
TEST_PRINT_OUTPUT(true);
|
||||
|
||||
SECTION("DecodingRotatedImages") {
|
||||
FaceContext ctx;
|
||||
CustomPipelineParameter param;
|
||||
auto ret = ctx.Configuration(DetectMode::DETECT_MODE_IMAGE, 1, param);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
std::vector<std::string> rotated_filename_list = {
|
||||
getTestData("images/rotate/rot_0.jpg"),
|
||||
getTestData("images/rotate/rot_90.jpg"),
|
||||
getTestData("images/rotate/rot_180.jpg"),
|
||||
getTestData("images/rotate/rot_270.jpg"),
|
||||
};
|
||||
std::vector<ROTATION_MODE> rotate_list = {ROTATION_0, ROTATION_90, ROTATION_180, ROTATION_270};
|
||||
|
||||
CHECK(rotate_list.size() == rotated_filename_list.size());
|
||||
|
||||
for (int i = 0; i < rotate_list.size(); ++i) {
|
||||
cv::Mat image = cv::imread(rotated_filename_list[i]);
|
||||
REQUIRE(!image.empty());
|
||||
auto rotated = rotate_list[i];
|
||||
|
||||
CameraStream stream;
|
||||
stream.SetDataBuffer(image.data, image.rows, image.cols);
|
||||
stream.SetDataFormat(BGR);
|
||||
stream.SetRotationMode(rotated);
|
||||
|
||||
ret = ctx.FaceDetectAndTrack(stream);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
const auto &faces = ctx.GetTrackingFaceList();
|
||||
CHECK(faces.size() == 1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
SECTION("DecodingNV21Image") {
|
||||
FaceContext ctx;
|
||||
CustomPipelineParameter param;
|
||||
auto ret = ctx.Configuration(DetectMode::DETECT_MODE_IMAGE, 1, param);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
int32_t width = 402;
|
||||
int32_t height = 324;
|
||||
auto rotated = ROTATION_90;
|
||||
auto format = NV21;
|
||||
auto nv21 = ReadNV21Data(getTestData("images/rotate/rot_90_324x402.nv21").c_str(), width, height);
|
||||
REQUIRE(nv21 != nullptr);
|
||||
|
||||
CameraStream stream;
|
||||
stream.SetDataBuffer(nv21, height, width);
|
||||
stream.SetDataFormat(format);
|
||||
stream.SetRotationMode(rotated);
|
||||
|
||||
ret = ctx.FaceDetectAndTrack(stream);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
const auto &faces = ctx.GetTrackingFaceList();
|
||||
CHECK(faces.size() == 1);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
//
|
||||
// Created by tunm on 2023/9/16.
|
||||
//
|
||||
|
||||
#include "settings/test_settings.h"
|
||||
#include "inspireface/face_context.h"
|
||||
#include "herror.h"
|
||||
|
||||
using namespace inspire;
|
||||
|
||||
TEST_CASE("test_FaceDetectTrack", "[face_track]") {
|
||||
DRAW_SPLIT_LINE
|
||||
TEST_PRINT_OUTPUT(true);
|
||||
|
||||
SECTION("TrackBenchmark") {
|
||||
// Initialize
|
||||
FaceContext ctx;
|
||||
CustomPipelineParameter param;
|
||||
param.enable_face_quality = true;
|
||||
auto ret = ctx.Configuration(DetectMode::DETECT_MODE_VIDEO, 1, param);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
// Prepare a picture of a face
|
||||
auto image = cv::imread(GET_DATA("images/face_sample.png"));
|
||||
CameraStream stream;
|
||||
stream.SetDataFormat(BGR);
|
||||
stream.SetRotationMode(ROTATION_0);
|
||||
stream.SetDataBuffer(image.data, image.rows, image.cols);
|
||||
|
||||
const auto loop = 1000;
|
||||
double total = 0.0f;
|
||||
spdlog::info("begin {} times tracking: ", loop);
|
||||
|
||||
auto out = (double) cv::getTickCount();
|
||||
for (int i = 0; i < loop; ++i) {
|
||||
auto timeStart = (double) cv::getTickCount();
|
||||
// Face detection
|
||||
ctx.FaceDetectAndTrack(stream);
|
||||
auto &faces = ctx.GetTrackingFaceList();
|
||||
double cost = ((double) cv::getTickCount() - timeStart) / cv::getTickFrequency() * 1000;
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
REQUIRE(faces.size() > 0);
|
||||
total += cost;
|
||||
}
|
||||
auto end = ((double) cv::getTickCount() - out) / cv::getTickFrequency() * 1000;
|
||||
|
||||
spdlog::info("[Face Tracking]{} times, Total cost: {}ms, Average cost: {}ms", loop, end, total / loop);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
//
|
||||
// Created by tunm on 2023/9/17.
|
||||
//
|
||||
|
||||
#include "settings/test_settings.h"
|
||||
#include "inspireface/common/face_data/data_tools.h"
|
||||
#include "herror.h"
|
||||
#include "inspireface/face_context.h"
|
||||
|
||||
using namespace inspire;
|
||||
|
||||
TEST_CASE("test_FaceData", "[face_data]") {
|
||||
DRAW_SPLIT_LINE
|
||||
TEST_PRINT_OUTPUT(true);
|
||||
|
||||
SECTION("DataConversion") {
|
||||
// Initialize
|
||||
FaceContext ctx;
|
||||
CustomPipelineParameter param;
|
||||
param.enable_face_quality = true;
|
||||
auto ret = ctx.Configuration(DetectMode::DETECT_MODE_VIDEO, 1, param);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
// Prepare a picture of a face
|
||||
auto image = cv::imread(GET_DATA("images/face_sample.png"));
|
||||
CameraStream stream;
|
||||
stream.SetDataFormat(BGR);
|
||||
stream.SetRotationMode(ROTATION_0);
|
||||
stream.SetDataBuffer(image.data, image.rows, image.cols);
|
||||
|
||||
ctx.FaceDetectAndTrack(stream);
|
||||
auto &faces = ctx.GetTrackingFaceList();
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
REQUIRE(faces.size() > 0);
|
||||
|
||||
HyperFaceData faceData = FaceObjectToHyperFaceData(faces[0], 0);
|
||||
|
||||
std::cout << faces[0].getTransMatrix() << std::endl;
|
||||
|
||||
PrintHyperFaceData(faceData);
|
||||
|
||||
ByteArray byteArray;
|
||||
INSPIRE_LOGD("sizeof: %lu", sizeof(byteArray));
|
||||
ret = SerializeHyperFaceData(faceData, byteArray);
|
||||
CHECK(ret == HSUCCEED);
|
||||
INSPIRE_LOGD("sizeof: %lu", sizeof(byteArray));
|
||||
|
||||
|
||||
HyperFaceData decode;
|
||||
ret = DeserializeHyperFaceData(byteArray, decode);
|
||||
CHECK(ret == HSUCCEED);
|
||||
PrintHyperFaceData(decode);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,185 @@
|
||||
//
|
||||
// Created by Tunm-Air13 on 2023/9/12.
|
||||
//
|
||||
|
||||
#include "settings/test_settings.h"
|
||||
#include "inspireface/face_context.h"
|
||||
#include "herror.h"
|
||||
#include "../test_helper/test_help.h"
|
||||
#include "feature_hub/feature_hub.h"
|
||||
|
||||
using namespace inspire;
|
||||
|
||||
TEST_CASE("test_FaceFeatureManagement", "[face_feature]") {
|
||||
DRAW_SPLIT_LINE
|
||||
TEST_PRINT_OUTPUT(true);
|
||||
|
||||
SECTION("FeatureCURD") {
|
||||
DRAW_SPLIT_LINE
|
||||
// Initialize
|
||||
FaceContext ctx;
|
||||
CustomPipelineParameter param;
|
||||
param.enable_recognition = true;
|
||||
auto ret = ctx.Configuration(DetectMode::DETECT_MODE_IMAGE, 1, param);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
FEATURE_HUB->PrintFeatureMatrixInfo();
|
||||
|
||||
// Know the location of 'kunkun' in advance
|
||||
int32_t KunkunIndex = 795;
|
||||
// Prepare a face photo in advance and extract the features
|
||||
auto image = cv::imread(GET_DATA("images/kun.jpg"));
|
||||
CameraStream stream;
|
||||
stream.SetDataFormat(BGR);
|
||||
stream.SetRotationMode(ROTATION_0);
|
||||
stream.SetDataBuffer(image.data, image.rows, image.cols);
|
||||
ret = ctx.FaceDetectAndTrack(stream);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
// Face detection
|
||||
ctx.FaceDetectAndTrack(stream);
|
||||
const auto &faces = ctx.GetTrackingFaceList();
|
||||
REQUIRE(faces.size() > 0);
|
||||
// Feature extraction of "Kunkun" was carried out
|
||||
Embedded feature;
|
||||
ret = ctx.FaceRecognitionModule()->FaceExtract(stream, faces[0], feature);
|
||||
CHECK(ret == HSUCCEED);
|
||||
|
||||
// Import face feature vectors in batches
|
||||
String mat_path = GET_DATA("test_faceset/test_faces_A1.npy");
|
||||
String tags_path = GET_DATA("test_faceset/test_faces_A1.txt");
|
||||
auto result = LoadMatrixAndTags(mat_path, tags_path);
|
||||
// Gets the feature matrix and label names
|
||||
EmbeddedList featureMatrix = result.first;
|
||||
std::vector<std::string> tagNames = result.second;
|
||||
REQUIRE(featureMatrix.size() == 3000);
|
||||
REQUIRE(tagNames.size() == 3000);
|
||||
REQUIRE(featureMatrix[0].size() == 512);
|
||||
|
||||
for (int i = 0; i < featureMatrix.size(); ++i) {
|
||||
auto &feat = featureMatrix[i];
|
||||
auto ret = FEATURE_HUB->RegisterFaceFeature(feat, i, tagNames[i], i);
|
||||
CHECK(ret == HSUCCEED);
|
||||
}
|
||||
|
||||
std::cout << std::endl;
|
||||
REQUIRE(FEATURE_HUB->GetFaceFeatureCount() == 3000);
|
||||
spdlog::trace("All 3000 Faces embedded vector are loaded");
|
||||
|
||||
// Prepare a face photo to search through the library
|
||||
SearchResult searchResult;
|
||||
ret = FEATURE_HUB->SearchFaceFeature(feature, searchResult, 0.5f);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
CHECK(searchResult.index != -1);
|
||||
CHECK(searchResult.index == KunkunIndex);
|
||||
CHECK(searchResult.tag == "Kunkun");
|
||||
CHECK(searchResult.score == Approx(0.76096).epsilon(1e-3));
|
||||
spdlog::info("Find Kunkun -> Location ID: {}, Confidence: {}, Tag: {}", searchResult.index, searchResult.score, searchResult.tag.c_str());
|
||||
// Save "Kunkun"'s library features and so on
|
||||
Embedded KunkunFeature;
|
||||
ret = FEATURE_HUB->GetFaceFeature(KunkunIndex, KunkunFeature);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
// The features of "Kunkun" library corresponding to those found above are deleted from the face library
|
||||
ret = FEATURE_HUB->DeleteFaceFeature(searchResult.index);
|
||||
CHECK(ret == HSUCCEED);
|
||||
// In search once
|
||||
SearchResult secondSearchResult;
|
||||
ret = FEATURE_HUB->SearchFaceFeature(feature, secondSearchResult, 0.5f);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
CHECK(secondSearchResult.index == -1);
|
||||
spdlog::info("Kunkun被删除了无法找到: {}, {}", secondSearchResult.index, secondSearchResult.tag);
|
||||
|
||||
// Just take a random place and change the eigenvector for that place and put "Kunkun" back in there
|
||||
auto newIndex = 2888;
|
||||
// Try inserting an unused location first
|
||||
ret = FEATURE_HUB->UpdateFaceFeature(KunkunFeature, 3001, "Chicken", 3001);
|
||||
REQUIRE(ret == HERR_SESS_REC_BLOCK_UPDATE_FAILURE);
|
||||
ret = FEATURE_HUB->UpdateFaceFeature(KunkunFeature, newIndex, "Chicken", 3001);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
SearchResult thirdlySearchResult;
|
||||
ret = FEATURE_HUB->SearchFaceFeature(feature, thirdlySearchResult, 0.5f);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
CHECK(thirdlySearchResult.index != -1);
|
||||
CHECK(thirdlySearchResult.index == newIndex);
|
||||
CHECK(thirdlySearchResult.tag == "Chicken");
|
||||
spdlog::info("Find Kunkun again -> New Location ID: {}, Confidence: {}, Tag: {}", thirdlySearchResult.index, thirdlySearchResult.score, thirdlySearchResult.tag.c_str());
|
||||
|
||||
}
|
||||
|
||||
#if ENABLE_BENCHMARK
|
||||
SECTION("FeatureSearchBenchmark") {
|
||||
DRAW_SPLIT_LINE
|
||||
|
||||
// Initialize
|
||||
FaceContext ctx;
|
||||
CustomPipelineParameter param;
|
||||
param.enable_recognition = true;
|
||||
auto ret = ctx.Configuration(DetectMode::DETECT_MODE_IMAGE, 1, param);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
FEATURE_HUB->PrintFeatureMatrixInfo();
|
||||
|
||||
// Import face feature vectors in batches
|
||||
String mat_path = GET_DATA("test_faceset/test_faces_A1.npy");
|
||||
String tags_path = GET_DATA("test_faceset/test_faces_A1.txt");
|
||||
auto result = LoadMatrixAndTags(mat_path, tags_path);
|
||||
// Gets the feature matrix and label names
|
||||
EmbeddedList featureMatrix = result.first;
|
||||
std::vector<std::string> tagNames = result.second;
|
||||
REQUIRE(featureMatrix.size() == 3000);
|
||||
REQUIRE(tagNames.size() == 3000);
|
||||
REQUIRE(featureMatrix[0].size() == 512);
|
||||
|
||||
for (int i = 0; i < featureMatrix.size(); ++i) {
|
||||
auto &feat = featureMatrix[i];
|
||||
auto ret = FEATURE_HUB->RegisterFaceFeature(feat, i, tagNames[i], i);
|
||||
CHECK(ret == HSUCCEED);
|
||||
}
|
||||
|
||||
std::cout << std::endl;
|
||||
REQUIRE(FEATURE_HUB->GetFaceFeatureCount() == 3000);
|
||||
spdlog::trace("3000个特征向量全部载入");
|
||||
|
||||
// Prepare a picture of a face
|
||||
auto image = cv::imread(GET_DATA("images/face_sample.png"));
|
||||
CameraStream stream;
|
||||
stream.SetDataFormat(BGR);
|
||||
stream.SetRotationMode(ROTATION_0);
|
||||
stream.SetDataBuffer(image.data, image.rows, image.cols);
|
||||
ret = ctx.FaceDetectAndTrack(stream);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
// Face detection
|
||||
ctx.FaceDetectAndTrack(stream);
|
||||
const auto &faces = ctx.GetTrackingFaceList();
|
||||
REQUIRE(faces.size() > 0);
|
||||
// Feature extraction of "kunkun" was carried out
|
||||
Embedded feature;
|
||||
ret = ctx.FaceRecognitionModule()->FaceExtract(stream, faces[0], feature);
|
||||
CHECK(ret == HSUCCEED);
|
||||
|
||||
// Insert the face further back
|
||||
auto regIndex = 4000;
|
||||
ret = FEATURE_HUB->RegisterFaceFeature(feature, regIndex, "test", 4000);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
const auto loop = 1000;
|
||||
double total = 0.0f;
|
||||
spdlog::info("Start performing {} searches: ", loop);
|
||||
auto out = (double) cv::getTickCount();
|
||||
for (int i = 0; i < loop; ++i) {
|
||||
|
||||
// Prepare a face photo to look it up from the library
|
||||
SearchResult searchResult;
|
||||
auto timeStart = (double) cv::getTickCount();
|
||||
ret = FEATURE_HUB->SearchFaceFeature(feature, searchResult, 0.5f);
|
||||
double cost = ((double) cv::getTickCount() - timeStart) / cv::getTickFrequency() * 1000;
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
CHECK(searchResult.index == regIndex);
|
||||
total += cost;
|
||||
}
|
||||
auto end = ((double) cv::getTickCount() - out) / cv::getTickFrequency() * 1000;
|
||||
|
||||
spdlog::info("Execute {} times Total Cost: {}ms, Average Cost: {}ms", loop, end, total / loop);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
//
|
||||
// Created by tunm on 2023/9/13.
|
||||
//
|
||||
|
||||
#include "settings/test_settings.h"
|
||||
#include "inspireface/face_context.h"
|
||||
#include "herror.h"
|
||||
|
||||
using namespace inspire;
|
||||
|
||||
TEST_CASE("test_FacePipeline", "[face_pipe") {
|
||||
DRAW_SPLIT_LINE
|
||||
TEST_PRINT_OUTPUT(true);
|
||||
|
||||
|
||||
SECTION("FaceContextInit") {
|
||||
FaceContext ctx;
|
||||
CustomPipelineParameter param;
|
||||
auto ret = ctx.Configuration(DetectMode::DETECT_MODE_IMAGE, 1, param);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
}
|
||||
|
||||
SECTION("FaceContextMaskPredict") {
|
||||
FaceContext ctx;
|
||||
CustomPipelineParameter param;
|
||||
param.enable_mask_detect = true;
|
||||
auto ret = ctx.Configuration(DetectMode::DETECT_MODE_IMAGE, 1, param);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
{
|
||||
// Prepare a photo of your face without a mask
|
||||
auto image = cv::imread(GET_DATA("images/kun.jpg"));
|
||||
CameraStream stream;
|
||||
stream.SetDataFormat(BGR);
|
||||
stream.SetRotationMode(ROTATION_0);
|
||||
stream.SetDataBuffer(image.data, image.rows, image.cols);
|
||||
ret = ctx.FaceDetectAndTrack(stream);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
// Face detection
|
||||
ctx.FaceDetectAndTrack(stream);
|
||||
auto &faces = ctx.GetTrackingFaceList();
|
||||
REQUIRE(faces.size() > 0);
|
||||
auto &face = faces[0];
|
||||
ctx.FacePipelineModule()->Process(stream, face);
|
||||
CHECK(face.faceProcess.maskInfo == MaskInfo::UNMASKED);
|
||||
}
|
||||
{
|
||||
// Prepare a face picture with a mask in advance
|
||||
auto image = cv::imread(GET_DATA("images/mask.png"));
|
||||
CameraStream stream;
|
||||
stream.SetDataFormat(BGR);
|
||||
stream.SetRotationMode(ROTATION_0);
|
||||
stream.SetDataBuffer(image.data, image.rows, image.cols);
|
||||
ret = ctx.FaceDetectAndTrack(stream);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
// Face detection
|
||||
ctx.FaceDetectAndTrack(stream);
|
||||
auto &faces = ctx.GetTrackingFaceList();
|
||||
REQUIRE(faces.size() > 0);
|
||||
auto &face = faces[0];
|
||||
ctx.FacePipelineModule()->Process(stream, face);
|
||||
CHECK(face.faceProcess.maskInfo == MaskInfo::MASKED);
|
||||
}
|
||||
|
||||
|
||||
SECTION("FaceContextLiveness") {
|
||||
FaceContext ctx;
|
||||
CustomPipelineParameter param;
|
||||
param.enable_liveness = true;
|
||||
auto ret = ctx.Configuration(DetectMode::DETECT_MODE_IMAGE, 1, param);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
{
|
||||
// Prepare realistic face images
|
||||
auto image = cv::imread(GET_DATA("images/face_sample.png"));
|
||||
CameraStream stream;
|
||||
stream.SetDataFormat(BGR);
|
||||
stream.SetRotationMode(ROTATION_0);
|
||||
stream.SetDataBuffer(image.data, image.rows, image.cols);
|
||||
ret = ctx.FaceDetectAndTrack(stream);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
// Face detection
|
||||
ctx.FaceDetectAndTrack(stream);
|
||||
auto &faces = ctx.GetTrackingFaceList();
|
||||
REQUIRE(faces.size() > 0);
|
||||
auto &face = faces[0];
|
||||
ctx.FacePipelineModule()->Process(stream, face);
|
||||
CHECK(face.faceProcess.rgbLivenessInfo == RGBLivenessInfo::LIVENESS_REAL);
|
||||
}
|
||||
|
||||
{
|
||||
// Prepare a fake photo that wasn't actually taken
|
||||
auto image = cv::imread(GET_DATA("images/rgb_fake.jpg"));
|
||||
CameraStream stream;
|
||||
stream.SetDataFormat(BGR);
|
||||
stream.SetRotationMode(ROTATION_0);
|
||||
stream.SetDataBuffer(image.data, image.rows, image.cols);
|
||||
ret = ctx.FaceDetectAndTrack(stream);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
// Face detection
|
||||
ctx.FaceDetectAndTrack(stream);
|
||||
auto &faces = ctx.GetTrackingFaceList();
|
||||
REQUIRE(faces.size() > 0);
|
||||
auto &face = faces[0];
|
||||
ctx.FacePipelineModule()->Process(stream, face);
|
||||
CHECK(face.faceProcess.rgbLivenessInfo == RGBLivenessInfo::LIVENESS_FAKE);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
//
|
||||
// Created by Tunm-Air13 on 2023/9/12.
|
||||
//
|
||||
|
||||
#include "settings/test_settings.h"
|
||||
#include "inspireface/face_context.h"
|
||||
#include "herror.h"
|
||||
#include "common/face_data/data_tools.h"
|
||||
#include "feature_hub/feature_hub.h"
|
||||
|
||||
using namespace inspire;
|
||||
|
||||
TEST_CASE("test_FaceRecognition", "[face_rec]") {
|
||||
DRAW_SPLIT_LINE
|
||||
TEST_PRINT_OUTPUT(true);
|
||||
|
||||
|
||||
SECTION("FaceContextInit") {
|
||||
FaceContext ctx;
|
||||
CustomPipelineParameter param;
|
||||
param.enable_recognition = true;
|
||||
auto ret = ctx.Configuration(DetectMode::DETECT_MODE_IMAGE, 1, param);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
}
|
||||
|
||||
SECTION("FaceRecognitionOption") {
|
||||
FaceContext ctx;
|
||||
CustomPipelineParameter param;
|
||||
param.enable_recognition = false; // Disable the face recognition function
|
||||
auto ret = ctx.Configuration(DetectMode::DETECT_MODE_IMAGE, 1, param);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
auto image = cv::imread(GET_DATA("images/cxk.jpg"));
|
||||
CameraStream stream;
|
||||
stream.SetDataFormat(BGR);
|
||||
stream.SetRotationMode(ROTATION_0);
|
||||
stream.SetDataBuffer(image.data, image.rows, image.cols);
|
||||
ret = ctx.FaceDetectAndTrack(stream);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
ctx.FaceDetectAndTrack(stream);
|
||||
const auto &faces = ctx.GetTrackingFaceList();
|
||||
REQUIRE(faces.size() > 0);
|
||||
Embedded feature;
|
||||
ret = ctx.FaceRecognitionModule()->FaceExtract(stream, faces[0], feature);
|
||||
CHECK(ret == HERR_SESS_REC_EXTRACT_FAILURE);
|
||||
}
|
||||
|
||||
SECTION("FaceRecognition1v1") {
|
||||
FaceContext ctx;
|
||||
CustomPipelineParameter param;
|
||||
param.enable_recognition = true;
|
||||
auto ret = ctx.Configuration(DetectMode::DETECT_MODE_IMAGE, 1, param);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
|
||||
std::vector<std::string> list = {
|
||||
GET_DATA("images/kun.jpg"),
|
||||
GET_DATA("images/Kunkun.jpg"),
|
||||
};
|
||||
EmbeddedList vectors;
|
||||
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
auto image = cv::imread(list[i]);
|
||||
REQUIRE(!image.empty());
|
||||
CameraStream stream;
|
||||
stream.SetDataFormat(BGR);
|
||||
stream.SetRotationMode(ROTATION_0);
|
||||
stream.SetDataBuffer(image.data, image.rows, image.cols);
|
||||
ret = ctx.FaceDetectAndTrack(stream);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
ctx.FaceDetectAndTrack(stream);
|
||||
const auto &faces = ctx.GetTrackingFaceList();
|
||||
REQUIRE(faces.size() > 0);
|
||||
Embedded feature;
|
||||
HyperFaceData data = FaceObjectToHyperFaceData(faces[0]);
|
||||
ret = ctx.FaceRecognitionModule()->FaceExtract(stream, data, feature);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
vectors.push_back(feature);
|
||||
}
|
||||
float score;
|
||||
ret = FEATURE_HUB->CosineSimilarity(vectors[1], vectors[0], score);
|
||||
REQUIRE(ret == HSUCCEED);
|
||||
// spdlog::info("score: {}", score);
|
||||
CHECK(0.7623623013 == Approx(score).epsilon(1e-2));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user