using Aurora.Api; using MilCommon; using VisionCommon; using Hermes; using Matrox.MatroxImagingLibrary; using System; using System.Collections.Generic; using Aurora.Api.DataType; namespace MilPattern { public enum eMilPatSpeed { High = MIL.M_HIGH, Low = MIL.M_LOW, Medium = MIL.M_MEDIUM, VeryHigh = MIL.M_VERY_HIGH, VeryLow = MIL.M_VERY_LOW, } public class PatternMatchingRunParam : IRunParam, ICloneable { public int FindNumber { get; set; } = 1; public double Acceptance { get; set; } = 60; public double Certainty { get; set; } = 90; public Angle AngleTolerance { get; set; } = Angle.CreateWithDegree(180); // (0, 180) public eMilAccuracy Accuracy { get; set; } = eMilAccuracy.Default; public eMilPatSpeed Speed { get; set; } = eMilPatSpeed.Medium; public double Score { get; set; } = 60; public PmParamExt PmParamExt { get; set; } = new PmParamExt(); public bool IsValidFindRoi(ImageSize imageSize) { return (0 < PmParamExt.FindROI.Width && PmParamExt.FindROI.Width < imageSize.Width) && (0 < PmParamExt.FindROI.Height && PmParamExt.FindROI.Height < imageSize.Height); } public ROI GetFindRoi() { return PmParamExt.FindROI.Clone() as ROI; } public void SetFindROI(ROI findRoi) { PmParamExt.FindROI = findRoi; } public object Clone() { return new PatternMatchingRunParam() { FindNumber = FindNumber, Acceptance = Acceptance, Certainty = Certainty, AngleTolerance = AngleTolerance.Clone() as Angle, Accuracy = Accuracy, Speed = Speed, Score = Score, PmParamExt = PmParamExt.Clone() as PmParamExt }; } } public class PatternMatchingTrainParam : ImageTrainParam, ICloneable { public object Clone() { return new PatternMatchingTrainParam() { TrainImage = TrainImage, TrainRoi = TrainRoi.Clone() as ROI, TrainOrigin = TrainOrigin.Clone() as Cross, TrainOriginInModel = TrainOriginInModel.Clone() as Cross }; } } internal static class MilPatternMatching { private static Logger _Logger = new Logger(typeof(MilPatternMatching).Name); public static MIL_ID CreateContext(MIL_ID milSystem) { MIL_ID contextId = MIL.M_NULL; MIL.MpatAlloc(milSystem, MIL.M_NORMALIZED, MIL.M_DEFAULT, ref contextId); return contextId; } public static MIL_ID LoadContext(MIL_ID milSystem, string filePath) { MIL_ID contextId = MIL.M_NULL; MIL.MpatRestore(filePath, milSystem, MIL.M_DEFAULT, ref contextId); if (HasModel(contextId)) { MIL.MpatPreprocess(contextId, MIL.M_DEFAULT, MIL.M_NULL); } return contextId; } public static int SaveContext(MIL_ID contextId, string filePath) { if (contextId != MIL.M_NULL && filePath != null) { MIL.MpatSave(filePath, contextId, MIL.M_DEFAULT); return E1.OK; } return E1.GENERIC; } public static void FreeContext(MIL_ID contextId) { if (contextId != MIL.M_NULL) { MIL.MpatFree(contextId); } } public static MIL_ID CreateResultContext(MIL_ID contextId) { var milSystem = GetSystemOfContext(contextId); return MIL.MpatAllocResult(milSystem, MIL.M_DEFAULT, MIL.M_NULL); } public static MIL_ID GetSystemOfContext(MIL_ID contextId) { return (MIL_ID)MIL.MpatInquire(contextId, MIL.M_CONTEXT, MIL.M_OWNER_SYSTEM, MIL.M_NULL); } public static bool IsPreprocessed(MIL_ID contextId) { if (contextId == MIL.M_NULL) { return false; } return MIL.M_TRUE == MIL.MpatInquire(contextId, MIL.M_CONTEXT, MIL.M_PREPROCESSED, MIL.M_NULL); } public static void DeleteAllModels(MIL_ID contextId) { if (HasModel(contextId)) { MIL.MpatDefine(contextId, MIL.M_DELETE, MIL.M_NULL, MIL.M_ALL, MIL.M_DEFAULT, MIL.M_DEFAULT, MIL.M_DEFAULT, MIL.M_DEFAULT); } } public static bool HasModel(MIL_ID contextId) { return MIL.MpatInquire(contextId, MIL.M_CONTEXT, MIL.M_NUMBER_MODELS, MIL.M_NULL) > 0; } public static ROI GetFindRoiFromMpat(MIL_ID contextId) { if (HasModel(contextId)) { double x = 0; MIL.MpatInquire(contextId, MIL.M_DEFAULT, MIL.M_SEARCH_OFFSET_X, ref x); double y = 0; MIL.MpatInquire(contextId, MIL.M_DEFAULT, MIL.M_SEARCH_OFFSET_Y, ref y); double width = 0; MIL.MpatInquire(contextId, MIL.M_DEFAULT, MIL.M_SEARCH_SIZE_X, ref width); double height = 0; MIL.MpatInquire(contextId, MIL.M_DEFAULT, MIL.M_SEARCH_SIZE_Y, ref height); if (width != MIL.M_ALL && height != MIL.M_ALL) { double centerX = x + (width * 0.5); double centerY = y + (height * 0.5); return new ROI( new ImagePoint(centerX, centerY), width, height); } } return new ROI(); } public static int SetFindRoiToMpat(MIL_ID contextId, ROI findRoi) { if (findRoi.Width > 0 && findRoi.Height > 0) { if (HasModel(contextId)) { MIL.MpatControl(contextId, MIL.M_ALL, MIL.M_SEARCH_OFFSET_X, findRoi.Left); MIL.MpatControl(contextId, MIL.M_ALL, MIL.M_SEARCH_OFFSET_Y, findRoi.Top); MIL.MpatControl(contextId, MIL.M_ALL, MIL.M_SEARCH_SIZE_X, findRoi.Width); MIL.MpatControl(contextId, MIL.M_ALL, MIL.M_SEARCH_SIZE_Y, findRoi.Height); } } else { ClearFindRoi(contextId); } return E1.OK; } public static int ClearFindRoi(MIL_ID contextId) { if (HasModel(contextId)) { MIL.MpatControl(contextId, MIL.M_ALL, MIL.M_SEARCH_OFFSET_X, MIL.M_DEFAULT); MIL.MpatControl(contextId, MIL.M_ALL, MIL.M_SEARCH_OFFSET_Y, MIL.M_DEFAULT); MIL.MpatControl(contextId, MIL.M_ALL, MIL.M_SEARCH_SIZE_X, MIL.M_DEFAULT); MIL.MpatControl(contextId, MIL.M_ALL, MIL.M_SEARCH_SIZE_Y, MIL.M_DEFAULT); } return E1.OK; } public static PatternMatchingRunParam GetRunParam(MIL_ID contextId) { var patternMatchingRunParam = new PatternMatchingRunParam(); if (HasModel(contextId)) { double acceptance = 0; MIL.MpatInquire(contextId, MIL.M_DEFAULT, MIL.M_ACCEPTANCE, ref acceptance); if (acceptance != MIL.M_DEFAULT) { patternMatchingRunParam.Acceptance = acceptance; } double certainty = 0; MIL.MpatInquire(contextId, MIL.M_DEFAULT, MIL.M_CERTAINTY, ref certainty); if (certainty != MIL.M_DEFAULT) { patternMatchingRunParam.Certainty = certainty; } double angleDeg = 0; MIL.MpatInquire(contextId, MIL.M_DEFAULT, MIL.M_SEARCH_ANGLE_DELTA_POS, ref angleDeg); if (angleDeg != MIL.M_DEFAULT) { patternMatchingRunParam.AngleTolerance = Angle.CreateWithDegree(angleDeg); } patternMatchingRunParam.Accuracy = (eMilAccuracy)Convert.ToInt32(MIL.MpatInquire(contextId, MIL.M_DEFAULT, MIL.M_ACCURACY, MIL.M_NULL)); patternMatchingRunParam.Speed = (eMilPatSpeed)Convert.ToInt32(MIL.MpatInquire(contextId, MIL.M_DEFAULT, MIL.M_SPEED, MIL.M_NULL)); patternMatchingRunParam.FindNumber = Convert.ToInt32(MIL.MpatInquire(contextId, MIL.M_DEFAULT, MIL.M_NUMBER, MIL.M_NULL)); } return patternMatchingRunParam; } public static int SetRunParam(MIL_ID contextId, IRunParam runParam) { if (runParam is PatternMatchingRunParam) { var param = runParam as PatternMatchingRunParam; if (HasModel(contextId)) { MIL.MpatControl(contextId, MIL.M_ALL, MIL.M_ACCURACY, (double)param.Accuracy); MIL.MpatControl(contextId, MIL.M_ALL, MIL.M_SPEED, (double)param.Speed); MIL.MpatControl(contextId, MIL.M_ALL, MIL.M_NUMBER, param.FindNumber); MIL.MpatControl(contextId, MIL.M_ALL, MIL.M_ACCEPTANCE, param.Acceptance); MIL.MpatControl(contextId, MIL.M_ALL, MIL.M_CERTAINTY, param.Certainty); if (param.AngleTolerance.Degree > 0) { MIL.MpatControl(contextId, MIL.M_ALL, MIL.M_SEARCH_ANGLE_MODE, MIL.M_ENABLE); MIL.MpatControl(contextId, MIL.M_ALL, MIL.M_SEARCH_ANGLE_TOLERANCE, param.AngleTolerance.Degree); MIL.MpatControl(contextId, MIL.M_ALL, MIL.M_SEARCH_ANGLE_ACCURACY, 0.5); MIL.MpatControl(contextId, MIL.M_ALL, MIL.M_SEARCH_ANGLE_DELTA_POS, param.AngleTolerance.Degree); MIL.MpatControl(contextId, MIL.M_ALL, MIL.M_SEARCH_ANGLE_DELTA_NEG, param.AngleTolerance.Degree); } else { MIL.MpatControl(contextId, MIL.M_ALL, MIL.M_SEARCH_ANGLE_MODE, MIL.M_DISABLE); } ClearFindRoi(contextId); MIL.MpatPreprocess(contextId, MIL.M_DEFAULT, MIL.M_NULL); } return E1.OK; } return E1.GENERIC; } public static PatternResult Find(MIL_ID contextId, MIL_ID resultContextId, MIL_ID image, ROI findRoi) { if (MilEnvironment.IsColorImage(image)) { var grayImageId = MilEnvironment.ConvertToGray(image); var patternResult = FindInternal(contextId, resultContextId, grayImageId, findRoi); MilEnvironment.FreeImage(grayImageId); return patternResult; } return FindInternal(contextId, resultContextId, image, findRoi); } private static PatternResult FindInternal(MIL_ID contextId, MIL_ID resultContextId, MIL_ID image, ROI findRoi) { PatternResult finderResult; MIL.MappTimer(MIL.M_DEFAULT, MIL.M_TIMER_RESET + MIL.M_SYNCHRONOUS, MIL.M_NULL); if (HasModel(contextId)) { if (ROI.IsNullOrEmpty(findRoi)) { MIL.MpatFind(contextId, image, resultContextId); finderResult = ExtractResults(resultContextId, MilEnvironment.GetImageCenter(image), findRoi); } else { var fittedFindRoi = FindWithCropImage(contextId, resultContextId, image, findRoi); finderResult = ExtractResults(resultContextId, MilEnvironment.GetImageCenter(image), fittedFindRoi); } } else { finderResult = GetNotFoundPatternResult(); } double tactTime = 0; MIL.MappTimer(MIL.M_DEFAULT, MIL.M_TIMER_READ + MIL.M_SYNCHRONOUS, ref tactTime); finderResult.TactTimeInMilliSec = MathUtil.ConvertUnitSecToMilli(tactTime); return finderResult; } private static ROI FindWithCropImage(MIL_ID contextId, MIL_ID resultContextId, MIL_ID image, ROI findRoi) { MIL_ID cropImage = MIL.M_NULL; ROI fittedFindRoi = findRoi.Clone() as ROI; try { var imageSzie = MilEnvironment.GetImageSize(image); if (ROI.IsOutsideImage(findRoi, imageSzie)) { fittedFindRoi = ROI.FitRoiToImage(findRoi, imageSzie); } cropImage = MilEnvironment.CropImage(image, fittedFindRoi); MIL.MpatFind(contextId, cropImage, resultContextId); } catch (Exception e) { _Logger.E(e.Message); } finally { MilEnvironment.FreeImage(cropImage); } return fittedFindRoi; } public static PatternResult GetNotFoundPatternResult() { return new PatternResult() { Status = eFoundStatus.NotFound, Results = new List() }; } private static PatternResult ExtractResults(MIL_ID contextResult, ImagePoint imageCenter, ROI findRoi) { var results = new List(); MIL_INT numOfResult = 0; MIL.MpatGetResult(contextResult, MIL.M_DEFAULT, MIL.M_NUMBER + MIL.M_TYPE_MIL_INT, ref numOfResult); for (int resultIndex = 0; resultIndex < numOfResult; resultIndex++) { double posX = 0, posY = 0; double score = 0; double angleDeg = 0; MIL.MpatGetResult(contextResult, resultIndex, MIL.M_POSITION_X, ref posX); MIL.MpatGetResult(contextResult, resultIndex, MIL.M_POSITION_Y, ref posY); MIL.MpatGetResult(contextResult, resultIndex, MIL.M_SCORE, ref score); MIL.MpatGetResult(contextResult, resultIndex, MIL.M_ANGLE, ref angleDeg); // Warning : Counter Clockwise posX += findRoi.Left; posY += findRoi.Top; results.Add(new PatternMatchingResult( position: new ImagePoint(posX, posY), offset: (new ImagePoint(posX, posY) - imageCenter) as ImagePoint, angle: Angle.NormalizeAngle(Angle.CreateWithDegree(angleDeg)), score: score)); } return new PatternResult() { Status = (results.Count > 0) ? eFoundStatus.FoundOK : eFoundStatus.NotFound, Results = results }; } public static void Draw( PatternResult patternResult, IMilCameraDisplay milCameraDisplay, bool isFixturePattern) { if (patternResult == null || patternResult.Results == null) { return; } var crosses = new List(); foreach (BaseResult baseResult in patternResult.Results) { var result = baseResult as PatternMatchingResult; if (result.Score > 0) { var color = GraphicColors.GetFindResultColor(patternResult.Status, isFixturePattern); // MIL : 시계 방향(-), 반시계 방향(+) var cross = new Cross(result.ImagePosition.Clone() as ImagePoint, -result.Angle, 50); crosses.Add(cross); milCameraDisplay.SetPatternTracking(cross); milCameraDisplay.AddCross(cross, color); var msgs = new List(); msgs.Add(string.Format("I({0:0.0}, {1:0.0})", result.ImagePosition.X, result.ImagePosition.Y)); msgs.Add(result.ConvertMaterialPosition()); msgs.Add(string.Format("Angle : {0:0.00}", result.Angle.Degree)); msgs.Add(string.Format("Score : {0:0.00}", result.Score)); msgs.Add(string.Format("TactTime : {0} ms", Math.Round(patternResult.TactTimeInMilliSec))); msgs.Add(string.Format("ID : {0}_{1}", patternResult.PatternIndex.PatternId, patternResult.PatternIndex.PatternSubId)); milCameraDisplay.AddTextList( color, new ImagePoint(result.ImagePosition.X, result.ImagePosition.Y), msgs); } milCameraDisplay.DrawPatternTrackings(crosses); } } public static ITrainParam GetTrainParam(MIL_ID contextId) { var trainParam = new PatternMatchingTrainParam(); if (HasModel(contextId)) { trainParam.TrainRoi = GetTrainROI(contextId); trainParam.TrainOrigin = GetFixtureOrigin(contextId); trainParam.TrainOriginInModel = GetTrainOriginInModel(contextId); } return trainParam; } public static ROI GetTrainROI(MIL_ID contextId) { if (HasModel(contextId)) { MIL_INT x = MIL.MpatInquire(contextId, MIL.M_DEFAULT, MIL.M_ALLOC_OFFSET_X, MIL.M_NULL); MIL_INT y = MIL.MpatInquire(contextId, MIL.M_DEFAULT, MIL.M_ALLOC_OFFSET_Y, MIL.M_NULL); MIL_INT width = MIL.MpatInquire(contextId, MIL.M_DEFAULT, MIL.M_ALLOC_SIZE_X, MIL.M_NULL); MIL_INT height = MIL.MpatInquire(contextId, MIL.M_DEFAULT, MIL.M_ALLOC_SIZE_Y, MIL.M_NULL); return new ROI( x + (width * 0.5), y + (height * 0.5), width, height, new Angle()); } return new ROI(); } public static Cross GetFixtureOrigin(MIL_ID contextId) { if (HasModel(contextId)) { double originalX = 0; MIL.MpatInquire(contextId, MIL.M_DEFAULT, MIL.M_ORIGINAL_X, ref originalX); double originalY = 0; MIL.MpatInquire(contextId, MIL.M_DEFAULT, MIL.M_ORIGINAL_Y, ref originalY); return new Cross(new ImagePoint(originalX, originalY)); } return new Cross(new ImagePoint()); } public static Cross GetTrainOriginInModel(MIL_ID contextId) { if (HasModel(contextId)) { double trainOriginInModelX = 0; MIL.MpatInquire(contextId, MIL.M_DEFAULT, MIL.M_REFERENCE_X, ref trainOriginInModelX); double trainOriginInModelY = 0; MIL.MpatInquire(contextId, MIL.M_DEFAULT, MIL.M_REFERENCE_Y, ref trainOriginInModelY); return new Cross(new ImagePoint(trainOriginInModelX, trainOriginInModelY)); } return new Cross(new ImagePoint()); } public static int Train(MIL_ID contextId, ITrainParam trainParam) { DeleteAllModels(contextId); if (trainParam is PatternMatchingTrainParam) { var param = trainParam as PatternMatchingTrainParam; return DefineModel(contextId, param); } return E1.GENERIC; } private static int DefineModel(MIL_ID contextId, PatternMatchingTrainParam param) { if ((MIL_ID)param.TrainImage == MIL.M_NULL) { return E1.ARGUMENT; } if (param.TrainRoi is null && param.TrainOrigin is null) { return Train(contextId, (MIL_ID)param.TrainImage); } else if (param.TrainRoi is null) { return Train(contextId, (MIL_ID)param.TrainImage, param.TrainOrigin); } else if (param.TrainOrigin is null) { return Train(contextId, (MIL_ID)param.TrainImage, param.TrainRoi); } return Train(contextId, (MIL_ID)param.TrainImage, param.TrainRoi, param.TrainOrigin); } public static int Train(MIL_ID contextId, MIL_ID trainImage) { var imageCenter = MilEnvironment.GetImageCenter(trainImage); return Train(contextId, trainImage, new Cross(imageCenter)); } public static int Train(MIL_ID contextId, MIL_ID trainImage, Cross trainOrigin) { var imageCenter = MilEnvironment.GetImageCenter(trainImage); var imageSize = MilEnvironment.GetImageSize(trainImage); return Train( contextId, trainImage, new ROI(imageCenter, imageSize.Width, imageSize.Height), trainOrigin); } public static int Train(MIL_ID contextId, MIL_ID trainImage, ROI trainRoi) { return Train( contextId, trainImage, trainRoi, trainRoi.Center); } public static int Train(MIL_ID contextId, MIL_ID trainImage, ROI trainRoi, ImagePoint trainOrigin) { var originInTrainRoi = new Cross(new ImagePoint( trainOrigin.X - trainRoi.Left, trainOrigin.Y - trainRoi.Top)); return TrainImpl( contextId, trainImage, trainRoi, originInTrainRoi); } public static int Train(MIL_ID contextId, MIL_ID trainImage, ROI trainRoi, Cross trainOrigin) { var originInTrainRoi = new Cross(new ImagePoint( trainOrigin.Origin.X - trainRoi.Left, trainOrigin.Origin.Y - trainRoi.Top)); return TrainImpl( contextId, trainImage, trainRoi, originInTrainRoi); } private static int TrainImpl(MIL_ID contextId, MIL_ID trainImage, ROI trainRoi, Cross originInTrainRoi) { if (MilEnvironment.IsColorImage(trainImage)) { var grayTrainImage = MilEnvironment.ConvertToGray(trainImage); var result = TrainWithGrayImage(contextId, grayTrainImage, trainRoi, originInTrainRoi); MIL.MbufFree(grayTrainImage); return result; } return TrainWithGrayImage(contextId, trainImage, trainRoi, originInTrainRoi); } private static int TrainWithGrayImage(MIL_ID contextId, MIL_ID grayTrainImage, ROI trainRoi, Cross originInTrainRoi) { DeleteAllModels(contextId); TrainWholeImageWithTrainROI(contextId, grayTrainImage, trainRoi); return SetTrainOrigin(contextId, originInTrainRoi); } public static int SetTrainOrigin(MIL_ID contextId, Cross originInTrainRoi) { if (HasModel(contextId)) { MIL.MpatControl(contextId, MIL.M_ALL, MIL.M_REFERENCE_X, originInTrainRoi.Origin.X); MIL.MpatControl(contextId, MIL.M_ALL, MIL.M_REFERENCE_Y, originInTrainRoi.Origin.Y); } MIL.MpatPreprocess(contextId, MIL.M_DEFAULT, MIL.M_NULL); if (!IsPreprocessed(contextId)) { return E1.GENERIC; } return E1.OK; } private static void TrainWholeImageWithTrainROI(MIL_ID contextId, MIL_ID grayTrainImage, ROI trainRoi) { MIL.MpatDefine( contextId, MIL.M_REGULAR_MODEL, grayTrainImage, trainRoi.Left, trainRoi.Top, trainRoi.Width, trainRoi.Height, MIL.M_DEFAULT); } private static void TrainWholeImageWithGraphicTrainROI(MIL_ID contextId, MIL_ID grayTrainImage, ROI trainRoi) { // MIL Help에서는 Graphic train ROI가 지원되는 것으로 되어 있으나, // 실제로는 Train이 불가능하다. // 1. Alloc graphic context MIL_ID graphicList = MIL.M_NULL; MIL_ID graphicsContext = MIL.M_NULL; MIL_ID systemId = MmfCommon.GetSystemOfContext(contextId); MIL.MgraAllocList(systemId, MIL.M_DEFAULT, ref graphicList); MIL.MgraAlloc(systemId, ref graphicsContext); // 2. Set graphic ROI to train image MIL.MgraRectAngle( graphicsContext, graphicList, trainRoi.CenterX, trainRoi.CenterY, trainRoi.Width, trainRoi.Height, trainRoi.Angle.Degree, MIL.M_CENTER_AND_DIMENSION); MIL.MbufSetRegion(grayTrainImage, graphicList, MIL.M_DEFAULT, MIL.M_RASTERIZE + MIL.M_FILL_REGION, MIL.M_DEFAULT); // 3. Train MIL.MpatDefine( contextId, MIL.M_REGULAR_MODEL, grayTrainImage, MIL.M_DEFAULT, MIL.M_DEFAULT, MIL.M_DEFAULT, MIL.M_DEFAULT, MIL.M_DEFAULT); // 4. Delete graphic ROI MIL.MbufSetRegion(grayTrainImage, MIL.M_NULL, MIL.M_DEFAULT, MIL.M_DELETE, MIL.M_DEFAULT); // 5. Free graphic MIL.MgraFree(graphicsContext); MIL.MgraFree(graphicList); } public static MIL_ID GetGrayModelImage(MIL_ID contextId) { if (HasModel(contextId)) { return GetModelImageFromContext(contextId, 1); } return MIL.M_NULL; } public static MIL_ID GetColorModelImage(MIL_ID contextId) { if (HasModel(contextId)) { return GetModelImageFromContext(contextId, 3); } return MIL.M_NULL; } private static MIL_ID GetModelImageFromContext(MIL_ID contextId, int channel) { MIL_INT sizeX = MIL.MpatInquire(contextId, 0, MIL.M_ALLOC_SIZE_X, MIL.M_NULL); MIL_INT sizeY = MIL.MpatInquire(contextId, 0, MIL.M_ALLOC_SIZE_Y, MIL.M_NULL); MIL_ID systemId = GetSystemOfContext(contextId); MIL_ID colorModelImageId = MIL.MbufAllocColor( systemId, channel, sizeX, sizeY, 8 + MIL.M_UNSIGNED, MIL.M_IMAGE + MIL.M_GRAB + MIL.M_PROC + MIL.M_DISP, MIL.M_NULL); MIL.MpatDraw(MIL.M_DEFAULT, contextId, colorModelImageId, MIL.M_DRAW_IMAGE, MIL.M_DEFAULT, MIL.M_DEFAULT); return colorModelImageId; } public static MIL_ID GetMaskImage(MIL_ID contextId) { return GetGrayMaskImage(contextId); } public static void DrawMaskImage(MIL_ID contextId, MIL_ID overalyId) { MIL_ID grayMaskImageId = GetGrayMaskImage(contextId); if (grayMaskImageId != MIL.M_NULL) { ConvertMaskGrayToColorImage(grayMaskImageId, overalyId); } } private static MIL_ID GetGrayMaskImage(MIL_ID contextId) { MIL_ID grayMaskImageId = MIL.M_NULL; if (HasModel(contextId)) { MIL_INT sizeX = MIL.MpatInquire(contextId, 0, MIL.M_ALLOC_SIZE_X, MIL.M_NULL); MIL_INT sizeY = MIL.MpatInquire(contextId, 0, MIL.M_ALLOC_SIZE_Y, MIL.M_NULL); int channel = 1; MIL_ID systemId = GetSystemOfContext(contextId); grayMaskImageId = MIL.MbufAllocColor( systemId, channel, sizeX, sizeY, 8 + MIL.M_UNSIGNED, MIL.M_IMAGE + MIL.M_GRAB + MIL.M_PROC + MIL.M_DISP, MIL.M_NULL); MIL.MbufClear(grayMaskImageId, 0); MIL.MpatDraw(MIL.M_DEFAULT, contextId, grayMaskImageId, MIL.M_DRAW_DONT_CARE, MIL.M_DEFAULT, MIL.M_DEFAULT); } return grayMaskImageId; } private static void ConvertMaskGrayToColorImage(MIL_ID grayMaskImage, MIL_ID colorMaskImage) { MIL_ID COLOR_MASK = MIL.M_COLOR_DARK_MAGENTA; MIL.MbufClearCond(colorMaskImage, MIL.M_RGB888_R((int)COLOR_MASK), MIL.M_RGB888_G((int)COLOR_MASK), MIL.M_RGB888_B((int)COLOR_MASK), grayMaskImage, MIL.M_EQUAL, 255); } public static int SetMaskImage(MIL_ID contextId, MIL_ID maskImage) { MIL.MpatMask(contextId, 0, maskImage, MIL.M_DONT_CARE, MIL.M_DEFAULT); return E1.OK; } } }