2026-03-30 17:09:29 +09:00

231 lines
9.3 KiB
C#

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<CodeResult> results = new List<CodeResult>();
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<CodeResult>()
};
}
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<CodeResult>;
var crosses = new List<Cross>();
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<string>();
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);
}
}
}
}