Fix issue that generate two or more objects with the same LP numbers/user name in the same image frame

This commit is contained in:
2026-04-01 08:01:22 +11:00
parent ccfc5964d4
commit 6c6d1c0e0b
7 changed files with 249 additions and 34 deletions

View File

@@ -8,7 +8,8 @@
"Bash(grep -n \"g_processExiting\" /c/Projects/CLionProjects/ANSCORE/engines/TensorRTAPI/include/engine/*.h /c/Projects/CLionProjects/ANSCORE/modules/ANSODEngine/engine.h)",
"Bash(ssh -T git@anscenter.ddns.net -p 2222)",
"Bash(ssh-add -l)",
"Bash(dotnet build:*)"
"Bash(dotnet build:*)",
"Bash(grep -n \"struct Object\\\\|class Object\" /c/Projects/CLionProjects/ANSCORE/modules/ANSLPR/*.h /c/Projects/CLionProjects/ANSCORE/modules/ANSLPR/include/*.h)"
]
}
}

View File

@@ -2163,7 +2163,9 @@ namespace ANSCENTER {
END_TIMER(postprocess, "Update Face Attributes Time");
// Deduplicate: if two faces matched the same userId, keep only the highest confidence
ensureUniqueUserIdWithHighestConfidence(resultObjects);
// Pass camera data for trackId-based identity persistence to prevent flickering
CameraData* camDataPtr = (!camera_id.empty()) ? &GetCameraData(camera_id) : nullptr;
ensureUniqueUserIdWithHighestConfidence(resultObjects, camDataPtr);
}
}
catch (const std::exception& e) {
@@ -2500,45 +2502,128 @@ namespace ANSCENTER {
cv::cvtColor(input, frame, cv::COLOR_GRAY2BGR);
return frame;
}
void ANSFacialRecognition::ensureUniqueUserIdWithHighestConfidence(std::vector<FaceResultObject>& resultObjects)
void ANSFacialRecognition::ensureUniqueUserIdWithHighestConfidence(std::vector<FaceResultObject>& resultObjects, CameraData* camData)
{
// NO LOCK NEEDED - Operating on thread-local resultObjects
// Each camera has its own vector, no shared state
if (resultObjects.empty()) {
return;
}
// Map userId to index of face with highest confidence
std::unordered_map<std::string, size_t> highestConfidenceIndices;
highestConfidenceIndices.reserve(resultObjects.size());
auto isUnknownId = [](const std::string& id) {
return id == "0000" || id == "0" || id.empty();
};
for (size_t i = 0; i < resultObjects.size(); ++i) {
const std::string& userId = resultObjects[i].userId;
if (camData) {
auto& identities = camData->trackIdentities;
// Skip unknown faces
if (userId == "0000") {
continue;
// Step 1: Build map of userId → candidate face indices (before modifying anything)
std::unordered_map<std::string, std::vector<size_t>> userIdCandidates;
for (size_t i = 0; i < resultObjects.size(); ++i) {
if (isUnknownId(resultObjects[i].userId)) continue;
userIdCandidates[resultObjects[i].userId].push_back(i);
}
auto it = highestConfidenceIndices.find(userId);
// Step 2: Resolve duplicate userIds using accumulated scores
for (auto& [uid, indices] : userIdCandidates) {
if (indices.size() <= 1) continue;
if (it == highestConfidenceIndices.end()) {
// First occurrence of this userId
highestConfidenceIndices[userId] = i;
}
else {
// Duplicate userId found - keep only highest confidence
size_t existingIndex = it->second;
// Find the candidate with the highest accumulated score for this userId
size_t winner = indices[0];
float bestScore = 0.0f;
if (resultObjects[i].confidence > resultObjects[existingIndex].confidence) {
// Current face has higher confidence - mark previous as unknown
MarkAsUnknown(resultObjects[existingIndex]);
highestConfidenceIndices[userId] = i;
for (size_t idx : indices) {
int tid = resultObjects[idx].trackId;
float score = resultObjects[idx].confidence; // fallback for new trackIds
auto it = identities.find(tid);
if (it != identities.end() && it->second.userId == uid) {
// Use accumulated score + this frame's confidence
score = it->second.accumulatedScore + resultObjects[idx].confidence;
}
if (score > bestScore) {
bestScore = score;
winner = idx;
}
}
else {
// Existing face has higher confidence - mark current as unknown
MarkAsUnknown(resultObjects[i]);
// Mark all non-winners as unknown
for (size_t idx : indices) {
if (idx != winner) {
MarkAsUnknown(resultObjects[idx]);
}
}
}
// Step 3: Update accumulated scores after dedup.
// - Winners: add this frame's confidence to their score
// - Losers (marked Unknown by dedup): decay their score (×0.8)
// so they gradually lose claim but don't reset instantly
// (avoids the alternating-win problem where neither can accumulate)
// - Losers that decay below a threshold are erased entirely
constexpr float DECAY_FACTOR = 0.8f;
constexpr float MIN_SCORE = 0.1f;
for (auto& r : resultObjects) {
int tid = r.trackId;
if (isUnknownId(r.userId)) {
// Lost dedup or genuinely unknown — decay existing score
auto it = identities.find(tid);
if (it != identities.end()) {
it->second.accumulatedScore *= DECAY_FACTOR;
if (it->second.accumulatedScore < MIN_SCORE) {
identities.erase(it);
}
}
continue;
}
auto it = identities.find(tid);
if (it != identities.end()) {
if (it->second.userId == r.userId) {
// Same identity as before and won dedup — accumulate
it->second.accumulatedScore += r.confidence;
} else {
// Different identity — start fresh
it->second.userId = r.userId;
it->second.accumulatedScore = r.confidence;
}
} else {
// New trackId — initialize
identities[tid] = { r.userId, r.confidence };
}
}
// Step 3: Clean up trackIds no longer in the scene
std::unordered_set<int> activeTrackIds;
for (const auto& r : resultObjects) {
activeTrackIds.insert(r.trackId);
}
for (auto it = identities.begin(); it != identities.end(); ) {
if (activeTrackIds.find(it->first) == activeTrackIds.end()) {
it = identities.erase(it);
} else {
++it;
}
}
} else {
// No camera data: fall back to simple confidence-based dedup
std::unordered_map<std::string, size_t> highestConfidenceIndices;
highestConfidenceIndices.reserve(resultObjects.size());
for (size_t i = 0; i < resultObjects.size(); ++i) {
const std::string& userId = resultObjects[i].userId;
if (isUnknownId(userId)) continue;
auto it = highestConfidenceIndices.find(userId);
if (it == highestConfidenceIndices.end()) {
highestConfidenceIndices[userId] = i;
} else {
size_t existingIndex = it->second;
if (resultObjects[i].confidence > resultObjects[existingIndex].confidence) {
MarkAsUnknown(resultObjects[existingIndex]);
highestConfidenceIndices[userId] = i;
} else {
MarkAsUnknown(resultObjects[i]);
}
}
}
}

View File

@@ -123,6 +123,7 @@ namespace ANSCENTER
void Destroy();
void SetMaxSlotsPerGpu(int n) { m_maxSlotsPerGpu = n; }
private:
struct CameraData; // Forward declaration for ensureUniqueUserIdWithHighestConfidence
int m_maxSlotsPerGpu{ 1 }; // set by dllmain based on GPU topology
int GetUser(int userId, UserRecord& userRecord);
int GetUser(int userId, const std::string& userCode,const std::string& userName, UserRecord& userRecord);
@@ -140,7 +141,7 @@ namespace ANSCENTER
bool InitializeAgeGenderModel(const std::string& deviceName);
bool InitializeEmotionModel(const std::string& deviceName);
bool InitializeHeadPoseModel(const std::string& deviceName);
void ensureUniqueUserIdWithHighestConfidence(std::vector<FaceResultObject>& resultObjects);
void ensureUniqueUserIdWithHighestConfidence(std::vector<FaceResultObject>& resultObjects, CameraData* camData = nullptr);
Object GetLargestObject(const std::vector<Object>& objects);
bool AreFacesSimilar(const FaceResultObject& face1, const FaceResultObject& face2);
size_t GenerateFaceHash(const FaceResultObject& face, const std::vector<FaceResultObject>& detectedObjects);
@@ -232,6 +233,16 @@ namespace ANSCENTER
int attributeFrameCounter = 0; // counts frames for attribute skip logic
std::unordered_map<int, CachedFaceAttributes> cachedAttributes; // trackId → cached attrs
// Identity persistence: accumulated confidence per (trackId, userId) pair.
// Each frame adds the recognition confidence to the running total.
// When two trackIds claim the same userId, the one with the higher
// accumulated score wins — preventing single-frame flickering.
struct TrackIdentity {
std::string userId;
float accumulatedScore = 0.0f;
};
std::unordered_map<int, TrackIdentity> trackIdentities; // trackId → accumulated identity
// Adaptive interval state
int currentAttributeInterval = 5; // current adaptive interval
int stableFrameCount = 0; // frames with no new/lost trackIds
@@ -246,6 +257,7 @@ namespace ANSCENTER
_detectionQueue.clear();
attributeFrameCounter = 0;
cachedAttributes.clear();
trackIdentities.clear();
currentAttributeInterval = 5;
stableFrameCount = 0;
previousTrackIdCount = 0;

View File

@@ -990,6 +990,10 @@ namespace ANSCENTER {
cv::waitKey(1);
#endif
// Deduplicate: if two trackIds claim the same plate text, keep the one
// with the higher accumulated score to prevent plate flickering
ensureUniquePlateText(output, cameraId);
return output;
}
@@ -2313,6 +2317,10 @@ namespace ANSCENTER {
output.push_back(std::move(lprObject));
}
// Deduplicate: if two trackIds claim the same plate text, keep the one
// with the higher accumulated score to prevent plate flickering
ensureUniquePlateText(output, cameraId);
return output;
}
catch (const cv::Exception& e) {
@@ -2701,4 +2709,102 @@ namespace ANSCENTER {
return AnalyseLicensePlateText(ocrText);
}
}
void ANSALPR_OD::ensureUniquePlateText(std::vector<Object>& results, const std::string& cameraId)
{
if (results.empty()) return;
auto isEmptyPlate = [](const std::string& plate) {
return plate.empty();
};
auto& identities = _plateIdentities[cameraId];
// Step 1: Build map of plateText → candidate indices
std::unordered_map<std::string, std::vector<size_t>> plateCandidates;
for (size_t i = 0; i < results.size(); ++i) {
if (isEmptyPlate(results[i].className)) continue;
plateCandidates[results[i].className].push_back(i);
}
// Step 2: Resolve duplicates using accumulated scores
for (auto& [plateText, indices] : plateCandidates) {
if (indices.size() <= 1) continue;
// Find the candidate with the highest accumulated score
size_t winner = indices[0];
float bestScore = 0.0f;
for (size_t idx : indices) {
int tid = results[idx].trackId;
float score = results[idx].confidence; // fallback for new trackIds
auto it = identities.find(tid);
if (it != identities.end() && it->second.plateText == plateText) {
score = it->second.accumulatedScore + results[idx].confidence;
}
if (score > bestScore) {
bestScore = score;
winner = idx;
}
}
// Clear plate text from non-winners
for (size_t idx : indices) {
if (idx != winner) {
results[idx].className.clear();
}
}
}
// Step 3: Update accumulated scores — winners accumulate, losers decay
constexpr float DECAY_FACTOR = 0.8f;
constexpr float MIN_SCORE = 0.1f;
for (auto& r : results) {
int tid = r.trackId;
if (isEmptyPlate(r.className)) {
// Lost dedup or empty — decay
auto it = identities.find(tid);
if (it != identities.end()) {
it->second.accumulatedScore *= DECAY_FACTOR;
if (it->second.accumulatedScore < MIN_SCORE) {
identities.erase(it);
}
}
continue;
}
auto it = identities.find(tid);
if (it != identities.end()) {
if (it->second.plateText == r.className) {
it->second.accumulatedScore += r.confidence;
} else {
it->second.plateText = r.className;
it->second.accumulatedScore = r.confidence;
}
} else {
identities[tid] = { r.className, r.confidence };
}
}
// Step 4: Clean up trackIds no longer in the scene
std::unordered_set<int> activeTrackIds;
for (const auto& r : results) {
activeTrackIds.insert(r.trackId);
}
for (auto it = identities.begin(); it != identities.end(); ) {
if (activeTrackIds.find(it->first) == activeTrackIds.end()) {
it = identities.erase(it);
} else {
++it;
}
}
// Step 5: Remove entries with cleared plate text from results
results.erase(
std::remove_if(results.begin(), results.end(),
[](const Object& o) { return o.className.empty(); }),
results.end());
}
};

View File

@@ -7,6 +7,7 @@
#include <map>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>
@@ -134,6 +135,16 @@ namespace ANSCENTER
"59S2", "94D1", "59H1", "29B1", "59L1", "50X1", "72L1",
"43B1", "68L1", "70G1", "36M1", "81N1", "90K1", "17B1", "64E1", "99D1", "60B2", "74L1", "60C1", "68M1", "63B7", "34B1", "69M1", "24B1", "15M1", "83Y1", "48C1", "95H1", "79X1", "17B6", "36E1", "38K1", "25N1", "25U1", "61B1", "36C1", "36B3", "38F1", "99G1", "69N1", "97D1", "92T1", "92B1", "88B1", "97G1", "14U1", "63A1", "26N1", "19D1", "93C1", "73B1", "84B1", "81K1", "18L1", "64D1", "35M1", "61N1", "83P1", "15S1", "82B1", "92U1", "43D1", "22L1", "63B5", "64G1", "27N1", "14X1", "62C1", "81D1", "38G1", "19F1", "34K1", "49P1", "89H1", "14T1", "19M1", "78D1", "76A1", "66K1", "66C1", "71C1", "37K1", "19G1", "15F1", "85C1", "49B1", "21B1", "89F1", "23M1", "66L1", "90B5", "93M1", "14P1", "77N1", "36B8", "86B1", "12U1", "63B3", "21L1", "36G5", "65G1", "82E1", "61H1", "65H1", "84A1", "23F1", "95C1", "99K1", "49G1", "92D1", "36K3", "92N1", "82X1", "83M1", "11N1", "14K1", "19H1", "93H1", "60A1", "79A1", "20D1", "90D1", "81C1", "66P1", "36K1", "92V1", "18B1", "37P1", "22Y1", "23H1", "26D1", "66G1", "78F1", "49C1", "26H1", "38P1", "47T1", "74H1", "63P1", "47D1", "15D1", "23D1", "68E1", "20B1", "49F1", "43K1", "65K1", "27Z1", "92S1", "79H1", "21E1", "35Y1", "14S1", "75E1", "24Y1", "12T1", "27P1", "77B1", "88H1", "60B3", "23P1", "61F1", "99H1", "23K1", "59A3", "26C1", "81B1", "74E1", "66B1", "22S1", "92P1", "93B1", "69B1", "81P1", "12H1", "62K1", "35A1", "77C1", "27V1", "68N1", "12D1", "64K1", "41A1", "12Z1", "76C1", "38B1", "78G1", "74K1", "69H1", "94A1", "61K1", "86B7", "82G1", "14N1", "82M1", "76E1", "18E1", "61C1", "15N1", "90A1", "77F1", "34D1", "47B1", "62S1", "43E1", "81M1", "92X1", "75B1", "34F1", "70H1", "62B1", "26B1", "60B4", "61A1", "12B1", "90T1", "92E1", "34C1", "47G1", "97B1", "25S1", "70E1", "93Y1", "47S1", "37F1", "28N1", "11K1", "38E1", "78M1", "74C1", "12S1", "75S1", "37A1", "28D1", "65L1", "22B1", "99B1", "74G1", "79K1", "76K1", "76H1", "23B1", "15R1", "36B1", "74D1", "62L1", "37E1", "78E1", "89K1", "26M1", "25F1", "48H1", "79D1", "43H1", "76F1", "36L1", "43L1", "21K1", "88L1", "27S1", "92K1", "77D1", "19N1", "66H1", "36H5", "62N1", "18G1", "75D1", "37L1", "68K1", "28C1", "26E1", "35N1", "85H1", "62D1", "27U1", "19E1", "99E1", "14Y1", "49L1", "66M1", "73F1", "70K1", "36F5", "97H1", "93E1", "68P1", "43F1", "48G1", "75K1", "62U1", "86B9", "65F1", "27L1", "70L1", "63B8", "78L1", "11Z1", "68C1", "18D1", "15L1", "99C1", "49E1", "84E1", "69E1", "38A1", "48D1", "68S1", "81E1", "84K1", "63B6", "24T1", "95A1", "86B4", "34M1", "84L1", "24V1", "14M1", "36H1", "15B1", "69F1", "47E1", "38H1", "88D1", "28E1", "60C2", "63B9", "75Y1", "21D1", "35H1", "68F1", "86B5", "15H1", "36B5", "83X1", "17B7", "12V1", "86B8", "95E1", "63B2", "74F1", "86C1", "48K1", "89M1", "85D1", "71C4", "34E1", "97C1", "88E1", "81F1", "60B5", "84M1", "92H1", "28L1", "34H1", "38X1", "82L1", "61E1", "82F1", "62P1", "93F1", "65B1", "93L1", "95B1", "15P1", "77G1", "28M1", "35B1", "68G1", "36C2", "68D1", "69K1", "14L1", "36M3", "24X1", "24Z1", "86A1", "88C1", "15E1", "77E1", "83E1", "47L1", "25T1", "89C1", "71C3", "49D1", "36L6", "48F1", "36B6", "34P1", "84D1", "15C1", "38M1", "85F1", "77K1", "86B3", "74B1", "78H1", "89G1", "64A2", "15K1", "85B1", "49K1", "21H1", "73C1", "47U1", "65E1", "18C1", "69D1", "63B1", "95G1", "19L1", "20G1", "76D1", "29A1", "68T1", "75L1", "12L1", "89L1", "37C1", "27B1", "19C1", "11H1", "81X1", "70B1", "11V1", "43G1", "22A1", "83C1", "75C1", "79C1", "22F1", "92F1", "81G1", "81T1", "28H1", "66N1", "71B1", "18H1", "76P1", "26F1", "81U1", "34N1", "64F1", "76N1", "24S1", "26P1", "63B4", "35T1", "36N1", "47F1", "81L1", "61G1", "77M1", "34G1", "26G1", "97F1", "62H1", "28F1", "62T1", "93G1", "73D1", "65A1", "47P1", "74P1", "82N1", "20E1", "36D1", "60B1", "49M1", "37H1", "37M1", "38D1", "84F1", "88F1", "36B2", "65C1", "92M1", "86B6", "75H1", "38L1", "20C1", "97E1", "85E1", "38N1", "26K1", "89B1", "99F1", "28B1", "34L1", "86B2", "66F1", "77L1", "27Y1", "68H1", "37D1", "92L1", "82K1", "99A1", "69L1", "76M1", "90B4", "48B1", "95D1", "20H1", "64H1", "79Z1", "92G1", "23G1", "21G1", "37G1", "35K1", "81H1", "83Z1", "76T1", "36F1", "36B4", "14B9", "47K1", "20K1", "62M1", "84H1", "62F1", "74A1", "18A1", "73H1", "37N1", "79N1", "61D1", "11P1", "15G1", "47N1", "19K1", "71C2", "81S1", "11M1", "60B7", "60B8", "62G1", "71A1", "24P1", "69A1", "38C1", "49N1", "21C1", "84G1", "37B1", "72A1", "88K1", "88G1", "83V1", "78C1", "73K1", "78K1", "73E189D1", "67A1", "27X1", "62A1", "18K1", "70F1", "36K5", "19B1", "49H1", "66S1", "12P1" };
ALPRChecker alprChecker;
// Plate identity persistence: accumulated confidence per (trackId, plateText) pair.
// Prevents the same plate string from flickering between different vehicles.
struct PlateTrackIdentity {
std::string plateText;
float accumulatedScore = 0.0f;
};
// cameraId → { trackId → PlateTrackIdentity }
std::unordered_map<std::string, std::unordered_map<int, PlateTrackIdentity>> _plateIdentities;
void ensureUniquePlateText(std::vector<Object>& results, const std::string& cameraId);
std::vector<std::string> ValidVNCarList = { "94H", "49F", "93A", "20F", "81H", "95R", "38R", "29F", "81F", "28G", "19A", "85B", "2", "43H", "51L", "28C", "21A", "51D", "50F", "24H", "93R", "92H", "71G", "75H", "86G", "30L", "79A", "82B", "79H", "78C", "61E", "70A", "90C", "72G", "34B", "17E", "18E", "78A", "37F", "51E", "71A", "28F", "47E", "83D", "81B", "84C", "71H", "76G", "92E", "36A", "69R", "30M", "27R", "71D", "19B", "34E", "38K", "88G", "68G", "30E", "68E", "25F", "74D", "98K", "89H", "36R", "84D", "61F", "49G", "25H", "17F", "14R", "36H", "47G", "90A", "68A", "83C", "26B", "15B", "61C", "15K", "47H", "78E", "75D", "15C", "63E", "34C", "36F", "38G", "15E", "93F", "22G", "60B", "94D", "62R", "24D", "11R", "12A", "76A", "94C", "97R", "24E", "26A", "15F", "72A", "49H", "62D", "98C", "71B", "61A", "12C", "27A", "78R", "51M", "69E", "76D", "78F", "49R", "81A", "64F", "29D", "18A", "19F", "21E", "92A", "65G", "86E", "62G", "61K", "47A", "23R", "14F", "95D", "36B", "74R", "11H", "24C", "11G", "66D", "63A", "43R", "70F", "86B", "61G", "47M", "67C", "37D", "43G", "14H", "90F", "51G", "86A", "11E", "29K", "85C", "83F", "24B", "98R", "19E", "61B", "90D", "82G", "14K", "74G", "72D", "85A", "19C", "37G", "98E", "74F", "28H", "90E", "89D", "35R", "97H", "83H", "95A", "20C", "65E", "15R", "73C", "37A", "38E", "77G", "94B", "17A", "75R", "98F", "65R", "76R", "20B", "24G", "25B", "73G", "62F", "29G", "77C", "22H", "14D", "23F", "93C", "19R", "15D", "47R", "79D", "60G", "77A", "82C", "63G", "21H", "81E", "25D", "12D", "37R", "36K", "84F", "98G", "28B", "51N", "18F", "50R", "74C", "35C", "30G", "64A", "95F", "18C", "99G", "99B", "37C", "76H", "60K", "67R", "75A", "83R", "28E", "65F", "17D", "92G", "23C", "60R", "90R", "38A", "43D", "50H", "43C", "77H", "47B", "89F", "82F", "65H", "89E", "62C", "24R", "26G", "84E", "17C", "65B", "34A", "12B", "64R", "29H", "71C", "88D", "79F", "76C", "98A", "69H", "22B", "29A", "72R", "67H", "48C", "22D", "60C", "35H", "38H", "63P", "70D", "49D", "18H", "89A", "72E", "92D", "26H", "73R", "85G", "20E", "98H", "69C", "18B", "73B", "22E", "34G", "30K", "20D", "50A", "34D", "15H", "34H", "71E", "62E", "64C", "51R", "82D", "99E", "70R", "18D", "92F", "94R", "24A", "85H", "11C", "73E", "95E", "86C", "94F", "86R", "37K", "23B", "20H", "73D", "95H", "35A", "89B", "82H", "67F", "70H", "97F", "29E", "97A", "51K", "68D", "37B", "82E", "18R", "86H", "35B", "43E", "35F", "95B", "70E", "21D", "27F", "36E", "63D", "68C", "50E", "36G", "75F", "21G", "29B", "93B", "22A", "18G", "43F", "93G", "62A", "83B", "28D", "75C", "22C", "21R", "25E", "23G", "97C", "75E", "79E", "19H", "47K", "65C", "35E", "20R", "68B", "89R", "67A", "75G", "81R", "78B", "77D", "78G", "20K", "36D", "66C", "38F", "27G", "19D", "67B", "84G", "22F", "61D", "20G", "48A", "76F", "48H", "92B", "85R", "26C", "65A", "70B", "38D", "14C", "66A", "73A", "49C", "74E", "68R", "66B", "74A", "49E", "17B", "69D", "51C", "85F", "21F", "99C", "17G", "72H", "94E", "51F", "92R", "60H", "21B", "93D", "19G", "86F", "51A", "66R", "72B", "26D", "64E", "93H", "12H", "97E", "60E", "82A", "60A", "83E", "27D", "64B", "11B", "11D", "76B", "95G", "14A", "61R", "21C", "30F", "23H", "89C", "97G", "62B", "63R", "88B", "98B", "90B", "67G", "69F", "73H", "20A", "72C", "65D", "68H", "51H", "79G", "70C", "90G", "66G", "83A", "77F", "63B", "64G", "25A", "88E", "68F", "99D", "26E", "94A", "48F", "34R", "61H", "90H", "74B", "14G", "12F", "15A", "27E", "69A", "35D", "12E", "85E", "25C", "29M", "89G", "17R", "78D", "84R", "95C", "15G", "28R", "99A", "69G", "48D", "97D", "27C", "78H", "14E", "79R", "73F", "88A", "48E", "48B", "64H", "99R", "14B", "77R", "75B", "88F", "84B", "11A", "67E", "12R", "50M", "11F", "79C", "49A", "43A", "88R", "77E", "48G", "51B", "81D", "74H", "93E", "37H", "88C", "71F", "94G", "38C", "29C", "43B", "30H", "81G", "28A", "26R", "66H", "66E", "17H", "79B", "49B", "63C", "98D", "81C", "69B", "63H", "85D", "26F", "22R", "83G", "37E", "12G", "77B", "35G", "62H", "60D", "60F", "99H", "70G", "76E", "84A", "72F", "25R", "27B", "30A", "47F", "34F", "97B", "23E", "36C", "66F", "48R", "92C", "71R", "23A", "50G", "47C", "82R", "63F", "84H", "38B", "47D", "67D", "25G", "86D", "88H", "64D", "24F", "23D", "99F" };
[[nodiscard]] std::string AnalyseLicensePlateText(const std::string& ocrText);
[[nodiscard]] char convertDigitToLetter(char c);

View File

@@ -730,8 +730,8 @@ int ANSVISTest() {
//std::string videoFilePath = "E:\\Programs\\DemoAssets\\Videos\\ANSVIS_Issues\\face.mp4";
//std::string videoFilePath = "E:\\Programs\\DemoAssets\\Videos\\TestFR\\Face31.mp4";
//std::string videoFilePath = "E:\\Programs\\DemoAssets\\Videos\\classroom.mp4";
std::string videoFilePath = "E:\\Programs\\DemoAssets\\Videos\\TestFR\\school1.mp4";// "C:\\ProgramData\\ANSCENTER\\Shared\\classroom.mp4";
std::string videoFilePath = "E:\\Programs\\DemoAssets\\Videos\\classroom.mp4";
//std::string videoFilePath = "E:\\Programs\\DemoAssets\\Videos\\TestFR\\school1.mp4";// "C:\\ProgramData\\ANSCENTER\\Shared\\classroom.mp4";
const char* configFilePath = "";
ANSCENTER::ANSFacialRecognition* infHandle;

View File

@@ -2770,9 +2770,9 @@ int main()
//for (int i = 0; i < 100; i++) {
// ANSLPR_CPU_Inferences_FileTest();
//}
ANSLPR_MultiGPU_StressTest();
//ANSLPR_MultiGPU_StressTest();
//ANSLPR_MultiGPU_StressTest_SimulatedCam();
//ANSLPR_MultiGPU_StressTest_FilePlayer();
ANSLPR_MultiGPU_StressTest_FilePlayer();
return 0;
}