using Aurora.Api; using MilCommon; using VisionCommon; using Hermes; using Matrox.MatroxImagingLibrary; using System; using System.Collections.Generic; using System.Text; using Aurora.Api.DataType; namespace MilPattern { public enum eMilCodeType { DataMatrix = MIL.M_DATAMATRIX, QRCode = MIL.M_QRCODE } public enum eMilThresholdMode { Adaptive = MIL.M_ADAPTIVE, GlobalSeg = MIL.M_GLOBAL_SEGMENTATION, GlobalWithLocalReSeg = MIL.M_GLOBAL_WITH_LOCAL_RESEGMENTATION, } public class CodeRunParam : IRunParam, ICloneable { public eMilCodeType CodeType { get; set; } = eMilCodeType.DataMatrix; public eMilSpeed Speed { get; set; } = eMilSpeed.Default; public eMilThresholdMode ThresholdMode { get; set; } = eMilThresholdMode.Adaptive; public bool AutoThreshold { get; set; } = true; public int Threshold { get; set; } = 10; public BarCodeParamExt BarCodeParamExt { get; set; } = new BarCodeParamExt(); public bool IsValidFindRoi(ImageSize imageSize) { return (0 < BarCodeParamExt.FindROI.Width && BarCodeParamExt.FindROI.Width < imageSize.Width) && (0 < BarCodeParamExt.FindROI.Height && BarCodeParamExt.FindROI.Height < imageSize.Height); } public ROI GetFindRoi() { return BarCodeParamExt.FindROI.Clone() as ROI; } public void SetFindROI(ROI findRoi) { BarCodeParamExt.FindROI = findRoi; } public object Clone() { return new CodeRunParam() { CodeType = CodeType, Speed = Speed, ThresholdMode = ThresholdMode, AutoThreshold = AutoThreshold, Threshold = Threshold, BarCodeParamExt = BarCodeParamExt.Clone() as BarCodeParamExt }; } } internal static class MilCode { private static Logger _logger = new Logger(typeof(MilCode).Name); public static MIL_ID CreateContext(MIL_ID milSystem) { MIL_ID contextId = MIL.M_NULL; MIL.McodeAlloc(milSystem, MIL.M_DEFAULT, MIL.M_DEFAULT, ref contextId); return contextId; } public static MIL_ID LoadContext(MIL_ID milSystem, string filePath) { MIL_ID contextId = MIL.M_NULL; MIL.McodeRestore(filePath, milSystem, MIL.M_DEFAULT, ref contextId); return contextId; } public static int SaveContext(MIL_ID contextId, string filePath) { if (contextId != MIL.M_NULL && filePath != null) { MIL.McodeSave(filePath, contextId, MIL.M_DEFAULT); return E1.OK; } return E1.GENERIC; } public static void FreeContext(MIL_ID contextId) { if (contextId != MIL.M_NULL) { MIL.McodeFree(contextId); } } public static MIL_ID CreateResultContext(MIL_ID contextId) { var milSystem = GetSystemOfContext(contextId); return MIL.McodeAllocResult(milSystem, MIL.M_DEFAULT, MIL.M_NULL); } private static MIL_ID GetSystemOfContext(MIL_ID contextId) { return (MIL_ID)MIL.McodeInquire(contextId, MIL.M_OWNER_SYSTEM, MIL.M_NULL); } public static CodeRunParam GetRunParam(MIL_ID contextId) { var codeRunParam = new CodeRunParam(); if (HasModel(contextId)) { double codeType = MIL.McodeInquire(contextId, MIL.M_CODE_TYPE, MIL.M_NULL); if (codeType != MIL.M_DEFAULT) { codeRunParam.CodeType = (eMilCodeType)codeType; } double thresholdMode = MIL.McodeInquire(contextId, MIL.M_THRESHOLD_MODE, MIL.M_NULL); if (thresholdMode != MIL.M_DEFAULT) { codeRunParam.ThresholdMode = (eMilThresholdMode)thresholdMode; } double threshold = MIL.McodeInquire(contextId, MIL.M_THRESHOLD_VALUE, MIL.M_NULL); codeRunParam.AutoThreshold = (threshold == MIL.M_AUTO_COMPUTE); codeRunParam.Threshold = (int)threshold; codeRunParam.Speed = (eMilSpeed)Convert.ToInt32(MIL.McodeInquire(contextId, MIL.M_SPEED, MIL.M_NULL)); } return codeRunParam; } public static int SetRunParam(MIL_ID contextId, IRunParam runParam) { if (runParam is CodeRunParam) { var param = runParam as CodeRunParam; MIL.McodeModel(contextId, MIL.M_ADD, (long)param.CodeType, MIL.M_NULL, MIL.M_DEFAULT, MIL.M_NULL); MIL.McodeControl(contextId, MIL.M_INITIALIZATION_MODE, MIL.M_IMPROVED_RECOGNITION); MIL.McodeControl(contextId, MIL.M_THRESHOLD_MODE, (double)param.ThresholdMode); MIL.McodeControl(contextId, MIL.M_SPEED, (double)param.Speed); if (param.AutoThreshold) { MIL.McodeControl(contextId, MIL.M_THRESHOLD_VALUE, MIL.M_AUTO_COMPUTE); } else { MIL.McodeControl(contextId, MIL.M_THRESHOLD_VALUE, param.Threshold); } return E1.OK; } return E1.GENERIC; } public static bool HasModel(MIL_ID contextId) { return MIL.McodeInquire(contextId, MIL.M_NUMBER_OF_CODE_MODELS, MIL.M_NULL) > 0; } public static PatternResult Find(MIL_ID contextId, MIL_ID resultContextId, MIL_ID image) { MIL.MappTimer(MIL.M_DEFAULT, MIL.M_TIMER_RESET + MIL.M_SYNCHRONOUS, MIL.M_NULL); MIL.McodeRead(contextId, image, resultContextId); double tactTime = 0; MIL.MappTimer(MIL.M_DEFAULT, MIL.M_TIMER_READ + MIL.M_SYNCHRONOUS, ref tactTime); var finderResult = ExtractResults(resultContextId, MilEnvironment.GetImageCenter(image)); finderResult.TactTimeInMilliSec = MathUtil.ConvertUnitSecToMilli(tactTime); return finderResult; } private static PatternResult ExtractResults(MIL_ID contextResult, ImagePoint imageCenter) { List results = new List(); MIL_INT resultStatus = 0; MIL.McodeGetResult(contextResult, MIL.M_GENERAL, MIL.M_GENERAL, MIL.M_STATUS + MIL.M_TYPE_MIL_INT, ref resultStatus); if (resultStatus == MIL.M_STATUS_READ_OK) { int STRING_LENGTH_MAX = 64; StringBuilder codeString = new StringBuilder(STRING_LENGTH_MAX); MIL.McodeGetResult(contextResult, 0, MIL.M_GENERAL, MIL.M_STRING, codeString); double posX = 0, posY = 0; double score = 0; double angleDeg = 0; MIL.McodeGetResult(contextResult, 0, MIL.M_GENERAL, MIL.M_POSITION_X, ref posX); MIL.McodeGetResult(contextResult, 0, MIL.M_GENERAL, MIL.M_POSITION_Y, ref posY); MIL.McodeGetResult(contextResult, 0, MIL.M_GENERAL, MIL.M_SCORE, ref score); MIL.McodeGetResult(contextResult, 0, MIL.M_GENERAL, MIL.M_ANGLE, ref angleDeg); // Warning : Counter Clockwise results.Add(new CodeResult( position: new ImagePoint(posX, posY), offset: (new ImagePoint(posX, posY) - imageCenter) as ImagePoint, angle: Angle.NormalizeAngle(Angle.CreateWithDegree(angleDeg)), code: codeString.ToString())); } return new PatternResult() { Status = (results.Count > 0) ? eFoundStatus.FoundOK : eFoundStatus.NotFound, Results = results }; } public static PatternResult GetNotFoundPatternResult() { return new PatternResult() { Status = eFoundStatus.NotFound, Results = new List() }; } public static void Draw(PatternResult patternResult, IMilCameraDisplay milCameraDisplay) { MIL_ID staticGraphicList = 0; MIL.MdispInquire(milCameraDisplay.GetMilDisplayId(), MIL.M_ASSOCIATED_GRAPHIC_LIST_ID, ref staticGraphicList); if (patternResult.Status == eFoundStatus.FoundOK) { var results = patternResult.Results as List; var crosses = new List(); foreach (var result in results) { var color = GraphicColors.PatternFoundOK; var cross = new Cross(result.ImagePosition.Clone() as ImagePoint, 50); crosses.Add(cross); milCameraDisplay.SetPatternTracking(cross); milCameraDisplay.AddCross(cross, color); var msgs = new List(); msgs.Add(string.Format("X : {0:0.00}", result.ImagePosition.X)); msgs.Add(string.Format("Y : {0:0.00}", result.ImagePosition.Y)); msgs.Add(string.Format("Angle : {0:0.00}", result.Angle.Degree)); msgs.Add(string.Format("Code : {0}", result.Code)); milCameraDisplay.AddTextList( GraphicColors.PatternFoundOK, new ImagePoint(result.ImagePosition.X, result.ImagePosition.Y), msgs); } milCameraDisplay.DrawPatternTrackings(crosses); } } } }