Fix mixed UTF16 issue (LabVIEW) and fix ANSFR for Intel

This commit is contained in:
2026-04-08 08:47:10 +10:00
parent 866e0282e2
commit a4a8caaa86
10 changed files with 594 additions and 38 deletions

View File

@@ -18,6 +18,7 @@
#include <string>
#include <chrono>
#include <thread>
#include <iomanip>
#include "ANSFR.h"
#include "fastdeploy/vision.h"
#include "ANSFilePlayer.h"
@@ -820,6 +821,317 @@ int ANSVISTest() {
return 0;
}
// ANSVISTestCPU — CPU-only variant of ANSVISTest for Intel CPU PCs without NVIDIA GPU.
// Uses CPU face detector model and forces precision=0 (FP32) for ONNX Runtime / OpenVINO.
int ANSVISTestCPU() {
boost::property_tree::ptree pt;
std::string databaseFilePath = "C:\\ProgramData\\ANSCENTER\\ANSVIS Server\\ANSFR\\ANSFR.db";
std::string recognizerFilePath = "C:\\ProgramData\\ANSCENTER\\ANSVIS Server\\ANSFR\\ANS_FaceRecognizer_v1.1.zip";
std::string facedetectorFilePath = "C:\\ProgramData\\ANSCENTER\\ANSVIS Server\\ANSFDET\\ANS_GenericFD(CPU)_v1.0.zip";
std::string videoFilePath = "C:\\ProgramData\\ANSCENTER\\Shared\\classroom.mp4";
const char* configFilePath = "";
ANSCENTER::ANSFacialRecognition* infHandle = nullptr;
std::string licenseKey = "";
int enableHeadPose = 1;
int enableFaceLiveness = 1;
int enableAgeGender = 1;
int enableEmotion = 1;
int enableAntispoofing = 1;
int precision = 0; // FP32
std::cout << "=== ANSVISTestCPU ===" << std::endl;
std::cout << "Database: " << databaseFilePath << std::endl;
std::cout << "Recognizer: " << recognizerFilePath << std::endl;
std::cout << "FaceDetector: " << facedetectorFilePath << std::endl;
std::cout << "Video: " << videoFilePath << std::endl;
// Step 1: Create handle
std::cout << "[CPU Test] Step 1: Creating handle..." << std::endl;
int result = CreateANSRFHandle(&infHandle,
licenseKey.c_str(),
configFilePath,
databaseFilePath.c_str(),
recognizerFilePath.c_str(),
facedetectorFilePath.c_str(),
precision,
0.25, enableAgeGender, enableEmotion, enableHeadPose, 30, 0.55, enableFaceLiveness, enableAntispoofing);
std::cout << "[CPU Test] CreateANSRFHandle result: " << result << std::endl;
if (result < 0) {
std::cerr << "[CPU Test] FAILED: CreateANSRFHandle returned " << result << std::endl;
return -1;
}
// Step 2: Load engine
std::cout << "[CPU Test] Step 2: Loading engine..." << std::endl;
int loadEngineResult = LoadANSRFEngine(&infHandle);
std::cout << "[CPU Test] LoadANSRFEngine result: " << loadEngineResult << std::endl;
if (loadEngineResult != 1) {
std::cerr << "[CPU Test] FAILED: LoadANSRFEngine returned " << loadEngineResult << std::endl;
ReleaseANSRFHandle(&infHandle);
return -2;
}
// Step 3: Reload database
std::cout << "[CPU Test] Step 3: Reloading database..." << std::endl;
Reload(&infHandle);
// Step 4: Open video
std::cout << "[CPU Test] Step 4: Opening video..." << std::endl;
cv::VideoCapture capture(videoFilePath);
if (!capture.isOpened()) {
std::cerr << "[CPU Test] FAILED: Could not open video: " << videoFilePath << std::endl;
ReleaseANSRFHandle(&infHandle);
return -3;
}
int totalFrames = static_cast<int>(capture.get(cv::CAP_PROP_FRAME_COUNT));
std::cout << "[CPU Test] Video opened: " << totalFrames << " frames" << std::endl;
// Step 5: Run inference on video frames
std::cout << "[CPU Test] Step 5: Running inference..." << std::endl;
int frameIndex = 0;
int totalDetections = 0;
double totalInferenceMs = 0.0;
int maxFrames = 200; // Process up to 200 frames for the test
while (frameIndex < maxFrames) {
cv::Mat frame;
if (!capture.read(frame)) {
std::cout << "[CPU Test] End of video at frame " << frameIndex << std::endl;
break;
}
frameIndex++;
unsigned int bufferLength = 0;
unsigned char* jpeg_string = ANSCENTER::ANSUtilityHelper::CVMatToBytes(frame, bufferLength);
int height = frame.rows;
int width = frame.cols;
auto start = std::chrono::system_clock::now();
string detectionResult = RunANSRFInferenceBinary(&infHandle, jpeg_string, width, height);
auto end = std::chrono::system_clock::now();
auto elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
totalInferenceMs += static_cast<double>(elapsed.count());
delete[] jpeg_string;
if (!detectionResult.empty()) {
try {
pt.clear();
std::stringstream ss;
ss << detectionResult;
boost::property_tree::read_json(ss, pt);
int detCount = 0;
BOOST_FOREACH(const boost::property_tree::ptree::value_type& child, pt.get_child("results")) {
const boost::property_tree::ptree& r = child.second;
const auto class_id = GetData<int>(r, "user_id");
const auto class_name = GetData<std::string>(r, "user_name");
const auto x = GetData<float>(r, "x");
const auto y = GetData<float>(r, "y");
const auto w = GetData<float>(r, "width");
const auto h = GetData<float>(r, "height");
const auto sim = GetData<float>(r, "similarity");
detCount++;
cv::rectangle(frame, cv::Rect(x, y, w, h), cv::Scalar(0, 255, 0), 2);
cv::putText(frame, cv::format("%s:%d-%.2f", class_name.c_str(), class_id, sim),
cv::Point(x, y - 5), 0, 0.6, cv::Scalar(0, 0, 255), 1, cv::LINE_AA);
}
totalDetections += detCount;
}
catch (const std::exception& e) {
std::cerr << "[CPU Test] JSON parse error at frame " << frameIndex << ": " << e.what() << std::endl;
}
}
// Show every 10th frame progress
if (frameIndex % 10 == 0) {
std::cout << "[CPU Test] Frame " << frameIndex << "/" << maxFrames
<< " | Time: " << elapsed.count() << "ms"
<< " | Detections: " << totalDetections << std::endl;
}
cv::imshow("ANS CPU Test", frame);
if (cv::waitKey(1) == 27) {
std::cout << "[CPU Test] ESC pressed, stopping." << std::endl;
break;
}
}
// Step 6: Print summary
double avgMs = (frameIndex > 0) ? (totalInferenceMs / frameIndex) : 0.0;
std::cout << "\n=== CPU Test Summary ===" << std::endl;
std::cout << "Frames processed: " << frameIndex << std::endl;
std::cout << "Total detections: " << totalDetections << std::endl;
std::cout << "Avg inference: " << avgMs << " ms/frame" << std::endl;
std::cout << "Total time: " << totalInferenceMs << " ms" << std::endl;
if (frameIndex == 0) {
std::cerr << "[CPU Test] FAILED: No frames processed" << std::endl;
} else {
std::cout << "[CPU Test] PASSED" << std::endl;
}
// Cleanup
capture.release();
cv::destroyAllWindows();
ReleaseANSRFHandle(&infHandle);
std::cout << "[CPU Test] Done." << std::endl;
return (frameIndex > 0) ? 0 : -4;
}
// ANSVISTestCPU_Lightweight — Detection + Recognition only, no attribute models.
// Measures baseline face detection + recognition speed on Intel CPU/iGPU.
int ANSVISTestCPU_Lightweight() {
boost::property_tree::ptree pt;
std::string databaseFilePath = "C:\\ProgramData\\ANSCENTER\\ANSVIS Server\\ANSFR\\ANSFR.db";
std::string recognizerFilePath = "C:\\ProgramData\\ANSCENTER\\ANSVIS Server\\ANSFR\\ANS_FaceRecognizer_v1.1.zip";
std::string facedetectorFilePath = "C:\\ProgramData\\ANSCENTER\\ANSVIS Server\\ANSFDET\\ANS_GenericFD(CPU)_v1.0.zip";
std::string videoFilePath = "C:\\ProgramData\\ANSCENTER\\Shared\\classroom.mp4";
const char* configFilePath = "";
ANSCENTER::ANSFacialRecognition* infHandle = nullptr;
std::string licenseKey = "";
// All attribute models DISABLED for lightweight test
int enableHeadPose = 0;
int enableFaceLiveness = 0;
int enableAgeGender = 0;
int enableEmotion = 0;
int enableAntispoofing = 0;
int precision = 0; // FP32
std::cout << "\n=== ANSVISTestCPU_Lightweight ===" << std::endl;
std::cout << "Mode: Detection + Recognition ONLY (no attributes)" << std::endl;
std::cout << "Database: " << databaseFilePath << std::endl;
std::cout << "Recognizer: " << recognizerFilePath << std::endl;
std::cout << "FaceDetector: " << facedetectorFilePath << std::endl;
std::cout << "Video: " << videoFilePath << std::endl;
// Step 1: Create handle
std::cout << "[Lightweight] Step 1: Creating handle..." << std::endl;
int result = CreateANSRFHandle(&infHandle,
licenseKey.c_str(),
configFilePath,
databaseFilePath.c_str(),
recognizerFilePath.c_str(),
facedetectorFilePath.c_str(),
precision,
0.25, enableAgeGender, enableEmotion, enableHeadPose, 30, 0.55, enableFaceLiveness, enableAntispoofing);
std::cout << "[Lightweight] CreateANSRFHandle result: " << result << std::endl;
if (result < 0) {
std::cerr << "[Lightweight] FAILED: CreateANSRFHandle returned " << result << std::endl;
return -1;
}
// Step 2: Load engine
std::cout << "[Lightweight] Step 2: Loading engine..." << std::endl;
int loadEngineResult = LoadANSRFEngine(&infHandle);
std::cout << "[Lightweight] LoadANSRFEngine result: " << loadEngineResult << std::endl;
if (loadEngineResult != 1) {
std::cerr << "[Lightweight] FAILED: LoadANSRFEngine returned " << loadEngineResult << std::endl;
ReleaseANSRFHandle(&infHandle);
return -2;
}
// Step 3: Reload database
std::cout << "[Lightweight] Step 3: Reloading database..." << std::endl;
Reload(&infHandle);
// Step 4: Open video
std::cout << "[Lightweight] Step 4: Opening video..." << std::endl;
cv::VideoCapture capture(videoFilePath);
if (!capture.isOpened()) {
std::cerr << "[Lightweight] FAILED: Could not open video: " << videoFilePath << std::endl;
ReleaseANSRFHandle(&infHandle);
return -3;
}
int totalFrames = static_cast<int>(capture.get(cv::CAP_PROP_FRAME_COUNT));
std::cout << "[Lightweight] Video opened: " << totalFrames << " frames" << std::endl;
// Step 5: Run inference
std::cout << "[Lightweight] Step 5: Running inference..." << std::endl;
int frameIndex = 0;
int totalDetections = 0;
double totalInferenceMs = 0.0;
int maxFrames = 200;
while (frameIndex < maxFrames) {
cv::Mat frame;
if (!capture.read(frame)) {
std::cout << "[Lightweight] End of video at frame " << frameIndex << std::endl;
break;
}
frameIndex++;
unsigned int bufferLength = 0;
unsigned char* jpeg_string = ANSCENTER::ANSUtilityHelper::CVMatToBytes(frame, bufferLength);
int height = frame.rows;
int width = frame.cols;
auto start = std::chrono::system_clock::now();
string detectionResult = RunANSRFInferenceBinary(&infHandle, jpeg_string, width, height);
auto end = std::chrono::system_clock::now();
auto elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
totalInferenceMs += static_cast<double>(elapsed.count());
delete[] jpeg_string;
if (!detectionResult.empty()) {
try {
pt.clear();
std::stringstream ss;
ss << detectionResult;
boost::property_tree::read_json(ss, pt);
int detCount = 0;
BOOST_FOREACH(const boost::property_tree::ptree::value_type& child, pt.get_child("results")) {
const boost::property_tree::ptree& r = child.second;
const auto x = GetData<float>(r, "x");
const auto y = GetData<float>(r, "y");
const auto w = GetData<float>(r, "width");
const auto h = GetData<float>(r, "height");
detCount++;
cv::rectangle(frame, cv::Rect(x, y, w, h), cv::Scalar(0, 255, 0), 2);
}
totalDetections += detCount;
}
catch (...) {}
}
if (frameIndex % 10 == 0) {
double avgSoFar = totalInferenceMs / frameIndex;
std::cout << "[Lightweight] Frame " << frameIndex << "/" << maxFrames
<< " | Time: " << elapsed.count() << "ms"
<< " | Avg: " << static_cast<int>(avgSoFar) << "ms"
<< " | FPS: " << std::fixed << std::setprecision(1) << (1000.0 / avgSoFar)
<< " | Faces: " << totalDetections << std::endl;
}
cv::imshow("ANS CPU Lightweight", frame);
if (cv::waitKey(1) == 27) break;
}
// Summary
double avgMs = (frameIndex > 0) ? (totalInferenceMs / frameIndex) : 0.0;
double fps = (avgMs > 0) ? (1000.0 / avgMs) : 0.0;
std::cout << "\n=== Lightweight Test Summary ===" << std::endl;
std::cout << "Frames processed: " << frameIndex << std::endl;
std::cout << "Total detections: " << totalDetections << std::endl;
std::cout << "Avg inference: " << avgMs << " ms/frame" << std::endl;
std::cout << "Avg FPS: " << std::fixed << std::setprecision(1) << fps << std::endl;
std::cout << "Total time: " << totalInferenceMs << " ms" << std::endl;
std::cout << (frameIndex > 0 ? "[Lightweight] PASSED" : "[Lightweight] FAILED") << std::endl;
capture.release();
cv::destroyAllWindows();
ReleaseANSRFHandle(&infHandle);
return (frameIndex > 0) ? 0 : -4;
}
// ANSVISTestFilePlayer — Same as ANSVISTest but uses ANSFILEPLAYER (HW decode + NV12 registry)
// instead of cv::VideoCapture. This enables NV12 fast-path testing for the FR pipeline:
// - SCRFD face detection uses fused NV12→RGB center-letterbox kernel
@@ -1321,16 +1633,16 @@ int TestCompleteFR1() {
}
int main()
{
//FaceDetectorTest();
//TestFaceRecognition();
//TestCompleteFR1();
//ANSVISImageTest();
ANSVISTest();
//ANSVISTest();
//ANSVISTestFilePlayer();
// ANSVISRecordingTest();
//FRStressTest();
//FRStressTest();
//for (int i = 0; i < 20; i++) {
// ANSVISTest();
//}
@@ -1341,6 +1653,8 @@ int main()
// TestCompleteFR();
//TestFaceRecognition();
//FaceRecognitionBenchmark();
ANSVISTestCPU_Lightweight();
ANSVISTestCPU();
std::cin.get();
}