659 lines
27 KiB
C#
659 lines
27 KiB
C#
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<PatternMatchingResult>()
|
|
};
|
|
}
|
|
|
|
private static PatternResult ExtractResults(MIL_ID contextResult, ImagePoint imageCenter, ROI findRoi) {
|
|
var results = new List<PatternMatchingResult>();
|
|
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<Cross>();
|
|
|
|
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<string>();
|
|
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;
|
|
}
|
|
}
|
|
}
|