Fix NV12 crash issue when recreate camera object

This commit is contained in:
2026-04-02 22:07:27 +11:00
parent 4bedf3a3a2
commit 958cab6ae3
25 changed files with 1459 additions and 393 deletions

View File

@@ -378,7 +378,7 @@ namespace ANSCENTER {
}
}
std::vector<Object> ANSALPR_CPU::RunInference(const cv::Mat& input, const std::string &cameraId) {
std::lock_guard<std::recursive_mutex> lock(_mutex);
// No coarse _mutex — sub-components have their own fine-grained locks.
std::vector<Object> output;
output.clear();
// Initial validation
@@ -419,17 +419,18 @@ namespace ANSCENTER {
#ifdef FNS_DEBUG // Corrected preprocessor directive
cv::Mat draw = input.clone();
#endif
_detectedArea = cv::Rect(0, 0, frame.cols, frame.rows);
if ((_detectedArea.width > 50) && (_detectedArea.height > 50)) {
// Use local variable instead of shared _detectedArea for thread safety
cv::Rect detectedArea(0, 0, frame.cols, frame.rows);
if ((detectedArea.width > 50) && (detectedArea.height > 50)) {
#ifdef FNS_DEBUG // Corrected preprocessor directive
cv::rectangle(draw, _detectedArea, cv::Scalar(0, 0, 255), 2); // RED for detectedArea
#endif
cv::rectangle(draw, detectedArea, cv::Scalar(0, 0, 255), 2); // RED for detectedArea
#endif
// Ensure _lprDetector is valid
if (!_lprDetector) {
this->_logger.LogFatal("ANSALPR_CPU::Inference", "_lprDetector is null", __FILE__, __LINE__);
return output;
}
cv::Mat activeFrame = frame(_detectedArea).clone();
cv::Mat activeFrame = frame(detectedArea).clone();
//std::vector<Object> lprOutputRaw = _lpDetector->RunInference(activeFrame, cameraId);
//std::vector<Object> lprOutput = AdjustLicensePlateBoundingBoxes(lprOutputRaw, _detectedArea, frame.size(), 3.0);
@@ -471,8 +472,12 @@ namespace ANSCENTER {
lprObject.cameraId = cameraId;
lprObject.polygon = RectToNormalizedPolygon(lprObject.box, input.cols, input.rows);
// OCR inference
std::vector<PaddleOCR::OCRPredictResult> res_ocr = ppocr->ocr(alignedLPR);
// OCR inference (ppocr is not thread-safe, use fine-grained lock)
std::vector<PaddleOCR::OCRPredictResult> res_ocr;
{
std::lock_guard<std::mutex> ocrLock(_ocrMutex);
res_ocr = ppocr->ocr(alignedLPR);
}
std::string ocrText;
if (!res_ocr.empty() && res_ocr.size() < 3) {
@@ -515,13 +520,13 @@ namespace ANSCENTER {
return output;
}
bool ANSALPR_CPU::Inference(const cv::Mat& input, std::string& lprResult) {
std::lock_guard<std::recursive_mutex> lock(_mutex);
// No coarse _mutex — delegates to Inference(input, lprResult, cameraId)
if (input.empty()) return false;
if ((input.cols < 5) || (input.rows < 5)) return false;
return Inference(input, lprResult, "CustomCam");
}
bool ANSALPR_CPU::Inference(const cv::Mat& input, std::string& lprResult, const std::string & cameraId) {
std::lock_guard<std::recursive_mutex> lock(_mutex);
// No coarse _mutex — sub-components have fine-grained locks.
std::vector<Object> output;
output.clear();
if (!_licenseValid) {
@@ -587,10 +592,15 @@ namespace ANSCENTER {
cv::Mat lprImage = frame(lprPos).clone();
lprObject.cameraId = cameraId;
lprObject.polygon = RectToNormalizedPolygon(lprObject.box, input.cols, input.rows);
std::vector<PaddleOCR::OCRPredictResult> res_ocr = ppocr->ocr(lprImage);
// ppocr is not thread-safe, use fine-grained lock
std::vector<PaddleOCR::OCRPredictResult> res_ocr;
{
std::lock_guard<std::mutex> ocrLock(_ocrMutex);
res_ocr = ppocr->ocr(lprImage);
}
int detectionSize = res_ocr.size();
if ((detectionSize > 0) && (detectionSize < 3)) {
for (int n = 0; n < res_ocr.size(); n++) { // number of detections
for (int n = 0; n < res_ocr.size(); n++) { // number of detections
ocrText.append(res_ocr[n].text);
}
std::string rawText = AnalyseLicensePlateText(ocrText);
@@ -613,7 +623,7 @@ namespace ANSCENTER {
}
}
bool ANSALPR_CPU::Inference(const cv::Mat& input, const std::vector<cv::Rect> & Bbox, std::string& lprResult) {
std::lock_guard<std::recursive_mutex> lock(_mutex);
// No coarse _mutex — delegates to Inference(input, Bbox, lprResult, cameraId)
if (input.empty()) return false;
if ((input.cols < 5) || (input.rows < 5)) return false;
return Inference(input, Bbox, lprResult, "CustomCam");
@@ -622,7 +632,7 @@ namespace ANSCENTER {
bool ANSALPR_CPU::Inference(const cv::Mat& input, const std::vector<cv::Rect>& Bbox,
std::string& lprResult, const std::string& cameraId)
{
std::lock_guard<std::recursive_mutex> lock(_mutex);
// No coarse _mutex — sub-components have fine-grained locks.
// Early validation
if (!_licenseValid) {
@@ -668,16 +678,12 @@ namespace ANSCENTER {
}
try {
// Convert grayscale to BGR if necessary
const cv::Mat* framePtr;
// Convert grayscale to BGR if necessary (use local buffer for thread safety)
cv::Mat localFrame;
if (input.channels() == 1) {
cv::cvtColor(input, this->_frameBuffer, cv::COLOR_GRAY2BGR);
framePtr = &this->_frameBuffer;
cv::cvtColor(input, localFrame, cv::COLOR_GRAY2BGR);
}
else {
framePtr = &input;
}
const cv::Mat& frame = *framePtr;
const cv::Mat& frame = (input.channels() == 1) ? localFrame : input;
const int frameWidth = frame.cols;
const int frameHeight = frame.rows;
@@ -794,7 +800,12 @@ namespace ANSCENTER {
cv::Mat lprImage = frame(plateRect);
cv::Mat alignedLPR = enhanceForOCR(lprImage);
std::vector<PaddleOCR::OCRPredictResult> res_ocr = ppocr->ocr(alignedLPR);
// ppocr is not thread-safe, use fine-grained lock
std::vector<PaddleOCR::OCRPredictResult> res_ocr;
{
std::lock_guard<std::mutex> ocrLock(_ocrMutex);
res_ocr = ppocr->ocr(alignedLPR);
}
const size_t detectionSize = res_ocr.size();
if (detectionSize == 0 || detectionSize >= 3) {