Files
ANSCORE/modules/ANSLPR/ANSLPR_OD.h

209 lines
24 KiB
C
Raw Normal View History

2026-03-28 16:54:11 +11:00
#ifndef ANSLPROD_H
#define ANSLPROD_H
#pragma once
#include "ANSLPR.h"
#include "NV12PreprocessHelper.h"
#include <list>
#include <map>
#include <string>
#include <unordered_map>
#include <unordered_set>
2026-03-28 16:54:11 +11:00
#include <utility>
#include <vector>
namespace ANSCENTER
{
class ANSLPR_API ANSALPR_OD :public ANSALPR {
private:
ANSCENTER::EngineType engineType;
std::unique_ptr<ANSCENTER::ANSODBase>_lpDetector = nullptr; // License plate detector
std::unique_ptr<ANSCENTER::ANSODBase>_ocrDetector = nullptr; // OCR detector
std::unique_ptr<ANSCENTER::ANSODBase>_lpColourDetector = nullptr; // License plate colour classifier
ANSCENTER::ModelConfig _lpdmodelConfig;
ANSCENTER::ModelConfig _ocrModelConfig;
ANSCENTER::ModelConfig _lpColourModelConfig;
// _clahe moved to thread-local in enhanceForOCR() for thread safety
2026-03-28 16:54:11 +11:00
ANSCENTER::NV12PreprocessHelper _nv12Helper; // NV12 crop for high-res plate OCR
std::string _lpdLabels;
std::string _ocrLabels;
std::string _lpColourLabels;
cv::Mat _frameBuffer; // Reusable buffer for color conversion
cv::Mat enhanceAndDebug(const cv::Mat& roi);
std::vector <std::string> _lprModelClass; //model that recognise license plate
#ifdef FNS_DEBUG
void showDebugComparison(const cv::Mat& roi, const cv::Mat& processed,
const std::vector<std::vector<cv::Point>>& contours, int bestIdx,
const cv::RotatedRect& bestRect);
#endif
[[nodiscard]] bool MatchesPlateFormat(const std::string& plate) const;
std::vector<std::string> ValidVNMotobikeList = { "29BA", "29BB", "29BC", "29BD", "29BE",
"29BF", "29BG", "29BH", "29BK", "29BL",
"29BM", "29BN", "29BP", "29AA", "29AD",
"29AE", "29AF", "29AG", "29AH", "29AK",
"29AL", "29AM", "29AN", "29AP", "29AS",
"29AT", "29AU", "29AV", "29AX", "29AY","29AZ","29AB", "29AC"//HN
"59AA", "59TA", "59FA", "59CA", "59HA",
"59KA", "59CB", "59LA", "59UA", "59MA",
"59GA", "59DB", "59PA", "59NA", "59EA",
"59SA", "59VA", "59YA", "59YB", "59ZA",
"59ZB", "59NB", "59XB", "59BA", "59XA",
"59XB", "59FA", //HCM
"43AA", "43AC", "43AD", "43AE", "43AF", "43AG", "43AB",// Da Nang
"67AA", "67AD", "67AE", "67AH", "67AB",
"67AF", "67AK", "67AL", "67AM", "67AN",// An Giang
"94AB", "94AE", "94AF", "94AH", "94AK","94FD","94FE",// Bac Lieu
"98AA", "98AH", "98AB", "98AC", "98AD",
"98AE", "98AF", "98AG", "98AK", "98AL",// Bac Giang
"71AA", "71AF", "71AG", "71AH", "71AK",
"71AB", "71AC", "71AD", "71AE", // Ben Tre
"77AA", "77AE", "77AB", "77AH",
"77AK", "77AC", "77AD", "77AF",
"77AG", "77AN", "77AM", // Binh Dinh
"69AA", "69AB", "69AC", "69AD", "69AE",
"69AF", "69KA", "69AK", "69AL", "69AM", // Ca Mau
"65MA", "65AA", "65CA", "65DB", "65EA",
"65FA", "65GA", "65HA", "65KA", // Can Tho
"76AA", "76AU", "76AV", "76AH", "76AB",
"76AC", "76AD", "76AE", "76AF", "76AK",
"76AL", "76AM", "76AN", "76AP", "76AS","76AT",// Quang Ngai
"84HA", "66PA", "84AE", "88AB", "68MA",
"63AB", "84AF", "66HA", "60AD", "47AG", "74AE",
"84AH", "76AA", "21BA", "68HA", "68AA", "28FN",
"49AL", "12HA", "66MA", "15AA", "15AC", "83VK",
"95EA", "64AA", "12FA", "21AA", "83YM", "38AG",
"68TA", "63AE", "79NA", "12ZA", "20AC", "64EA",
"66VA", "83CA", "21FA", "68KB", "74AB", "63AK",
"23AB", "47AK", "60AM", "23AE", "74AK", "84CA",
"47AV", "26AA", "28FC", "21LA", "76AS", "68FA",
"21GA", "47AH", "47AU", "23AC", "63AN", "21KA",
"49AD", "74AH", "20AK", "26AC", "74AF", "76AC",
"68NA", "60AE", "22LA", "12XA", "15AH", "26AD",
"23AA", "83EA", "47AA", "38AA", "26AB", "60AB",
"60AF", "38AE", "28FD", "66BA", "68CA", "20AD",
"21EA", "38AS", "60AA", "88AC", "64BA", "22AB",
"49AG", "38AK", "47AS", "64AC", "47AD", "68SA",
"12BA", "15AE", "28FM", "26AM", "79ZA", "66FA",
"63AH", "64DA", "47AM", "68UA", "26AG", "84AC",
"66SA", "76AD", "49AN", "26AF", "79XA", "28FS",
"49AA", "63AS", "84BA", "12SA", "83DB", "60AL",
"21HA", "38AF", "22AA", "63AF", "49AE", "47AT",
"23AD", "84AD", "23AH", "79CA", "60AH", "66GA",
"26AK", "21CA", "38AB", "28FE", "26AP", "47AP",
"47AE", "76AV", "49AC", "38AN", "12PA", "76AE",
"64FA", "12VA", "22FA", "79DA", "95NA", "76AP",
"66NA", "47AB", "74AG", "60AC", "68GA", "63AC",
"47AN", "22YA", "68PA", "47AC", "83GE", "26AL",
"64DB", "47AL", "83ZY", "60AN", "64GA", "84AL",
"49AK", "28FB", "20AE", "20AG", "76AU", "66KA",
"64CA", "76AK", "23AV", "38AX", "79HA", "47AX",
"49AM", "83PT", "15AF", "95AA", "38AM", "76AT",
"47AF", "74AC", "20AB", "64HA", "12UA", "22SA",
"68BA", "49AH", "23AK", "20AF", "63AD", "60AK",
"28FZ", "28FL", "76AB", "49AF", "26AH", "63AL",
"74AA", "79DB", "22NA", "23AU", "23AY", "83TG",
"63AM", "64KA", "23AM", "74AD", "79VA", "95XA",
"28FF", "68KA", "49AP", "83XL", "83MF", "64HB",
"15AN", "15AK", "76AF", "22TA", "12LA", "38AL",
"95HA", "68EA", "84AA", "66CA", "26AE", "66LA",
"76AN", "23AX", "95RA", "68B", "68LA", "20AH",
"20AA", "76AH", "38AC", "12TA", "76AM",
"59C3", "29S7", "29V7", "29L2", "72K1", "72D1", "98AF",
"59D2", "59S1", "59K2", "67K1", "59C4", "98AG", "59E2",
"67H2", "94L1", "29S1", "59E1", "59X4", "94B2", "67L1",
"29E1", "72C1", "29V3", "67M1", "29X7", "29X1", "98AD",
"59N3", "59C1", "59D3", "59P1", "67F1", "59M2", "59K1",
"98AB", "59T2", "72E1", "59V1", "29N2", "29E2", "67D2",
"72E2", "29T2", "29V5", "59L3", "29S2", "59L2", "72G1",
"59G2", "30Z1", "67N1", "98B1", "59U1", "59D1", "72C2",
"98B2", "98M1", "29P1", "67M2", "98H1", "29V1", "29K2",
"59V2", "59F2", "59N1", "29Z1", "98D1", "59C2", "94K1",
"67G1", "98AL", "29Y5", "59B1", "41B1", "94G1", "59G1",
"94M1", "59X2", "67C1", "67D1", "59X3", "67B1", "98AC",
"67C2", "98B3", "59Z1", "59Z2", "98AH", "59S3", "94F1",
"98L1", "59H2", "98D2", "29D1", "59M1", "29B2", "29D2",
"29U1", "59U2", "29H2", "29K1", "94B1", "98C1", "59F1",
"67H1", "29F1", "29Y1", "59P2", "67L2", "59X1", "98G1",
"29C1", "67B2", "59T1", "29G2", "29L5", "29S6", "29Y7",
"59Y2", "67E1", "98AK", "94C1", "29X2", "98K1", "98AE",
"98AA", "29H1", "29T1", "67K2", "94D2", "94E1", "29M1",
"29N1", "59Y1", "72H1", "29X3", "98F1", "29C2", "94K2",
"72F1", "29M2", "29Y3", "59P3", "29E3", "29G1", "59V3",
"59Y3", "29P2", "59N2", "29L1", "98E1", "59G3", "29X5",
"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"
ALPRChecker alprChecker;
2026-04-01 17:01:05 +11:00
// Plate identity persistence: accumulated confidence per spatial plate location.
// Prevents the same plate string from appearing on multiple vehicles.
// Uses bounding box center position (not trackId) as the identity key,
// since trackIds may overlap when ALPR runs on cropped vehicle images.
struct SpatialPlateIdentity {
cv::Point2f center; // plate center in frame coordinates
std::string plateText;
float accumulatedScore = 0.0f;
2026-04-01 17:01:05 +11:00
int framesSinceLastSeen = 0;
};
2026-04-01 17:01:05 +11:00
// cameraId → list of tracked plate identities
std::mutex _plateIdentitiesMutex; // Fine-grained lock for plate identity tracking
2026-04-01 17:01:05 +11:00
std::unordered_map<std::string, std::vector<SpatialPlateIdentity>> _plateIdentities;
static constexpr float PLATE_SPATIAL_MATCH_THRESHOLD = 0.3f; // IoU threshold for same plate
void ensureUniquePlateText(std::vector<Object>& results, const std::string& cameraId);
2026-03-28 16:54:11 +11:00
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",
[[nodiscard]] std::string AnalyseLicensePlateText(const std::string& ocrText);
[[nodiscard]] char convertDigitToLetter(char c);
[[nodiscard]] char convertLetterToDigit(char c);
[[nodiscard]] char fixLPDigit(char c);
[[nodiscard]] int findSubstringIndex(const std::string& str);
[[nodiscard]] std::string convertStringToDigits(const std::string& input);
[[nodiscard]] std::string convertStringToLetters(const std::string& input);
[[nodiscard]] int searchDiplomacyLP(const std::string& input);
[[nodiscard]] bool ValidateVNMotobikeLP(const std::string& input);
[[nodiscard]] bool ValidateVNCarLP(const std::string& input);
bool valid;
cv::Mat alignPlateForOCR(const cv::Mat& fullImage, const cv::Rect& bbox);
cv::Mat enhanceForOCR(const cv::Mat& plateROI);
[[nodiscard]] std::string DetectLicensePlateString(const cv::Mat& lprROI, const std::string& cameraId);
[[nodiscard]] std::string DetectLPColourDetector(const cv::Mat& lprROI, const std::string& cameraId);
[[nodiscard]] std::string DetectLPColourCached(const cv::Mat& lprROI, const std::string& cameraId, const std::string& plateText);
// LPC colour cache: keyed by plate text (e.g. "29BA-12345"),
// stores { colour, hitCount }. Plate colour doesn't change, so
// we only run the classifier once per unique plate and reuse the
// result for subsequent frames.
struct ColourCacheEntry {
std::string colour;
int hitCount = 0;
};
std::mutex _colourCacheMutex; // Fine-grained lock for colour cache only
2026-03-28 16:54:11 +11:00
std::unordered_map<std::string, ColourCacheEntry> _colourCache;
static constexpr size_t COLOUR_CACHE_MAX_SIZE = 200;
public:
ANSALPR_OD();
~ANSALPR_OD();
[[nodiscard]] bool Initialize(const std::string& licenseKey, const std::string& modelZipFilePath, const std::string& modelZipPassword, double detectorThreshold, double ocrThreshold, double colourThreshold) override;
[[nodiscard]] bool LoadEngine() override;
[[nodiscard]] bool Inference(const cv::Mat& input, std::string& lprResult) override;
[[nodiscard]] bool Inference(const cv::Mat& input, std::string& lprResult, const std::string &cameraId) override;
[[nodiscard]] bool Inference(const cv::Mat& input, const std::vector<cv::Rect> & Bbox, std::string& lprResult) override;
[[nodiscard]] bool Inference(const cv::Mat& input, const std::vector<cv::Rect> & Bbox, std::string& lprResult, const std::string & cameraId) override;
[[nodiscard]] std::vector<Object> RunInferenceSingleFrame(const cv::Mat& input, const std::string& cameraId);
[[nodiscard]] std::vector<Object> RunInference(const cv::Mat& input, const std::string& cameraId) override;
[[nodiscard]] std::vector<std::string> DetectLicensePlateStringBatch(const std::vector<cv::Mat>& lprROIs, const std::string& cameraId);
[[nodiscard]] std::vector<std::string> DetectLPColourDetectorBatch(const std::vector<cv::Mat>& lprROIs, const std::string& cameraId);
[[nodiscard]] std::string ProcessSingleOCRResult(const std::vector<Object>& ocrOutput);
[[nodiscard]] bool Destroy() override;
/// Propagate debug flag to all sub-detectors (LPD, OCR, colour)
void ActivateDebugger(bool debugFlag) override {
_debugFlag = debugFlag;
if (_lpDetector) _lpDetector->ActivateDebugger(debugFlag);
if (_ocrDetector) _ocrDetector->ActivateDebugger(debugFlag);
if (_lpColourDetector) _lpColourDetector->ActivateDebugger(debugFlag);
}
};
}
#endif