/* * Copyright (c) 2025 LG Electronics Inc. * SPDX-License-Identifier: LicenseRef-LGE-Proprietary */ using Aurora.Api; using MilCommon; using VisionCommon; using Hermes; using Matrox.MatroxImagingLibrary; using System; using System.IO; using System.Drawing; using VisionCommonUI; using System.Collections.Generic; namespace MilPattern { public class OcrFinder : PatternBase, IPatternFinder, IDisposable { [Obsolete] public string FILE_EXT_PATTERN { get; set; } = ""; public string FILE_EXT_PATTERN_STR { get; set; } = ".msr"; public string FILE_EXT_PATTERN_OCR { get; set; } = ".mfo"; private OcrParamExt _paramExt = null; private Logger _logger; private PatternInfo _patternInfo; private MIL_ID _contextId_Str = MIL.M_NULL; private MIL_ID _resultContextId_Str = MIL.M_NULL; private MIL_ID _contextId_Ocr = MIL.M_NULL; private MIL_ID _resultContextId_Ocr = MIL.M_NULL; public OcrFinder(PatternInfo patternInfo) { _patternInfo = patternInfo; _logger = new Logger( $"StrRead_{patternInfo.GetPatternIndex()}"); InitContext(); } private void InitContext() { if (E1.OK != Load()) { Create(); } } #region IPatternFinder [Obsolete] public string GetPatternFilePath(string patternName = PatternConstants.FILE_NAME_PATTERN) { return Path.Combine(new string[] { PatternConstants.GetSubPatternDirPath(_patternInfo), patternName + FILE_EXT_PATTERN }); } public string GetPatternFilePath_Str(string patternName = PatternConstants.FILE_NAME_PATTERN) { return Path.Combine(new string[] { PatternConstants.GetSubPatternDirPath(_patternInfo), patternName + FILE_EXT_PATTERN_STR }); } public string GetPatternFilePath_Ocr(string patternName = PatternConstants.FILE_NAME_PATTERN) { return Path.Combine(new string[] { PatternConstants.GetSubPatternDirPath(_patternInfo), patternName + FILE_EXT_PATTERN_OCR }); } public int Load() { FreeContexts(); // String Read var patternFilePath_Str = GetPatternFilePath_Str(); if (!File.Exists(patternFilePath_Str)) { _logger.I($"Pattern File does NOT exist : {patternFilePath_Str}"); return E2.NOT_FOUND; } _contextId_Str = MilStrRead.LoadContext(_patternInfo.MilSystemId, patternFilePath_Str); _resultContextId_Str = MilStrRead.CreateResultContext(_contextId_Str); // OCR Read var patternFilePath_Ocr = GetPatternFilePath_Ocr(); if (!File.Exists(patternFilePath_Ocr)) { _logger.I($"Pattern File does NOT exist : {patternFilePath_Ocr}"); return E2.NOT_FOUND; } _contextId_Ocr = MilOcrRead.LoadContext(_patternInfo.MilSystemId, patternFilePath_Ocr); _resultContextId_Ocr = MilOcrRead.CreateResultContext(_contextId_Ocr); _paramExt = LoadParamExt(); if (!IsParamExtExist()) { Save(); } return E1.OK; } public int Save() { var patternFilePath_Str = GetPatternFilePath_Str(); var patternDirPath_Str = Path.GetDirectoryName(patternFilePath_Str); if (!Directory.Exists(patternDirPath_Str)) { Directory.CreateDirectory(patternDirPath_Str); } var patternFilePath_Ocr = GetPatternFilePath_Ocr(); var patternDirPath_Ocr = Path.GetDirectoryName(patternFilePath_Ocr); if (!Directory.Exists(patternDirPath_Ocr)) { Directory.CreateDirectory(patternDirPath_Ocr); } SaveParamExt(_paramExt); var results = new List(); results.Add(MilStrRead.SaveContext(_contextId_Str, patternFilePath_Str)); results.Add(MilOcrRead.SaveContext(_contextId_Ocr, patternFilePath_Ocr)); foreach (int result in results) { if (result == E1.GENERIC) { return E1.GENERIC; } } return E1.OK; } public int Create() { FreeContexts(); _paramExt = LoadParamExt(); _contextId_Str = MilStrRead.CreateContext(_patternInfo.MilSystemId); _resultContextId_Str = MilStrRead.CreateResultContext(_contextId_Str); _contextId_Ocr = MilOcrRead.CreateContext(_patternInfo.MilSystemId); _resultContextId_Ocr = MilOcrRead.CreateResultContext(_contextId_Ocr); return E1.OK; } public int Remove() { FreeContexts(); var patternFilePath_Str = GetPatternFilePath_Str(); var patternDirPath_Str = Path.GetDirectoryName(patternFilePath_Str); if (Directory.Exists(patternDirPath_Str)) { Directory.Delete(patternDirPath_Str, recursive: true); } var patternFilePath_Ocr = GetPatternFilePath_Ocr(); var patternDirPath_Ocr = Path.GetDirectoryName(patternFilePath_Ocr); if (Directory.Exists(patternDirPath_Ocr)) { Directory.Delete(patternDirPath_Ocr, recursive: true); } return E1.OK; } public ROI GetFindROI() { return _paramExt.FindROI; } public int SetFindROI(ROI findRoi) { if (ROI.IsNullOrEmpty(findRoi)) { return E1.GENERIC; } _paramExt.FindROI = findRoi.Clone() as ROI; return E1.OK; } public IRunParam GetRunParam() { var runParam = MilOcr.GetRunParam(_contextId_Str, _contextId_Ocr); runParam.OcrParamExt = _paramExt.Clone() as OcrParamExt; return runParam; } public int SetRunParam(IRunParam runParam) { _paramExt = ((OcrRunParam)runParam).OcrParamExt.Clone() as OcrParamExt; TesseractRead.SetRunParam(_paramExt); return MilOcr.SetRunParam(_contextId_Str, runParam); } public PatternResult Find(object image) { return Find((MIL_ID)image, _paramExt.FindROI); } public PatternResult Find(object image, ROI findRoi) { MIL_ID cropImage = MIL.M_NULL; var patternResult = new PatternResult() { Status = eFoundStatus.NotFound }; try { if (!ROI.IsNullOrEmpty(findRoi)) { cropImage = MilEnvironment.CropImage((MIL_ID)image, findRoi); // 1차 시도 (String Read) if (_paramExt.StrReadParamExt.Enabled) { patternResult = MilStrRead.Find(_contextId_Str, _resultContextId_Str, cropImage, _paramExt); } // 2차 시도 (OCR Read) if (_paramExt.OcrReadParamExt.Enabled && patternResult.Status == eFoundStatus.NotFound) { patternResult = MilOcrRead.Find(_contextId_Ocr, _resultContextId_Ocr, cropImage, _paramExt); } // 3차 시도 (Tesseract AI) if (_paramExt.TesseractParamExt.Enabled && patternResult.Status == eFoundStatus.NotFound) { patternResult = TesseractRead.Find(cropImage, _paramExt); } if (patternResult.Status != eFoundStatus.NotFound) { var imageCenter = MilEnvironment.GetImageCenter((MIL_ID)image); foreach (OcrResult result in patternResult.Results) { result.ImagePosition = result.ImagePosition + findRoi.LeftTop as ImagePoint; result.Offset = result.ImagePosition - imageCenter as ImagePoint; } } } } catch (Exception e) { _logger.E(e.Message); } finally { MilEnvironment.FreeImage(cropImage); } return patternResult; } public PatternResult GetNotFoundPatternResult() { return MilOcr.GetNotFoundPatternResult(); } public object GetTool() { return _contextId_Str; } public void Draw( PatternResult patternResult, ICameraDisplay cameraDisplay, bool isFixturePattern = false) { MilOcr.Draw(patternResult, cameraDisplay as IMilCameraDisplay); if (patternResult.MoreInfo is eOcrType) { switch ((eOcrType)patternResult.MoreInfo) { case eOcrType.StrRead: MilStrRead.Draw(patternResult, cameraDisplay as IMilCameraDisplay, _resultContextId_Str); break; case eOcrType.OcrRead: MilOcrRead.Draw(patternResult, cameraDisplay as IMilCameraDisplay, _resultContextId_Ocr); break; } } } public Bitmap GetThumbnail() { return ThumbnailImage.OCR(); } #endregion #region IDisposible public void Dispose() { FreeContexts(); } private void FreeContexts() { MilStrRead.FreeContext(_contextId_Str); MilStrRead.FreeContext(_resultContextId_Str); MilStrRead.FreeContext(_contextId_Ocr); MilStrRead.FreeContext(_resultContextId_Ocr); _contextId_Str = MIL.M_NULL; _resultContextId_Str = MIL.M_NULL; _contextId_Ocr = MIL.M_NULL; _resultContextId_Ocr = MIL.M_NULL; } #endregion public bool IsParamExtExist() { return OcrParamExt.Exists(PatternConstants.GetSubPatternDirPath(_patternInfo)); } internal OcrParamExt LoadParamExt() { return OcrParamExt.Load(PatternConstants.GetSubPatternDirPath(_patternInfo)); } internal int SaveParamExt(OcrParamExt strReadParamExt) { return OcrParamExt.Save( PatternConstants.GetSubPatternDirPath(_patternInfo), strReadParamExt); } } }