209 lines
24 KiB
C++
209 lines
24 KiB
C++
#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>
|
|
#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
|
|
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", "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 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;
|
|
int framesSinceLastSeen = 0;
|
|
};
|
|
// cameraId → list of tracked plate identities
|
|
std::mutex _plateIdentitiesMutex; // Fine-grained lock for plate identity tracking
|
|
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);
|
|
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);
|
|
[[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
|
|
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 |