Fix ALPR Batch and memory leak
This commit is contained in:
@@ -304,11 +304,18 @@ namespace ANSCENTER {
|
||||
p.framesSinceLastSeen++;
|
||||
}
|
||||
|
||||
// Periodic pruning: remove stale entries
|
||||
static thread_local int pruneCounterById = 0;
|
||||
pruneCounterById++;
|
||||
if (pruneCounterById >= 30 && plates.size() > 20) {
|
||||
pruneCounterById = 0;
|
||||
// Periodic pruning: remove stale entries.
|
||||
// NOTE: previously used `static thread_local int pruneCounterById`.
|
||||
// LabVIEW dispatches calls across a worker-thread pool, so the
|
||||
// thread-local counter fragmented across threads and pruning
|
||||
// effectively stopped firing — `trackedPlatesById[cameraId]` then
|
||||
// grew unbounded (one entry per frame when trackIds never repeat),
|
||||
// which manifested as a slow LabVIEW-side memory leak. The counter
|
||||
// is now a plain instance member guarded by `_mutex` (taken above),
|
||||
// so every 30th call across the whole engine triggers a prune pass.
|
||||
_pruneCounterById++;
|
||||
if (_pruneCounterById >= 30 && plates.size() > 20) {
|
||||
_pruneCounterById = 0;
|
||||
int staleThreshold = maxFrames * 3;
|
||||
for (auto it = plates.begin(); it != plates.end(); ) {
|
||||
if (it->second.framesSinceLastSeen > staleThreshold) {
|
||||
@@ -521,6 +528,36 @@ namespace ANSCENTER {
|
||||
ANSALPR::~ANSALPR(){};
|
||||
bool ANSALPR::Destroy() { return true; };
|
||||
|
||||
// Default batch implementation — fallback that loops RunInference over
|
||||
// vehicle crops one at a time. Subclasses should override this with a
|
||||
// true batched path (see ANSALPR_OD::RunInferencesBatch and
|
||||
// ANSALPR_OCR::RunInferencesBatch) to issue a single LP-detect and a
|
||||
// single OCR call per frame instead of N. The fallback preserves the
|
||||
// "transform bboxes back to frame coordinates" contract so a subclass
|
||||
// that never overrides still produces valid output.
|
||||
std::vector<Object> ANSALPR::RunInferencesBatch(
|
||||
const cv::Mat& input,
|
||||
const std::vector<cv::Rect>& vehicleBoxes,
|
||||
const std::string& cameraId)
|
||||
{
|
||||
std::vector<Object> out;
|
||||
if (input.empty() || vehicleBoxes.empty()) return out;
|
||||
const cv::Rect frameRect(0, 0, input.cols, input.rows);
|
||||
out.reserve(vehicleBoxes.size());
|
||||
for (const auto& r : vehicleBoxes) {
|
||||
cv::Rect c = r & frameRect;
|
||||
if (c.width <= 0 || c.height <= 0) continue;
|
||||
const cv::Mat crop = input(c);
|
||||
std::vector<Object> perVehicle = RunInference(crop, cameraId);
|
||||
for (auto& obj : perVehicle) {
|
||||
obj.box.x += c.x;
|
||||
obj.box.y += c.y;
|
||||
out.push_back(std::move(obj));
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
std::vector<cv::Rect> ANSCENTER::ANSALPR::GetBoundingBoxes(const std::string& strBBoxes) {
|
||||
std::vector<cv::Rect> bBoxes;
|
||||
bBoxes.clear();
|
||||
|
||||
Reference in New Issue
Block a user