263 lines
8.9 KiB
C#
263 lines
8.9 KiB
C#
|
using HalconDotNet;
|
|||
|
using Microsoft.ML.OnnxRuntime;
|
|||
|
using Microsoft.ML.OnnxRuntime.Tensors;
|
|||
|
using Newtonsoft.Json.Linq;
|
|||
|
using System;
|
|||
|
using System.Collections.Generic;
|
|||
|
using System.Drawing;
|
|||
|
using System.Drawing.Imaging;
|
|||
|
using System.IO;
|
|||
|
using System.Linq;
|
|||
|
using System.Reflection;
|
|||
|
using System.Text;
|
|||
|
using System.Threading;
|
|||
|
using System.Threading.Tasks;
|
|||
|
using Yolo5;
|
|||
|
|
|||
|
namespace AssistClient.Device
|
|||
|
{
|
|||
|
public class SizeLib : IDisposable
|
|||
|
{
|
|||
|
public Action<WarningEnum, string> WarningEvent;
|
|||
|
/// <summary>
|
|||
|
/// 检测结果JSON(原图,结果)
|
|||
|
/// </summary>
|
|||
|
public Action<SizeTask> finishEvent;
|
|||
|
/// <summary>
|
|||
|
/// 是否打开设备成功
|
|||
|
/// </summary>
|
|||
|
public bool IsInit { get; private set; } = false;
|
|||
|
//private System.Timers.Timer timer = new System.Timers.Timer();
|
|||
|
|
|||
|
//配置
|
|||
|
HDevEngine MyEngine = new HDevEngine();
|
|||
|
|
|||
|
private Thread t_task;
|
|||
|
public SizeLib()
|
|||
|
{
|
|||
|
}
|
|||
|
public bool start(string enginePath)
|
|||
|
{
|
|||
|
try
|
|||
|
{
|
|||
|
IsInit = true;
|
|||
|
taskList.Clear();
|
|||
|
MyEngine.SetProcedurePath(enginePath);
|
|||
|
|
|||
|
t_task = new System.Threading.Thread(run);
|
|||
|
t_task.IsBackground = true;
|
|||
|
t_task.Start();
|
|||
|
return true;
|
|||
|
}
|
|||
|
catch (Exception ex)
|
|||
|
{
|
|||
|
WarningEvent?.Invoke(WarningEnum.High, ex.Message);
|
|||
|
return false;
|
|||
|
}
|
|||
|
}
|
|||
|
public void stop()
|
|||
|
{
|
|||
|
if (!IsInit) return;
|
|||
|
|
|||
|
try
|
|||
|
{
|
|||
|
IsInit = false;
|
|||
|
//timer.Elapsed -= Timer_Elapsed;
|
|||
|
|
|||
|
MyEngine.Dispose();
|
|||
|
}
|
|||
|
catch { }
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
private bool _debug = false;
|
|||
|
public bool setDebug
|
|||
|
{
|
|||
|
get { return _debug; }
|
|||
|
set
|
|||
|
{
|
|||
|
if (!IsInit) return;
|
|||
|
|
|||
|
_debug = value;
|
|||
|
if (_debug)
|
|||
|
MyEngine.StartDebugServer();
|
|||
|
else
|
|||
|
MyEngine.StopDebugServer();
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
private void run()
|
|||
|
{
|
|||
|
int taskCount;
|
|||
|
while (IsInit)
|
|||
|
{
|
|||
|
lock (taskList)
|
|||
|
{
|
|||
|
taskCount = taskList.Count;
|
|||
|
}
|
|||
|
if (taskCount < 1)
|
|||
|
{
|
|||
|
Thread.Sleep(10);
|
|||
|
continue;
|
|||
|
}
|
|||
|
|
|||
|
////
|
|||
|
int step = 0;
|
|||
|
var task = pop();
|
|||
|
try
|
|||
|
{
|
|||
|
if (task != null)
|
|||
|
{
|
|||
|
var Program1 = new HDevProcedure(task.engineName);
|
|||
|
HDevProcedureCall ProcCall1_PI_PT = new HDevProcedureCall(Program1);
|
|||
|
step = 1;
|
|||
|
//
|
|||
|
HObject image;
|
|||
|
if (task.bmp != null)
|
|||
|
Bitmap2HObjectBpp24(out image, task.bmp);
|
|||
|
else
|
|||
|
HOperatorSet.ReadImage(out image, task.file_path);
|
|||
|
step = 2;
|
|||
|
//设置外部函数输入
|
|||
|
ProcCall1_PI_PT.SetInputIconicParamObject("Image_Repair", image);
|
|||
|
ProcCall1_PI_PT.SetInputCtrlParamTuple("Index", task.index);//参数0-9
|
|||
|
ProcCall1_PI_PT.SetInputCtrlParamTuple("PoseX", task.posX);
|
|||
|
ProcCall1_PI_PT.SetInputCtrlParamTuple("PoseY", task.posY);
|
|||
|
|
|||
|
ProcCall1_PI_PT.SetInputCtrlParamTuple("PoseMarkX_Detect_1", task.MarkPointList[0]);
|
|||
|
ProcCall1_PI_PT.SetInputCtrlParamTuple("PoseMarkY_Detect_1", task.MarkPointList[1]);
|
|||
|
ProcCall1_PI_PT.SetInputCtrlParamTuple("PoseMarkX_Detect_2", task.MarkPointList[2]);
|
|||
|
ProcCall1_PI_PT.SetInputCtrlParamTuple("PoseMarkY_Detect_2", task.MarkPointList[3]);
|
|||
|
ProcCall1_PI_PT.SetInputCtrlParamTuple("PoseMarkX_Detect_3", task.MarkPointList[4]);
|
|||
|
ProcCall1_PI_PT.SetInputCtrlParamTuple("PoseMarkY_Detect_3", task.MarkPointList[5]);
|
|||
|
ProcCall1_PI_PT.SetInputCtrlParamTuple("PoseMarkX_Detect_4", task.MarkPointList[6]);
|
|||
|
ProcCall1_PI_PT.SetInputCtrlParamTuple("PoseMarkY_Detect_4", task.MarkPointList[7]);
|
|||
|
step = 3;
|
|||
|
ProcCall1_PI_PT.Execute();//执行外部函数
|
|||
|
step = 4;
|
|||
|
//获取外部函数输出
|
|||
|
|
|||
|
step = 5;
|
|||
|
task.isSucceed = true;
|
|||
|
task.resultInfo = "成功";
|
|||
|
callback(task);
|
|||
|
}
|
|||
|
}
|
|||
|
catch (Exception ex)
|
|||
|
{
|
|||
|
WarningEvent?.Invoke(WarningEnum.Low, "SizeLib task err(" + step + "):" + ex.Message);
|
|||
|
task.isSucceed = false;
|
|||
|
task.resultInfo = $"(errcode:{step}):{ex.Message}";
|
|||
|
callback(task);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
private void callback(SizeTask task)
|
|||
|
{
|
|||
|
//返回成功/失败,异步调用
|
|||
|
if (task.finishEvent != null || (task.finishEvent = finishEvent) != null)
|
|||
|
//task.finishEvent.BeginInvoke(result, errInfo, res => task.finishEvent.EndInvoke(res), null);
|
|||
|
System.Threading.ThreadPool.QueueUserWorkItem(waitCallback, task);
|
|||
|
}
|
|||
|
//异步回调
|
|||
|
WaitCallback waitCallback = new WaitCallback(o => {
|
|||
|
var task = (SizeTask)o;
|
|||
|
task.finishEvent(task);
|
|||
|
});
|
|||
|
//=======task list
|
|||
|
private List<SizeTask> taskList = new List<SizeTask>();
|
|||
|
public class SizeTask
|
|||
|
{
|
|||
|
public int stepIndex;//库内部不用,回调时引用
|
|||
|
public string engineName;
|
|||
|
/// <summary>
|
|||
|
/// 源文件
|
|||
|
/// </summary>
|
|||
|
public string file_path;
|
|||
|
public double posX, posY;
|
|||
|
public Bitmap bmp;
|
|||
|
/// <summary>
|
|||
|
/// 比对(index=777); 计算Mark(111/222/333/444); 尺寸(0-9); 轴偏移调整(10,20,30...)
|
|||
|
/// </summary>
|
|||
|
public int index; //index=8 PT1=PT2
|
|||
|
//MARK点
|
|||
|
public double[] MarkPointList = { 0, 0, 0, 0, 0, 0, 0, 0 };
|
|||
|
/// <summary>
|
|||
|
/// 完成后回调
|
|||
|
/// </summary>
|
|||
|
public Action<SizeTask> finishEvent;
|
|||
|
public long createTime = DateTime.Now.Ticks;
|
|||
|
|
|||
|
//==结果返回
|
|||
|
/// <summary>
|
|||
|
/// 比对结果(index=777)
|
|||
|
/// </summary>
|
|||
|
public bool CompResult;
|
|||
|
public double PT1, PT2, Shanxian, Circle_Ymm, Circle_Xmm, offsetX, offsetY;
|
|||
|
public bool isSucceed;//转换是否成功
|
|||
|
public string resultInfo = "";//成功或失败信息
|
|||
|
}
|
|||
|
|
|||
|
public void add(SizeTask task)
|
|||
|
{
|
|||
|
lock (taskList)
|
|||
|
taskList.Add(task);
|
|||
|
}
|
|||
|
private SizeTask pop()
|
|||
|
{
|
|||
|
lock (taskList)
|
|||
|
{
|
|||
|
if (taskList.Count < 1)
|
|||
|
return null;
|
|||
|
|
|||
|
int index = 0;// taskList.FindIndex(p => { return p.isSync; });
|
|||
|
//if (index < 0) index = 0;
|
|||
|
var task = taskList[0];
|
|||
|
taskList.RemoveAt(0);
|
|||
|
return task;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public void Dispose()
|
|||
|
{
|
|||
|
stop();
|
|||
|
}
|
|||
|
/// <summary>
|
|||
|
/// Bitmap转HObject灰度图
|
|||
|
/// </summary>
|
|||
|
/// <param name="bmp">Bitmap图像</param>
|
|||
|
/// <param name="image">HObject图像</param>
|
|||
|
private void Bitmap2HObjectBpp8(out HObject image, Bitmap bmp)
|
|||
|
{
|
|||
|
try
|
|||
|
{
|
|||
|
Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
|
|||
|
|
|||
|
BitmapData srcBmpData = bmp.LockBits(rect, ImageLockMode.ReadOnly, PixelFormat.Format8bppIndexed);
|
|||
|
|
|||
|
HOperatorSet.GenImage1(out image, "byte", bmp.Width, bmp.Height, srcBmpData.Scan0);
|
|||
|
bmp.UnlockBits(srcBmpData);
|
|||
|
}
|
|||
|
catch (Exception)
|
|||
|
{
|
|||
|
image = null;
|
|||
|
}
|
|||
|
}
|
|||
|
public void Bitmap2HObjectBpp24(out HObject image, Bitmap bmp)
|
|||
|
{
|
|||
|
try
|
|||
|
{
|
|||
|
Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
|
|||
|
|
|||
|
BitmapData srcBmpData = bmp.LockBits(rect, ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
|
|||
|
HOperatorSet.GenImageInterleaved(out image, srcBmpData.Scan0, "bgr", bmp.Width, bmp.Height, 0, "byte", 0, 0, 0, 0, -1, 0);
|
|||
|
bmp.UnlockBits(srcBmpData);
|
|||
|
|
|||
|
}
|
|||
|
catch (Exception ex)
|
|||
|
{
|
|||
|
image = null;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|