banboshi_V1/halftoneproject-master/Code/Device/SizeLib.cs
2023-11-01 15:13:54 +08:00

391 lines
18 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using HalconDotNet;
using Microsoft.ML.OnnxRuntime;
using Microsoft.ML.OnnxRuntime.Tensors;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using OpenCvSharp;
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 ProductionControl.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();
//777时用
Yolo_Class yolo5 =new Yolo_Class();
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();
}
}
//流程111222444333777777777。。。
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;
//设置外部函数输入
//if (task.index < 100)
{
ProcCall1_PI_PT.SetInputIconicParamObject("Image1", image.Clone());
ProcCall1_PI_PT.SetInputCtrlParamTuple("index", task.index);//参数1-9
ProcCall1_PI_PT.SetInputCtrlParamTuple("posX", task.posX);
ProcCall1_PI_PT.SetInputCtrlParamTuple("posY", task.posY);
ProcCall1_PI_PT.SetInputCtrlParamTuple("GerberPath",new HTuple( task.drawingPagePath));//美尚没有
//设置外部函数输入
if ((task.PTandLinePos != null) && (task.PTandLinePos[0] != 0))
{
double[] posarray = new double[23];
posarray[0] = task.PTandLinePos[0];
posarray[1] = task.PTandLinePos[2];
posarray[2] = task.PTandLinePos[4];
posarray[3] = task.PTandLinePos[6];
posarray[4] = task.PTandLinePos[8];
for (int i = 0; i < 18; i++)
{
posarray[5 + i] = task.PTandLinePos[10 + i];
}
ProcCall1_PI_PT.SetInputCtrlParamTuple("UserPose", posarray);
/////
///
//string directory = Config.LogPath + "\\" + DateTime.Now.ToString("yyyyMM") + "\\";
//if (!System.IO.Directory.Exists(directory))
// System.IO.Directory.CreateDirectory(directory);
//File.AppendAllText(directory + "sizeData.log", "data:" + string.Join(",", posarray) + "\r\n");
}
else
{
double[] posarray = new double[23];
ProcCall1_PI_PT.SetInputCtrlParamTuple("UserPose", posarray);
}
}
if (task.index == 777)
{
ProcCall1_PI_PT.SetInputIconicParamObject("ContoursAffineTrans1", task.ContoursAffineTrans1_Out);
}
else
{
HObject ContoursAffineTrans1;
HOperatorSet.GenEmptyObj(out ContoursAffineTrans1);
ProcCall1_PI_PT.SetInputIconicParamObject("ContoursAffineTrans1", ContoursAffineTrans1);
}
step = 3;
ProcCall1_PI_PT.Execute();//执行外部函数
step = 4;
//获取外部函数输出
switch (task.index)
{
case 777://比对结果
step = 10;
task.CompResult = (double)ProcCall1_PI_PT.GetOutputCtrlParamTuple("RES") == 1;//结果1为true0为false
step = 11;
if (!task.CompResult)
{
var Defects_X = ProcCall1_PI_PT.GetOutputCtrlParamTuple("Defects_X");
var Defects_Y = ProcCall1_PI_PT.GetOutputCtrlParamTuple("Defects_Y");
var Defects_LeftTop_X = ProcCall1_PI_PT.GetOutputCtrlParamTuple("Defects_LeftTop_X");
var Defects_LeftTop_Y = ProcCall1_PI_PT.GetOutputCtrlParamTuple("Defects_LeftTop_Y");
var Defects_RightBottom_X = ProcCall1_PI_PT.GetOutputCtrlParamTuple("Defects_RightBottom_X");
var Defects_RightBottom_Y = ProcCall1_PI_PT.GetOutputCtrlParamTuple("Defects_RightBottom_Y");
var Contour_Image = ProcCall1_PI_PT.GetOutputIconicParamObject("Contour_Image");
//var Zoom_Image = ProcCall1_PI_PT.GetOutputIconicParamObject("Zoom_Image");
var Defects_Type = ProcCall1_PI_PT.GetOutputCtrlParamTuple("Defects_Type");
var Defects_Index = ProcCall1_PI_PT.GetOutputCtrlParamTuple("Defects_Index");
step = 12;
//对比打标图显示在UI上以后修复台用
//task.Zoom_Image_mat = yolo5.DrawContour_Opencv(Contour_Image, Zoom_Image, Defects_LeftTop_X, Defects_LeftTop_Y, Defects_RightBottom_X, Defects_RightBottom_Y);
//新YOLO.DLL
task.defectInfor2RestorationDesk = new List<List<string>>();
task.Zoom_Image_mat = yolo5.DrawContour_Opencv(Contour_Image, image, Defects_LeftTop_X, Defects_LeftTop_Y,
Defects_RightBottom_X, Defects_RightBottom_Y, Defects_Type, Defects_Index, Defects_X, Defects_Y, out task.defectInfor2RestorationDesk);
//WarningEvent?.Invoke(WarningEnum.Normal, $"SizeLib 777 call DrawContour_Opencv(),Defects_LeftTop_X={Defects_LeftTop_X}," +
// $"Defects_LeftTop_Y={Defects_LeftTop_Y},Defects_RightBottom_X={Defects_RightBottom_X},Defects_RightBottom_Y={Defects_RightBottom_Y}," +
// $"Defects_Type={Defects_Type},Defects_Index={Defects_Index},Defects_X={Defects_X},Defects_Y={Defects_Y}," +
// $"defectInfor2RestorationDesk={JsonConvert.SerializeObject(task.defectInfor2RestorationDesk)}");
step = 13;
task.Zoom_Image_mat = yolo5.ResizesMat_4(task.Zoom_Image_mat);
//大图缺陷坐标转换到图纸坐标
step = 14;
if (!string.IsNullOrWhiteSpace(task.drawingPagePath) && task.defectInfor2RestorationDesk != null && task.defectInfor2RestorationDesk.Count > 0)
task.defectInfor2RestorationDeskPage = yolo5.DefectDrawGerberImage(task.drawingPagePath, task.defectInfor2RestorationDesk);
}
break;
case 111:
task.MarkPointList[0] = (double)ProcCall1_PI_PT.GetOutputCtrlParamTuple("PoseMarkX_1");
task.MarkPointList[1] = (double)ProcCall1_PI_PT.GetOutputCtrlParamTuple("PoseMarkY_1");
break;
case 222:
task.MarkPointList[2] = (double)ProcCall1_PI_PT.GetOutputCtrlParamTuple("PoseMarkX_2");
task.MarkPointList[3] = (double)ProcCall1_PI_PT.GetOutputCtrlParamTuple("PoseMarkY_2");
break;
case 333:
task.MarkPointList[4] = (double)ProcCall1_PI_PT.GetOutputCtrlParamTuple("PoseMarkX_3");
task.MarkPointList[5] = (double)ProcCall1_PI_PT.GetOutputCtrlParamTuple("PoseMarkY_3");//ContoursAffineTrans1
task.ContoursAffineTrans1_Out = ProcCall1_PI_PT.GetOutputIconicParamObject("ContoursAffineTrans1_Out");
break;
case 444:
task.MarkPointList[6] = (double)ProcCall1_PI_PT.GetOutputCtrlParamTuple("PoseMarkX_4");
task.MarkPointList[7] = (double)ProcCall1_PI_PT.GetOutputCtrlParamTuple("PoseMarkY_4");
break;
case 3333: //Tag使用同时继续获取使用default时时校正和其它值
step = 80;
if (!string.IsNullOrWhiteSpace( task.sizeTag))
task.posePT= ProcCall1_PI_PT.GetOutputCtrlParamTuple("posePT").DArr;
goto default;
default:
step = 90;
task.PT1 = (double)ProcCall1_PI_PT.GetOutputCtrlParamTuple("DistancePT1");//index=8 PT1=PT2
task.PT2 = ProcCall1_PI_PT.GetOutputCtrlParamTuple("DistancePT2");
task.Shanxian = (double)ProcCall1_PI_PT.GetOutputCtrlParamTuple("Distance3Median");
//task.RowP = (double)ProcCall1_PI_PT.GetOutputCtrlParamTuple("RowP");
task.Circle_Ymm = (double)ProcCall1_PI_PT.GetOutputCtrlParamTuple("Circle_Ymm");
task.Circle_Xmm = (double)ProcCall1_PI_PT.GetOutputCtrlParamTuple("Circle_Xmm");
task.offsetX = (double)ProcCall1_PI_PT.GetOutputCtrlParamTuple("offsetX");
task.offsetY = (double)ProcCall1_PI_PT.GetOutputCtrlParamTuple("offsetY");
break;
}
step = 100;
ProcCall1_PI_PT.Dispose();
Program1.Dispose();
step = 101;
task.isSucceed = true;
task.resultInfo = "成功";
callback(task);
step = 102;
}
}
catch (Exception ex)
{
WarningEvent?.Invoke(WarningEnum.Low, $"SizeLib task err({step}) index({task.index}):"+ 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 processName;//只为回调记录当前工序信息
public string engineName,sizeTag;
/// <summary>
/// 源文件
/// </summary>
public string file_path;
public double posX,posY;
public Bitmap bmp;
public string drawingPagePath = "";//.gbx图纸路径
//2023-10-27 新增图纸选择pt点位与线宽点位
public double[] PTandLinePos;
/// <summary>
/// 比对(index=777); 计算Mark(111/222/333/444); 尺寸(1-9); 轴偏移调整(10,20,30...)
/// </summary>
public int index; //index=8 PT1=PT2
/// <summary>
/// 完成后回调
/// </summary>
public Action<SizeTask> finishEvent;
public long createTime = DateTime.Now.Ticks;
//==结果返回
/// <summary>
/// 比对结果(index=777)
/// </summary>
public bool CompResult;
public Mat Zoom_Image_mat;//对比打标图:777比对失败时计算得出后面显示到UI 以后修复台用
public List<List<string>> defectInfor2RestorationDesk, defectInfor2RestorationDeskPage;//对比未通过坐标信息,合并到缺陷检测中的 //打标缺陷转为图纸的坐标;
//MARK点
public double[] MarkPointList = { 0, 0, 0, 0, 0, 0, 0, 0 };
public HObject ContoursAffineTrans1_Out;//index=333时输出供后面多个777比对时输入使用
public double[] posePT;//index=3333 && !isEmpty(sizeTag) 才取此数组值len为0时急停
//
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;
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;
}
}
}
}