2233 lines
88 KiB
C#
2233 lines
88 KiB
C#
/************************
|
||
* 作者:CVE-安翀岚
|
||
*
|
||
* Vision:1.0.23.1007 (发布使用)
|
||
* Windows10 X64(PaddleOCR不能部署在32位操作系统上)
|
||
* PaddleOCR 3.10
|
||
* Vpro: 9.5 SR2
|
||
*
|
||
***********************/
|
||
|
||
|
||
using System;
|
||
using System.IO;
|
||
using System.Collections.Generic;
|
||
using System.ComponentModel;
|
||
using System.Data;
|
||
using System.Drawing;
|
||
using System.Linq;
|
||
using System.Text;
|
||
using System.Threading.Tasks;
|
||
using System.Threading;
|
||
using System.Windows.Forms;
|
||
using OfficeOpenXml;
|
||
|
||
using Cognex.VisionPro;
|
||
using Cognex.VisionPro.Comm;
|
||
using Cognex.VisionPro.QuickBuild;
|
||
using Cognex.VisionPro.ToolBlock;
|
||
using Cognex.VisionPro.PMAlign;
|
||
using Cognex.VisionPro.ToolGroup;
|
||
using Cognex.VisionPro.ImageProcessing;
|
||
using PaddleOCRSharp;
|
||
using AVP.CRobot;
|
||
using log4net;
|
||
using LogShowLib;
|
||
using System.Text.RegularExpressions;
|
||
using TetraParkOCR;
|
||
using Bjcve.Comm.FFP;
|
||
using ThridLibray;
|
||
using CLIDelegate;
|
||
|
||
namespace TetraPackOCR
|
||
{
|
||
public partial class Form1 : Form
|
||
{
|
||
public Form1()
|
||
{
|
||
InitializeComponent();
|
||
LogInit();
|
||
}
|
||
|
||
#region 字段 委托
|
||
|
||
|
||
//创建字段log
|
||
ILog log = LogManager.GetLogger(typeof(Form1));
|
||
/// <summary>
|
||
/// 声明一个cc24通讯对象
|
||
/// </summary>
|
||
CC24 cc24;
|
||
/// <summary>
|
||
/// 声明一个PaddleOCR对象
|
||
/// </summary>
|
||
PaddleOCREngine Engine;
|
||
|
||
/// <summary>
|
||
///对应表格"P2生成数据"这一页
|
||
/// </summary>
|
||
ExcelWorksheet sheet1;
|
||
/// <summary>
|
||
/// 对应表格"QSV对应产品规格和梯度"这一页
|
||
/// </summary>
|
||
ExcelWorksheet sheet2;
|
||
/// <summary>
|
||
/// 对应"产品规格对应排布方式"这一页
|
||
/// </summary>
|
||
ExcelWorksheet sheet3;
|
||
/// <summary>
|
||
/// 表格路径
|
||
/// </summary>
|
||
string execlFileName = AppDomain.CurrentDomain.BaseDirectory + "Data\\Excle\\OCR文件0602.xlsx";
|
||
|
||
/// <summary>
|
||
/// 共印依据 QSV Design, Layers, Colours,产品规格
|
||
/// </summary>
|
||
string Sequence, QSV, Design, Layers, Colours, ProductStandard, ord;
|
||
/// <summary>
|
||
/// 幅数 包材宽 梯度 X距离 Y距离
|
||
/// </summary>
|
||
double NumberOfLanes, width, Gradient, DistX, DistY;
|
||
/// <summary>
|
||
/// 定位Vpp文件
|
||
/// </summary>
|
||
string vppdetFile = AppDomain.CurrentDomain.BaseDirectory + "Data\\VPPFile\\liledet.vpp";
|
||
/// <summary>
|
||
/// OCRVpp文件
|
||
/// </summary>
|
||
string vppocrFile = AppDomain.CurrentDomain.BaseDirectory + "Data\\VPPFile\\lileOCR.vpp";
|
||
/// <summary>
|
||
/// 存图路径
|
||
/// </summary>
|
||
string SaveImageFileOCR = AppDomain.CurrentDomain.BaseDirectory + "SaveImage\\OCR";//ocr存图
|
||
string SaveImageFileDET = AppDomain.CurrentDomain.BaseDirectory + "SaveImage\\Det";//ocr存图
|
||
private CogJobManager myJobManager1;//, myJobManager2;
|
||
private CogJob myJob1;//, myJob2;
|
||
|
||
private string[] verocr = new string[20];
|
||
|
||
bool Coprinted_ordeFlag = false; //是否为共印订单旗帜
|
||
//bool PlcContinueFlag = false; //PLC状态旗帜
|
||
int mMatchingStr = 0;//接收当前OCR拍照位置
|
||
|
||
List<float> ocrAcc = new List<float>();
|
||
/// <summary>
|
||
/// 相机对象 1和2
|
||
/// </summary>
|
||
IDevice m_dev_cam0, m_dev_cam1;
|
||
List<IDeviceInfo> DeviceList;
|
||
public string ImagePixelFormat = ""; //图像格式设置
|
||
|
||
delegate void DetResultDelegate(Object Sender, CogJobManagerActionEventArgs e);
|
||
delegate void OcrResultDelegate(Bitmap bmp);
|
||
#endregion
|
||
|
||
#region 窗体加载和关闭
|
||
|
||
//private void MainPage_SizeChanged(object sender, EventArgs e)
|
||
//{
|
||
// asf.controlAutoSize(this);
|
||
//}
|
||
|
||
/// <summary>
|
||
/// 窗体加载
|
||
/// </summary>
|
||
/// <param name="sender"></param>
|
||
/// <param name="e"></param>
|
||
private void Form1_Load(object sender, EventArgs e)
|
||
{
|
||
try
|
||
{
|
||
btn_manualDet.Enabled = false;
|
||
btn_manualOcr.Enabled = false;
|
||
check_Autorun.Enabled = false;
|
||
btn_StarDet_manual.Enabled = false;
|
||
//asf.controllInitializeSize(this);
|
||
log.Info("软件正在加载...");
|
||
Action action = (() =>
|
||
{
|
||
//InitializeCamer1();
|
||
//InitializeCamer2();
|
||
InitializePaddleOCR();
|
||
myJobManager1 = CogSerializer.LoadObjectFromFile(vppdetFile) as CogJobManager;
|
||
//myJobManager2 = CogSerializer.LoadObjectFromFile(vppocrFile) as CogJobManager;
|
||
|
||
|
||
InitializeCC24();
|
||
|
||
log.Info("模型文件加载完成");
|
||
this.check_Autorun.BackgroundImage = Image.FromFile(Application.StartupPath + "\\logo_image\\ON.png");
|
||
this.ttls_SystemStatusShow.Visible = true;
|
||
this.ttls_CamStatusShow.Visible = true;
|
||
this.Invoke(new Action(() =>
|
||
{
|
||
this.btn_manualOcr.Enabled = true;
|
||
this.btn_manualDet.Enabled = true;
|
||
check_Autorun.Enabled = true;
|
||
btn_StarDet_manual.Enabled = true;
|
||
}));
|
||
});
|
||
|
||
|
||
|
||
Task myTask = new Task(action);
|
||
|
||
//实例化一个线程列表
|
||
List<Task> tsk = new List<Task>();
|
||
|
||
//将上面的加载vpp工作加入线程列表中
|
||
tsk.Add(myTask);
|
||
|
||
//读取线程列表内的工作让cpu为其开辟线程空间并执行程序
|
||
foreach (var iteam in tsk)
|
||
{
|
||
iteam.Start();
|
||
|
||
}
|
||
|
||
TaskFactory tskFactory = new TaskFactory();
|
||
tskFactory.ContinueWhenAll(tsk.ToArray(), FlashFormView =>
|
||
{
|
||
|
||
|
||
myJob1 = myJobManager1.Job(0);
|
||
//myJob2 = myJobManager2.Job(0);
|
||
|
||
// 注册结果队列事件
|
||
myJobManager1.UserResultAvailable += new CogJobManager.CogUserResultAvailableEventHandler(DetResult);
|
||
// myJobManager2.UserResultAvailable += new CogJobManager.CogUserResultAvailableEventHandler(OCRResult);
|
||
|
||
});
|
||
|
||
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
log.Error(ex.Message);
|
||
}
|
||
|
||
|
||
}
|
||
|
||
|
||
|
||
/// <summary>
|
||
/// 窗体关闭
|
||
/// </summary>
|
||
/// <param name="sender"></param>
|
||
/// <param name="e"></param>
|
||
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
|
||
{
|
||
|
||
try
|
||
{
|
||
//if (myJob1.AcqFifo.FrameGrabber != null)
|
||
//{
|
||
// myJob1.AcqFifo.FrameGrabber.Disconnect(true);
|
||
//}
|
||
//if (myJob2.AcqFifo.FrameGrabber != null)
|
||
//{
|
||
// myJob2.AcqFifo.FrameGrabber.Disconnect(true);
|
||
//}
|
||
|
||
ClossCam();
|
||
|
||
// 注销结果队列事件
|
||
myJobManager1.UserResultAvailable -= new CogJobManager.CogUserResultAvailableEventHandler(DetResult);
|
||
//myJobManager2.UserResultAvailable -= new CogJobManager.CogUserResultAvailableEventHandler(OCRResult);
|
||
myJobManager1.Shutdown();
|
||
//myJobManager2.Shutdown();
|
||
|
||
|
||
|
||
CloseCC24();
|
||
|
||
Application.DoEvents();
|
||
System.Environment.Exit(0);
|
||
}
|
||
catch
|
||
{
|
||
ClossCam();
|
||
|
||
// 注销结果队列事件
|
||
myJobManager1.UserResultAvailable -= new CogJobManager.CogUserResultAvailableEventHandler(DetResult);
|
||
//myJobManager2.UserResultAvailable -= new CogJobManager.CogUserResultAvailableEventHandler(OCRResult);
|
||
myJobManager1.Shutdown();
|
||
//myJobManager2.Shutdown();
|
||
|
||
|
||
|
||
CloseCC24();
|
||
|
||
Application.DoEvents();
|
||
System.Environment.Exit(0);
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region 日志显示初始化
|
||
|
||
private void LogInit()
|
||
{
|
||
try
|
||
{
|
||
//实例化日志助手
|
||
LogShowLib.LogHelper lib = new LogShowLib.LogHelper();
|
||
//为log4net导入配置文件
|
||
//若传入目录未找到配置文件,将创建一个LogConfig.xml
|
||
|
||
log4net.Config.XmlConfigurator.Configure(lib.GetXMLStream(AppDomain.CurrentDomain.BaseDirectory));
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
MessageBox.Show(string.Format("配置日志出错:{0}", ex.Message));
|
||
}
|
||
}
|
||
|
||
|
||
|
||
#endregion
|
||
|
||
#region 相机初始化
|
||
|
||
#region 相机1 定义为OCR相机
|
||
private void InitializeCamer1()
|
||
{
|
||
DeviceList = Enumerator.EnumerateDevices(); //发现设备,搜索所有大华相机
|
||
|
||
// m_dev_cam0 = Enumerator.GetDeviceByIndex(0);//通过索引获取
|
||
m_dev_cam0 = Enumerator.GetDeviceByKey("Machine Vision:CK21686DAK00001");//通过"设备厂商名:设备序列号"获取
|
||
//m_dev_cam0 = Enumerator.GetDeviceByGigeIP("192.168.20.2");//通过IP地址获取
|
||
|
||
m_dev_cam0.CameraOpened += m_dev0_CameraOpened;
|
||
m_dev_cam0.CameraClosed += m_dev0_CameraClosed;
|
||
m_dev_cam0.ConnectionLost += m_dev0_ConnectionLost;
|
||
|
||
if(!m_dev_cam0.Open())
|
||
{
|
||
MessageBox.Show("OCR相机打开失败");
|
||
}
|
||
// 设置图像格式
|
||
// set PixelFormat
|
||
using (IEnumParameter p = m_dev_cam0.ParameterCollection[ParametrizeNameSet.ImagePixelFormat])
|
||
{
|
||
ImagePixelFormat = "BayerRG8";
|
||
//ImagePixelFormat = "Mono8";
|
||
p.SetValue(ImagePixelFormat);
|
||
}
|
||
|
||
// 设置曝光
|
||
|
||
using (IFloatParameter p = m_dev_cam0.ParameterCollection[ParametrizeNameSet.ExposureTime])
|
||
{
|
||
p.SetValue(80000);
|
||
}
|
||
// 设置增益
|
||
|
||
using (IFloatParameter p = m_dev_cam0.ParameterCollection[ParametrizeNameSet.GainRaw])
|
||
{
|
||
p.SetValue(2.5);
|
||
}
|
||
using (IEnumParameter p = m_dev_cam0.ParameterCollection[ParametrizeNameSet.AcquisitionMode])
|
||
{
|
||
p.SetValue("Continuous");
|
||
}
|
||
using (IEnumParameter p = m_dev_cam0.ParameterCollection[ParametrizeNameSet.TriggerMode])
|
||
{
|
||
p.SetValue("On");
|
||
}
|
||
|
||
//if (!m_dev_cam0.Open())
|
||
//{
|
||
// MessageBox.Show(@"OCR相机连接失败");
|
||
// return;
|
||
//}
|
||
m_dev_cam0.StreamGrabber.ImageGrabbed += StreamGrabber_ImageGrabbed_0;
|
||
m_dev_cam0.StreamGrabber.GrabStarted += StreamGrabber_GrabStarted_0;
|
||
// 打开Software Trigger
|
||
// Set Software Trigger
|
||
m_dev_cam0.TriggerSet.Open(TriggerSourceEnum.Software);
|
||
if (!m_dev_cam0.GrabUsingGrabLoopThread())
|
||
{
|
||
|
||
// 开启采集失败
|
||
log.Error("开启采集失败");
|
||
}
|
||
log.Info("OCR相机加载完毕");
|
||
}
|
||
#endregion
|
||
|
||
#region 相机1事件响应
|
||
|
||
void m_dev0_ConnectionLost(object sender, EventArgs e)
|
||
{
|
||
MessageBox.Show(m_dev_cam0.DeviceInfo.Key + "OCR相机断线");
|
||
}
|
||
|
||
void m_dev0_CameraClosed(object sender, EventArgs e)
|
||
{
|
||
MessageBox.Show(m_dev_cam0.DeviceInfo.Key + "OCR相机关闭");
|
||
}
|
||
|
||
void m_dev0_CameraOpened(object sender, EventArgs e)
|
||
{
|
||
// MessageBox.Show(m_dev_cam0.DeviceInfo.Key + "启动");
|
||
}
|
||
|
||
void StreamGrabber_GrabStarted_0(object sender, EventArgs e)
|
||
{
|
||
log.Info("OCR相机启动码流");
|
||
}
|
||
|
||
/// <summary>
|
||
/// 拍照完成后触发
|
||
/// </summary>
|
||
/// <param name="sender"></param>
|
||
/// <param name="e"></param>
|
||
private void StreamGrabber_ImageGrabbed_0(object sender, GrabbedEventArgs e)
|
||
{
|
||
try
|
||
{
|
||
Bitmap bmp = null;
|
||
|
||
bmp = e.GrabResult.ToBitmap(true);
|
||
|
||
OCRResult(bmp);
|
||
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
MessageBox.Show(ex.ToString());
|
||
}
|
||
}
|
||
#endregion
|
||
|
||
#region 相机2 定义为定位相机
|
||
private void InitializeCamer2()
|
||
{
|
||
DeviceList = Enumerator.EnumerateDevices(); //发现设备,搜索所有大华相机
|
||
|
||
//m_dev_cam1 = Enumerator.GetDeviceByIndex(1);//通过索引获取
|
||
m_dev_cam1 = Enumerator.GetDeviceByKey("Machine Vision:BK27185BAK00038");//通过"设备厂商名:设备序列号"获取
|
||
//m_dev_cam1 = Enumerator.GetDeviceByGigeIP("192.168.10.1");//通过IP地址获取
|
||
|
||
m_dev_cam1.CameraOpened += m_dev1_CameraOpened;
|
||
m_dev_cam1.CameraClosed += m_dev1_CameraClosed;
|
||
m_dev_cam1.ConnectionLost += m_dev1_ConnectionLost;
|
||
|
||
if (!m_dev_cam1.Open())
|
||
{
|
||
MessageBox.Show("定位相机打开失败");
|
||
}
|
||
// 设置图像格式
|
||
// set PixelFormat
|
||
using (IEnumParameter p = m_dev_cam1.ParameterCollection[ParametrizeNameSet.ImagePixelFormat])
|
||
{
|
||
ImagePixelFormat = "Mono";
|
||
p.SetValue(ImagePixelFormat);
|
||
}
|
||
|
||
// 设置曝光
|
||
|
||
using (IFloatParameter p = m_dev_cam1.ParameterCollection[ParametrizeNameSet.ExposureTime])
|
||
{
|
||
p.SetValue(80000);
|
||
}
|
||
// 设置增益
|
||
|
||
using (IFloatParameter p = m_dev_cam1.ParameterCollection[ParametrizeNameSet.GainRaw])
|
||
{
|
||
p.SetValue(1.0);
|
||
}
|
||
using (IEnumParameter p = m_dev_cam1.ParameterCollection[ParametrizeNameSet.AcquisitionMode])
|
||
{
|
||
p.SetValue("Continuous");
|
||
}
|
||
using (IEnumParameter p = m_dev_cam1.ParameterCollection[ParametrizeNameSet.TriggerMode])
|
||
{
|
||
p.SetValue("On");
|
||
}
|
||
//if (!m_dev_cam1.Open())
|
||
//{
|
||
// MessageBox.Show(@"定位相机连接失败");
|
||
// return;
|
||
//}
|
||
m_dev_cam1.StreamGrabber.ImageGrabbed += StreamGrabber_ImageGrabbed_1;
|
||
m_dev_cam1.StreamGrabber.GrabStarted += StreamGrabber_GrabStarted_1;
|
||
// 打开Software Trigger
|
||
// Set Software Trigger
|
||
m_dev_cam1.TriggerSet.Open(TriggerSourceEnum.Software);
|
||
if (!m_dev_cam1.GrabUsingGrabLoopThread())
|
||
{
|
||
|
||
// 开启采集失败
|
||
log.Error("开启采集失败");
|
||
}
|
||
log.Info("定位相机加载完毕");
|
||
}
|
||
#endregion
|
||
|
||
#region 相机2事件响应
|
||
|
||
void m_dev1_ConnectionLost(object sender, EventArgs e)
|
||
{
|
||
MessageBox.Show(m_dev_cam1.DeviceInfo.Key + "定位相机断线");
|
||
}
|
||
|
||
void m_dev1_CameraClosed(object sender, EventArgs e)
|
||
{
|
||
MessageBox.Show(m_dev_cam1.DeviceInfo.Key + "定位相机关闭");
|
||
}
|
||
|
||
void m_dev1_CameraOpened(object sender, EventArgs e)
|
||
{
|
||
// MessageBox.Show(m_dev_cam0.DeviceInfo.Key + "启动");
|
||
}
|
||
|
||
void StreamGrabber_GrabStarted_1(object sender, EventArgs e)
|
||
{
|
||
log.Info("定位相机启动码流");
|
||
}
|
||
|
||
/// <summary>
|
||
/// 拍照完成后触发
|
||
/// </summary>
|
||
/// <param name="sender"></param>
|
||
/// <param name="e"></param>
|
||
private void StreamGrabber_ImageGrabbed_1(object sender, GrabbedEventArgs e)
|
||
{
|
||
try
|
||
{
|
||
Bitmap bmp = null;
|
||
|
||
bmp = e.GrabResult.ToBitmap(true);
|
||
|
||
|
||
|
||
//Bitmap bmp = new Bitmap(cogimg.ToBitmap());
|
||
MemoryStream ms = new MemoryStream();
|
||
bmp.Save(ms, System.Drawing.Imaging.ImageFormat.Bmp);
|
||
byte[] bytes = ms.GetBuffer();
|
||
ms.Close();
|
||
//保存DET图像
|
||
if (!Directory.Exists(SaveImageFileDET))
|
||
{
|
||
Directory.CreateDirectory(SaveImageFileDET);
|
||
}
|
||
string strTime = System.DateTime.Now.ToString("yyyyMMddHHmmss");
|
||
|
||
FileStream fs = new FileStream(SaveImageFileDET + '\\' + strTime + ".bmp", FileMode.Create);
|
||
BinaryWriter bw = new BinaryWriter(fs);
|
||
bw.Write(bytes, 0, bytes.Length);
|
||
bw.Close();
|
||
fs.Close();
|
||
log.Info("定位存图已完成");
|
||
|
||
|
||
CogImage8Grey cogimage = new CogImage8Grey(bmp);
|
||
|
||
//把图像给job中convertImagetool
|
||
CogToolGroup myTG = myJob1.VisionTool as CogToolGroup;
|
||
CogToolBlock myTB = myTG.Tools["CogToolBlock1"] as CogToolBlock;
|
||
CogImageConvertTool cogImageConvert = myTB.Tools["CogImageConvertTool1"] as CogImageConvertTool;
|
||
|
||
cogImageConvert.InputImage = cogimage;
|
||
//运行jobmanager
|
||
myJobManager1.Run();
|
||
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
MessageBox.Show(ex.ToString());
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region 相机关闭
|
||
void ClossCam()
|
||
{
|
||
//注销相机事件
|
||
m_dev_cam0.CameraOpened -= m_dev0_CameraOpened;
|
||
m_dev_cam0.CameraClosed -= m_dev0_CameraClosed;
|
||
m_dev_cam0.ConnectionLost -= m_dev0_ConnectionLost;
|
||
|
||
m_dev_cam1.CameraOpened -= m_dev1_CameraOpened;
|
||
m_dev_cam1.CameraClosed -= m_dev1_CameraClosed;
|
||
m_dev_cam1.ConnectionLost -= m_dev1_ConnectionLost;
|
||
|
||
m_dev_cam0.ShutdownGrab();
|
||
m_dev_cam0.Dispose();
|
||
m_dev_cam0 = null;
|
||
m_dev_cam1.ShutdownGrab();
|
||
m_dev_cam1.Dispose();
|
||
m_dev_cam1 = null;
|
||
}
|
||
#endregion
|
||
#endregion
|
||
|
||
#region OCR模型参数初始化
|
||
private void InitializePaddleOCR()
|
||
{
|
||
//模型初始化
|
||
OCRModelConfig config = new OCRModelConfig(); //创建一个模型参数设置对象
|
||
string rootPath = System.IO.Path.GetDirectoryName(typeof(OCRModelConfig).Assembly.Location); //程序的根目录
|
||
config.det_infer = rootPath + @"\Data\OCRModel\det_infer"; //文字检测模型路径
|
||
config.cls_infer = rootPath + @"\Data\OCRModel\cls_infer"; //文本角度模型路径
|
||
config.rec_infer = rootPath + @"\Data\OCRModel\rec_infer"; //文字内容识别模型路径
|
||
//以上三个模型参数的文件路径只需要写到存放的文件夹名称
|
||
//对于字典来说需要写全加上后缀
|
||
config.keys = rootPath + @"\Data\OCRModel\keys\ppocr_keys.txt"; //词典路径
|
||
|
||
//OCR参数设置
|
||
OCRParameter OcrParameter = new OCRParameter(); //创建一个检测参数设置对象
|
||
|
||
OcrParameter.cpu_math_library_num_threads = 8;//预测并发线程数
|
||
OcrParameter.enable_mkldnn = true;//web部署该值建议设置为0,否则出错,内存如果使用很大,建议该值也设置为0.
|
||
OcrParameter.cls = true; //是否执行文字方向分类;默认false
|
||
OcrParameter.det = true;//是否开启方向检测,用于检测识别180旋转
|
||
OcrParameter.rec = true;
|
||
OcrParameter.use_angle_cls = true;//是否开启方向检测,用于检测识别180旋转
|
||
OcrParameter.det_db_score_mode = true;//是否使用多段线,即文字区域是用多段线还是用矩形,
|
||
OcrParameter.det_db_unclip_ratio = 1.5f;
|
||
OcrParameter.max_side_len = 1280;
|
||
|
||
//初始化OCR
|
||
Engine = new PaddleOCREngine(config, OcrParameter);
|
||
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region 按钮事件
|
||
|
||
/// <summary>
|
||
/// 自动运行状态改变按钮
|
||
/// </summary>
|
||
/// <param name="sender"></param>
|
||
/// <param name="e"></param>
|
||
private void check_Autorun_CheckedChanged(object sender, EventArgs e)
|
||
{
|
||
if (check_Autorun.Checked)
|
||
{
|
||
//CloseCC24();
|
||
log.Info("PC断开PLC连接,只可进行本地操作。");
|
||
this.check_Autorun.BackgroundImage = Image.FromFile(Application.StartupPath + "\\logo_image\\OFF.png");
|
||
this.panel_Manual.Visible = true;
|
||
this.btn_StarDet_manual.Enabled = false;
|
||
this.ttls_PCLStatusShow.Visible = false;
|
||
}
|
||
else if (!check_Autorun.Checked)
|
||
{
|
||
//InitializeCC24();
|
||
log.Info("PC加载PLC已完成");
|
||
this.check_Autorun.BackgroundImage = Image.FromFile(Application.StartupPath + "\\logo_image\\ON.png");
|
||
this.panel_Manual.Visible = false;
|
||
this.btn_StarDet_manual.Enabled = true;
|
||
this.ttls_PCLStatusShow.Visible = true;
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 此按钮事件主要是获取excel表格内的数据
|
||
/// 包括定位偏移量,需要验证的字符
|
||
/// </summary>
|
||
/// <param name="sender"></param>
|
||
/// <param name="e"></param>
|
||
private void btn_OrderNum_Click(object sender, EventArgs e)
|
||
{
|
||
try
|
||
{
|
||
ClearData();
|
||
ClearDataShow();
|
||
this.Invoke(new Action(() =>
|
||
{
|
||
this.lbl_L1_verOcrRs.Text = "未启用";
|
||
this.lbl_L1_verOcrRs.BackColor = Color.Gray;
|
||
this.lbl_L2_verOcrRs.Text = "未启用";
|
||
this.lbl_L2_verOcrRs.BackColor = Color.Gray;
|
||
this.lbl_L3_verOcrRs.Text = "未启用";
|
||
this.lbl_L3_verOcrRs.BackColor = Color.Gray;
|
||
this.lbl_L4_verOcrRs.Text = "未启用";
|
||
this.lbl_L4_verOcrRs.BackColor = Color.Gray;
|
||
this.lbl_L5_verOcrRs.Text = "未启用";
|
||
this.lbl_L5_verOcrRs.BackColor = Color.Gray;
|
||
this.lbl_L6_verOcrRs.Text = "未启用";
|
||
this.lbl_L6_verOcrRs.BackColor = Color.Gray;
|
||
this.lbl_L7_verOcrRs.Text = "未启用";
|
||
this.lbl_L7_verOcrRs.BackColor = Color.Gray;
|
||
this.lbl_L8_verOcrRs.Text = "未启用";
|
||
this.lbl_L8_verOcrRs.BackColor = Color.Gray;
|
||
this.lbl_L9_verOcrRs.Text = "未启用";
|
||
this.lbl_L9_verOcrRs.BackColor = Color.Gray;
|
||
}));
|
||
this.btn_OrderNum.Enabled = false;
|
||
//通过订单号获取表格中需要的值
|
||
string order = txt_OrderNum.Text;
|
||
string laststr = order.Substring(order.Length - 1);
|
||
if (laststr == "C")
|
||
{
|
||
Coprinted_ordeFlag = true;
|
||
if (order == null)
|
||
{
|
||
log.Warn("订单号为空,请输入订单号。");
|
||
//MessageBox.Show("请输入订单号");
|
||
}
|
||
else
|
||
{
|
||
log.Info("当前订单号为:" + order);
|
||
//读取表格内容
|
||
ExcelPackage.License.SetNonCommercialOrganization("My Noncommercial organization");
|
||
using (ExcelPackage package = new ExcelPackage(execlFileName))
|
||
{
|
||
sheet1 = package.Workbook.Worksheets["P2生成数据"];
|
||
sheet2 = package.Workbook.Worksheets["QSV对应产品规格和梯度"];
|
||
sheet3 = package.Workbook.Worksheets["产品规格对应排布方式"];
|
||
//根据订单遍历sheet1 找Sequence QSV NumOFLanes 字符
|
||
for (int i = 1; i < sheet1.Dimension.Rows; i++)
|
||
{
|
||
if (sheet1.GetValue(i, 3) != null)
|
||
{
|
||
ord = sheet1.Cells[i, 3].Value.ToString();
|
||
}
|
||
else
|
||
{
|
||
ord = null;
|
||
}
|
||
if (ord == order)
|
||
{
|
||
Sequence = sheet1.Cells[i, 2].Value.ToString();
|
||
QSV = sheet1.Cells[i, 4].Value.ToString();
|
||
this.lbl_QSVShow.Text = QSV;
|
||
log.Info("当前订单QSV:" + QSV);
|
||
NumberOfLanes = Convert.ToInt32(sheet1.Cells[i, 5].Value.ToString());
|
||
log.Info("当前订单Number Of Lanes:" + NumberOfLanes);
|
||
this.lbl_NOFShow.Text = sheet1.Cells[i, 5].Value.ToString();
|
||
|
||
////获取字符 并显示在界面还需处理先预留在这 共印订单不在这取字符
|
||
//Design = sheet1.Cells[i, 7].Value.ToString();
|
||
//Layers = sheet1.Cells[i, 8].Value.ToString();
|
||
//Colours = sheet1.Cells[i, 9].Value.ToString();
|
||
|
||
//lbl_verOcrShow.Text = ExecelGetOcrDealWithForShow(Design, Layers, Colours);
|
||
break;
|
||
}
|
||
|
||
|
||
|
||
}
|
||
|
||
if (Sequence != null)
|
||
{
|
||
for (int i = 1; i < sheet1.Dimension.Rows; i++)
|
||
{
|
||
string seq;
|
||
if (sheet1.GetValue(i, 2) != null)
|
||
{
|
||
seq = sheet1.Cells[i, 2].Value.ToString();
|
||
}
|
||
else
|
||
{
|
||
seq = null;
|
||
}
|
||
if (seq == Sequence)
|
||
{
|
||
Design = sheet1.Cells[i, 7].Value.ToString();
|
||
Layers = sheet1.Cells[i, 8].Value.ToString();
|
||
Colours = sheet1.Cells[i, 9].Value.ToString();
|
||
string Lane = sheet1.Cells[i, 6].Value.ToString();
|
||
Lane = Lane.Replace("[", ""); Lane = Lane.Replace("]", "");
|
||
string[] lans = Lane.Split(',');
|
||
for (int j = 0; j < lans.Length; j++)
|
||
{
|
||
verocr[Convert.ToInt32(lans[j])] = ExecelGetOcrDealWithForShow(Design, Layers);
|
||
}
|
||
|
||
}
|
||
}
|
||
}
|
||
|
||
if (QSV != null)
|
||
{
|
||
string qsv;
|
||
//根据得到的QSV遍历sheet2 找产品规格和宽度梯度
|
||
for (int j = 1; j <= sheet2.Dimension.Rows; j++)
|
||
{
|
||
qsv = sheet2.Cells[j, 1].Value.ToString();
|
||
if (qsv == QSV)
|
||
{
|
||
ProductStandard = sheet2.Cells[j, 2].Value.ToString();
|
||
this.lbl_ProductStandardShow.Text = ProductStandard;
|
||
log.Info("当前订单产品编号:" + ProductStandard);
|
||
width = Convert.ToDouble(sheet2.Cells[j, 3].Value.ToString());
|
||
this.lbl_widthShow.Text = sheet2.Cells[j, 3].Value.ToString();
|
||
log.Info("当前订单幅宽:" + width);
|
||
Gradient = Convert.ToDouble(sheet2.Cells[j, 4].Value.ToString());
|
||
this.lbl_GradientShow.Text = sheet2.Cells[j, 4].Value.ToString();
|
||
log.Info("当前订单梯度:" + Gradient);
|
||
}
|
||
}
|
||
string str, ps;
|
||
|
||
//根据产品规格获取距离坐标
|
||
for (int n = 1; n < sheet3.Dimension.Rows; n++)
|
||
{
|
||
|
||
if (sheet3.GetValue(n, 1) != null)
|
||
{
|
||
ps = sheet3.Cells[n, 1].Value.ToString();
|
||
}
|
||
else
|
||
{
|
||
ps = null;
|
||
}
|
||
if (ps == null)
|
||
{
|
||
continue;
|
||
}
|
||
else if (ps == ProductStandard)//应该有另一个条件一同决定
|
||
{
|
||
str = sheet3.Cells[n, 4].Value.ToString();
|
||
string[] x_y = str.Split(',');
|
||
string[] X = x_y[0].Split(':');
|
||
string[] Y = x_y[1].Split(':');
|
||
DistX = Convert.ToDouble(X[1].Replace("mm", ""));
|
||
this.lbl_DistXShow.Text = X[1].Replace("mm", "");
|
||
log.Info("当前订单X偏移:" + DistX);
|
||
DistY = Convert.ToDouble(Y[1].Replace("mm", ""));
|
||
this.lbl_DistYShow.Text = Y[1].Replace("mm", "");
|
||
log.Info("当前订单Y偏移:" + DistY);
|
||
}
|
||
}
|
||
log.Info("相关数据已获取完成,且已显示在界面中,请查看。");
|
||
}
|
||
else
|
||
{
|
||
log.Debug("请检查订单号是否正确");
|
||
}
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
Coprinted_ordeFlag = false;
|
||
if (order == null)
|
||
{
|
||
log.Warn("订单号为空,请输入订单号。");
|
||
//MessageBox.Show("请输入订单号");
|
||
}
|
||
else
|
||
{
|
||
log.Info("当前订单号为:" + order);
|
||
//读取表格内容
|
||
ExcelPackage.License.SetNonCommercialOrganization("My Noncommercial organization");
|
||
using (ExcelPackage package = new ExcelPackage(execlFileName))
|
||
{
|
||
sheet1 = package.Workbook.Worksheets["P2生成数据"];
|
||
sheet2 = package.Workbook.Worksheets["QSV对应产品规格和梯度"];
|
||
sheet3 = package.Workbook.Worksheets["产品规格对应排布方式"];
|
||
//根据订单遍历sheet1 找QSV NumOFLanes 字符
|
||
for (int i = 1; i < sheet1.Dimension.Rows; i++)
|
||
{
|
||
if (sheet1.GetValue(i, 3) != null)
|
||
{
|
||
ord = sheet1.Cells[i, 3].Value.ToString();
|
||
}
|
||
else
|
||
{
|
||
ord = null;
|
||
}
|
||
if (ord == order)
|
||
{
|
||
QSV = sheet1.Cells[i, 4].Value.ToString();
|
||
this.lbl_QSVShow.Text = QSV;
|
||
log.Info("当前订单QSV:" + QSV);
|
||
NumberOfLanes = Convert.ToInt32(sheet1.Cells[i, 5].Value.ToString());
|
||
log.Info("当前订单Number Of Lanes:" + NumberOfLanes);
|
||
this.lbl_NOFShow.Text = sheet1.Cells[i, 5].Value.ToString();
|
||
|
||
//获取字符 并显示在界面还需处理先预留在这
|
||
Design = sheet1.Cells[i, 7].Value.ToString();
|
||
Layers = sheet1.Cells[i, 8].Value.ToString();
|
||
Colours = sheet1.Cells[i, 9].Value.ToString();
|
||
|
||
lbl_verOcrShow.Text = ExecelGetOcrDealWithForShow(Design, Layers);
|
||
}
|
||
|
||
}
|
||
if (QSV != null)
|
||
{
|
||
string qsv;
|
||
//根据得到的QSV遍历sheet2 找产品规格和宽度梯度
|
||
for (int j = 1; j <= sheet2.Dimension.Rows; j++)
|
||
{
|
||
qsv = sheet2.Cells[j, 1].Value.ToString();
|
||
if (qsv == QSV)
|
||
{
|
||
ProductStandard = sheet2.Cells[j, 2].Value.ToString();
|
||
this.lbl_ProductStandardShow.Text = ProductStandard;
|
||
log.Info("当前订单产品编号:" + ProductStandard);
|
||
width = Convert.ToDouble(sheet2.Cells[j, 3].Value.ToString());
|
||
this.lbl_widthShow.Text = sheet2.Cells[j, 3].Value.ToString();
|
||
log.Info("当前订单幅宽:" + width);
|
||
Gradient = Convert.ToDouble(sheet2.Cells[j, 4].Value.ToString());
|
||
this.lbl_GradientShow.Text = sheet2.Cells[j, 4].Value.ToString();
|
||
log.Info("当前订单梯度:" + Gradient);
|
||
}
|
||
}
|
||
string str, ps;
|
||
|
||
//根据产品规格获取距离坐标
|
||
for (int n = 1; n < sheet3.Dimension.Rows; n++)
|
||
{
|
||
|
||
if (sheet3.GetValue(n, 1) != null)
|
||
{
|
||
ps = sheet3.Cells[n, 1].Value.ToString();
|
||
}
|
||
else
|
||
{
|
||
ps = null;
|
||
}
|
||
if (ps == null)
|
||
{
|
||
continue;
|
||
}
|
||
else if (ps == ProductStandard)//应该有另一个条件一同决定
|
||
{
|
||
str = sheet3.Cells[n, 4].Value.ToString();
|
||
string[] x_y = str.Split(',');
|
||
string[] X = x_y[0].Split(':');
|
||
string[] Y = x_y[1].Split(':');
|
||
DistX = Convert.ToDouble(X[1].Replace("mm", ""));
|
||
this.lbl_DistXShow.Text = X[1].Replace("mm", "");
|
||
log.Info("当前订单X偏移:" + DistX);
|
||
DistY = Convert.ToDouble(Y[1].Replace("mm", ""));
|
||
this.lbl_DistYShow.Text = Y[1].Replace("mm", "");
|
||
log.Info("当前订单Y偏移:" + DistY);
|
||
}
|
||
}
|
||
log.Info("相关数据已获取完成,且已显示在界面中,请查看。");
|
||
}
|
||
else
|
||
{
|
||
log.Debug("请检查订单号是否正确");
|
||
}
|
||
}
|
||
}
|
||
}
|
||
///判断当前Lans决定结果显示数量
|
||
switch (NumberOfLanes)
|
||
{
|
||
case 1:
|
||
this.Invoke(new Action(() =>
|
||
{
|
||
this.lbl_L1_verOcrRs.Text = "启用";
|
||
this.lbl_L1_verOcrRs.BackColor = Color.Yellow;
|
||
}));
|
||
break;
|
||
case 2:
|
||
this.Invoke(new Action(() =>
|
||
{
|
||
this.lbl_L1_verOcrRs.Text = "启用";
|
||
this.lbl_L1_verOcrRs.BackColor = Color.Yellow;
|
||
this.lbl_L2_verOcrRs.Text = "启用";
|
||
this.lbl_L2_verOcrRs.BackColor = Color.Yellow;
|
||
}));
|
||
break;
|
||
case 3:
|
||
this.Invoke(new Action(() =>
|
||
{
|
||
this.lbl_L1_verOcrRs.Text = "启用";
|
||
this.lbl_L1_verOcrRs.BackColor = Color.Yellow;
|
||
this.lbl_L2_verOcrRs.Text = "启用";
|
||
this.lbl_L2_verOcrRs.BackColor = Color.Yellow;
|
||
this.lbl_L3_verOcrRs.Text = "启用";
|
||
this.lbl_L3_verOcrRs.BackColor = Color.Yellow;
|
||
}));
|
||
break;
|
||
case 4:
|
||
this.Invoke(new Action(() =>
|
||
{
|
||
this.lbl_L1_verOcrRs.Text = "启用";
|
||
this.lbl_L1_verOcrRs.BackColor = Color.Yellow;
|
||
this.lbl_L2_verOcrRs.Text = "启用";
|
||
this.lbl_L2_verOcrRs.BackColor = Color.Yellow;
|
||
this.lbl_L3_verOcrRs.Text = "启用";
|
||
this.lbl_L3_verOcrRs.BackColor = Color.Yellow;
|
||
this.lbl_L4_verOcrRs.Text = "启用";
|
||
this.lbl_L4_verOcrRs.BackColor = Color.Yellow;
|
||
}));
|
||
break;
|
||
case 5:
|
||
this.Invoke(new Action(() =>
|
||
{
|
||
this.lbl_L1_verOcrRs.Text = "启用";
|
||
this.lbl_L1_verOcrRs.BackColor = Color.Yellow;
|
||
this.lbl_L2_verOcrRs.Text = "启用";
|
||
this.lbl_L2_verOcrRs.BackColor = Color.Yellow;
|
||
this.lbl_L3_verOcrRs.Text = "启用";
|
||
this.lbl_L3_verOcrRs.BackColor = Color.Yellow;
|
||
this.lbl_L4_verOcrRs.Text = "启用";
|
||
this.lbl_L4_verOcrRs.BackColor = Color.Yellow;
|
||
this.lbl_L5_verOcrRs.Text = "启用";
|
||
this.lbl_L5_verOcrRs.BackColor = Color.Yellow;
|
||
}));
|
||
break;
|
||
case 6:
|
||
this.Invoke(new Action(() =>
|
||
{
|
||
this.lbl_L1_verOcrRs.Text = "启用";
|
||
this.lbl_L1_verOcrRs.BackColor = Color.Yellow;
|
||
this.lbl_L2_verOcrRs.Text = "启用";
|
||
this.lbl_L2_verOcrRs.BackColor = Color.Yellow;
|
||
this.lbl_L3_verOcrRs.Text = "启用";
|
||
this.lbl_L3_verOcrRs.BackColor = Color.Yellow;
|
||
this.lbl_L4_verOcrRs.Text = "启用";
|
||
this.lbl_L4_verOcrRs.BackColor = Color.Yellow;
|
||
this.lbl_L5_verOcrRs.Text = "启用";
|
||
this.lbl_L5_verOcrRs.BackColor = Color.Yellow;
|
||
this.lbl_L6_verOcrRs.Text = "启用";
|
||
this.lbl_L6_verOcrRs.BackColor = Color.Yellow;
|
||
|
||
}));
|
||
break;
|
||
case 7:
|
||
this.Invoke(new Action(() =>
|
||
{
|
||
this.lbl_L1_verOcrRs.Text = "启用";
|
||
this.lbl_L1_verOcrRs.BackColor = Color.Yellow;
|
||
this.lbl_L2_verOcrRs.Text = "启用";
|
||
this.lbl_L2_verOcrRs.BackColor = Color.Yellow;
|
||
this.lbl_L3_verOcrRs.Text = "启用";
|
||
this.lbl_L3_verOcrRs.BackColor = Color.Yellow;
|
||
this.lbl_L4_verOcrRs.Text = "启用";
|
||
this.lbl_L4_verOcrRs.BackColor = Color.Yellow;
|
||
this.lbl_L5_verOcrRs.Text = "启用";
|
||
this.lbl_L5_verOcrRs.BackColor = Color.Yellow;
|
||
this.lbl_L6_verOcrRs.Text = "启用";
|
||
this.lbl_L6_verOcrRs.BackColor = Color.Yellow;
|
||
this.lbl_L7_verOcrRs.Text = "启用";
|
||
this.lbl_L7_verOcrRs.BackColor = Color.Yellow;
|
||
}));
|
||
break;
|
||
case 8:
|
||
this.Invoke(new Action(() =>
|
||
{
|
||
this.lbl_L1_verOcrRs.Text = "启用";
|
||
this.lbl_L1_verOcrRs.BackColor = Color.Yellow;
|
||
this.lbl_L2_verOcrRs.Text = "启用";
|
||
this.lbl_L2_verOcrRs.BackColor = Color.Yellow;
|
||
this.lbl_L3_verOcrRs.Text = "启用";
|
||
this.lbl_L3_verOcrRs.BackColor = Color.Yellow;
|
||
this.lbl_L4_verOcrRs.Text = "启用";
|
||
this.lbl_L4_verOcrRs.BackColor = Color.Yellow;
|
||
this.lbl_L5_verOcrRs.Text = "启用";
|
||
this.lbl_L5_verOcrRs.BackColor = Color.Yellow;
|
||
this.lbl_L6_verOcrRs.Text = "启用";
|
||
this.lbl_L6_verOcrRs.BackColor = Color.Yellow;
|
||
this.lbl_L7_verOcrRs.Text = "启用";
|
||
this.lbl_L7_verOcrRs.BackColor = Color.Yellow;
|
||
this.lbl_L8_verOcrRs.Text = "启用";
|
||
this.lbl_L8_verOcrRs.BackColor = Color.Yellow;
|
||
}));
|
||
break;
|
||
case 9:
|
||
this.Invoke(new Action(() =>
|
||
{
|
||
this.lbl_L1_verOcrRs.Text = "启用";
|
||
this.lbl_L1_verOcrRs.BackColor = Color.Yellow;
|
||
this.lbl_L2_verOcrRs.Text = "启用";
|
||
this.lbl_L2_verOcrRs.BackColor = Color.Yellow;
|
||
this.lbl_L3_verOcrRs.Text = "启用";
|
||
this.lbl_L3_verOcrRs.BackColor = Color.Yellow;
|
||
this.lbl_L4_verOcrRs.Text = "启用";
|
||
this.lbl_L4_verOcrRs.BackColor = Color.Yellow;
|
||
this.lbl_L5_verOcrRs.Text = "启用";
|
||
this.lbl_L5_verOcrRs.BackColor = Color.Yellow;
|
||
this.lbl_L6_verOcrRs.Text = "启用";
|
||
this.lbl_L6_verOcrRs.BackColor = Color.Yellow;
|
||
this.lbl_L7_verOcrRs.Text = "启用";
|
||
this.lbl_L7_verOcrRs.BackColor = Color.Yellow;
|
||
this.lbl_L8_verOcrRs.Text = "启用";
|
||
this.lbl_L8_verOcrRs.BackColor = Color.Yellow;
|
||
this.lbl_L9_verOcrRs.Text = "启用";
|
||
this.lbl_L9_verOcrRs.BackColor = Color.Yellow;
|
||
}));
|
||
break;
|
||
}
|
||
|
||
this.btn_OrderNum.Enabled = true;
|
||
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
log.Error(ex.Message + "请检查订单号是否正确,数据表中并无此订单号");
|
||
this.btn_OrderNum.Enabled = true;
|
||
}
|
||
}
|
||
/// <summary>
|
||
/// 手动ocr
|
||
/// </summary>
|
||
/// <param name="sender"></param>
|
||
/// <param name="e"></param>
|
||
private void btn_manualOcr_Click(object sender, EventArgs e)
|
||
{
|
||
m_dev_cam0.ExecuteSoftwareTrigger();//相机1触发 = OCR拍照
|
||
log.Info("手动触发OCR");
|
||
}
|
||
/// <summary>
|
||
/// 手动定位
|
||
/// </summary>
|
||
/// <param name="sender"></param>
|
||
/// <param name="e"></param>
|
||
private void btn_manualDet_Click(object sender, EventArgs e)
|
||
{
|
||
m_dev_cam1.ExecuteSoftwareTrigger();
|
||
log.Info("手动触发定位");
|
||
}
|
||
private void btn_StarDet_manual_Click(object sender, EventArgs e)
|
||
{
|
||
m_dev_cam1.ExecuteSoftwareTrigger();
|
||
log.Info("手动触发开始");
|
||
}
|
||
|
||
/// <summary>
|
||
/// 字符排序
|
||
/// </summary>
|
||
/// <param name="d">设计</param>
|
||
/// <param name="l"></param>
|
||
/// <param name="c"></param>
|
||
/// <returns></returns>
|
||
private string ExecelGetOcrDealWithForShow(string d, string l)
|
||
{
|
||
string rescult = "";
|
||
string[] dd = d.Split('-');
|
||
//for (int i = 0; i < dd.Length-1; i++)
|
||
//{
|
||
// rescult = rescult + dd[0];
|
||
//}
|
||
//rescult = dd[0].Remove(0, 1);
|
||
string[] ll = l.Split(',');
|
||
for (int i = 0; i < ll.Length; i++)
|
||
{
|
||
ll[i] = ll[i].Replace(" ", ""); ll[i] = ll[i].Replace("[", ""); ll[i] = ll[i].Replace("]", "");
|
||
string[] str = ll[i].Split('-');
|
||
rescult = rescult + dd[1]+ str[1] + str[0];
|
||
}
|
||
return rescult;
|
||
}
|
||
/// <summary>
|
||
/// 清空上次订单数据
|
||
/// </summary>
|
||
void ClearData()
|
||
{
|
||
|
||
QSV = null; Design = null; Layers = null; Colours = null; ProductStandard = null; ord = null;
|
||
NumberOfLanes = 0; width = 0; Gradient = 0; DistX = 0; DistY = 0;
|
||
}
|
||
/// <summary>
|
||
/// 清空上次订单显示区
|
||
/// </summary>
|
||
void ClearDataShow()
|
||
{
|
||
lbl_QSVShow.Text = "";
|
||
lbl_NOFShow.Text = "";
|
||
lbl_ProductStandardShow.Text = "";
|
||
lbl_widthShow.Text = "";
|
||
lbl_GradientShow.Text = "";
|
||
lbl_DistXShow.Text = "";
|
||
lbl_DistYShow.Text = "";
|
||
lbl_verOcrShow.Text = "";
|
||
|
||
|
||
}
|
||
|
||
private void txt_OrderNum_KeyDown(object sender, KeyEventArgs e)
|
||
{
|
||
if (e.KeyCode == Keys.Enter)
|
||
{
|
||
this.btn_OrderNum_Click(sender, e);
|
||
}
|
||
}
|
||
#endregion
|
||
|
||
#region PLC触发相机
|
||
|
||
#region 定位相机拍照触发处理函数
|
||
/// <summary>
|
||
/// 定位相机拍照信号过来程序需要进行的操作
|
||
///
|
||
/// </summary>
|
||
/// <param name="sender"></param>
|
||
/// <param name="e"></param>
|
||
private void DetCamTriger()
|
||
{
|
||
log.Info("PLC触发定位相机,正在拍照计算...");
|
||
try
|
||
{
|
||
m_dev_cam1.ExecuteSoftwareTrigger();
|
||
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
MessageBox.Show(ex.Message);
|
||
}
|
||
}
|
||
#endregion
|
||
|
||
#region OCR相机拍照触发处理函数
|
||
/// <summary>
|
||
/// OCR相机拍照信号过来需要进行的操作
|
||
/// </summary>
|
||
/// <param name="sender"></param>
|
||
/// <param name="e"></param>
|
||
private void OcrCamTriger()
|
||
{
|
||
log.Info("PLC触发OCR相机,正在拍照计算...");
|
||
try
|
||
{
|
||
m_dev_cam0.ExecuteSoftwareTrigger();
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
MessageBox.Show(ex.Message);
|
||
}
|
||
}
|
||
#endregion
|
||
|
||
#endregion
|
||
|
||
#region 结果处理
|
||
|
||
#region 定位结果处理
|
||
public void DetResult(object sender, CogJobManagerActionEventArgs e)
|
||
{
|
||
try
|
||
{
|
||
if (InvokeRequired)
|
||
{
|
||
Invoke(new DetResultDelegate(DetResult), new object[] { sender, e });
|
||
return;
|
||
}
|
||
//清除上次的结果显示
|
||
this.lbl_XShow.Text = "";
|
||
this.lbl_YShow.Text = "";
|
||
this.lbl_RShow.Text = "";
|
||
|
||
CogToolGroup myTG = myJob1.VisionTool as CogToolGroup;
|
||
CogToolBlock myTB = myTG.Tools["CogToolBlock1"] as CogToolBlock;
|
||
CogPMAlignTool myPMA = myTB.Tools["CogPMAlignTool2"] as CogPMAlignTool;
|
||
CogImageConvertTool myImage = myTB.Tools["CogImageConvertTool1"] as CogImageConvertTool;
|
||
|
||
////把vpro图像转为bitmap
|
||
//ICogImage cogimg = myImage.OutputImage;
|
||
//Bitmap bmp = new Bitmap(cogimg.ToBitmap());
|
||
//MemoryStream ms = new MemoryStream();
|
||
//bmp.Save(ms, System.Drawing.Imaging.ImageFormat.Bmp);
|
||
//byte[] bytes = ms.GetBuffer();
|
||
//ms.Close();
|
||
////保存DET图像
|
||
//if (!Directory.Exists(SaveImageFileDET))
|
||
//{
|
||
// Directory.CreateDirectory(SaveImageFileDET);
|
||
//}
|
||
//string strTime = System.DateTime.Now.ToString("yyyyMMddHHmmss");
|
||
|
||
//FileStream fs = new FileStream(SaveImageFileDET + '\\' + strTime + ".bmp", FileMode.Create);
|
||
//BinaryWriter bw = new BinaryWriter(fs);
|
||
//bw.Write(bytes, 0, bytes.Length);
|
||
//bw.Close();
|
||
//fs.Close();
|
||
//log.Info("定位存图已完成");
|
||
|
||
|
||
Location_Display.Image = myPMA.InputImage;
|
||
Location_Display.StaticGraphics.Clear();
|
||
Location_Display.InteractiveGraphics.Clear();
|
||
Location_Display.Fit();
|
||
if (myPMA.Results != null)
|
||
{
|
||
int i = GetXYRonRightDown(myPMA.Results);//获取视野中最右下边的K标志坐标的索引
|
||
double xx = myPMA.Results[i].GetPose().TranslationX;
|
||
double yy = myPMA.Results[i].GetPose().TranslationY;
|
||
double rr = CogMisc.RadToDeg(myPMA.Results[i].GetPose().Rotation);
|
||
|
||
this.lbl_XShow.Text = xx.ToString();
|
||
this.lbl_YShow.Text = yy.ToString();
|
||
this.lbl_RShow.Text = rr.ToString();
|
||
|
||
//画模型轮廓
|
||
CogCompositeShape shape = myPMA.Results[i].CreateResultGraphics(CogPMAlignResultGraphicConstants.MatchFeatures);
|
||
CogCompositeShape shape1 = myPMA.Results[i].CreateResultGraphics(CogPMAlignResultGraphicConstants.CoordinateAxes);
|
||
this.Location_Display.InteractiveGraphics.Add(shape, "", false);
|
||
this.Location_Display.InteractiveGraphics.Add(shape1, "", false);
|
||
//画定位的十字点
|
||
CPMARunStatus.DrawPointMarker(xx, yy, CogMisc.DegToRad(rr), CogColorConstants.Orange, Location_Display, ".");
|
||
log.Info("定位计算已完成。");
|
||
sendToPLC(xx, yy, rr);
|
||
}
|
||
else
|
||
{
|
||
log.Info("没有定位到K标志,请查看图像或相机是否正常");
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
log.Error(ex.Message + "未检测到K标志");
|
||
if (this.check_Autorun.Checked == false)
|
||
{
|
||
byte[] datax = DataConverter.FloatToByte(0.0f, true);
|
||
cc24?.NotifyCamInspectionComplete(0, datax);
|
||
cc24?.NotifyCamAcqComplete(0);
|
||
}
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取右下角定位标志坐标
|
||
/// </summary>
|
||
/// <param name="Results">PatMAX结果</param>
|
||
/// <returns></returns>
|
||
private int GetXYRonRightDown(CogPMAlignResults Results)
|
||
{
|
||
|
||
int i=0;
|
||
double[] xx = new double[Results.Count], yy = new double[Results.Count], rr = new double[Results.Count];
|
||
//第一次循环将所有坐标取出
|
||
for (int j = 0; j < Results.Count; j++)
|
||
{
|
||
xx[j] = Results[j].GetPose().TranslationX;
|
||
yy[j] = Results[j].GetPose().TranslationY;
|
||
rr[j] = CogMisc.RadToDeg(Results[j].GetPose().Rotation);
|
||
}
|
||
if (Results.Count == 1)
|
||
{
|
||
i= 0;
|
||
}
|
||
else if (Results.Count == 2)
|
||
{
|
||
double Xdist,Ydist;
|
||
Xdist = Math.Abs(xx[0] - xx[1]);
|
||
Ydist = Math.Abs(yy[0] - yy[1]);
|
||
if (Xdist>Ydist)
|
||
{
|
||
i= Array.IndexOf(xx, xx.Min());
|
||
}
|
||
else if(Xdist<Ydist)
|
||
{
|
||
i= Array.IndexOf(yy, yy.Max());
|
||
}
|
||
|
||
}
|
||
else
|
||
{
|
||
double averageX = xx.Average();
|
||
//第二次循环保留x比平均x值小的元素
|
||
for (int j = 0; j < Results.Count; j++)
|
||
{
|
||
if (averageX < xx[j])
|
||
{
|
||
xx[j] = -9999;
|
||
yy[j] = -9999;
|
||
}
|
||
}
|
||
//找出保留元素中Y值最大的
|
||
i = Array.IndexOf(yy, yy.Max());
|
||
|
||
}
|
||
return i;
|
||
}
|
||
#endregion
|
||
|
||
#region 排序算法
|
||
List<Point> paixu(List<Point> points)
|
||
{
|
||
int rowDistance = 50;
|
||
List<List<Point>> rows = new List<List<Point>>();
|
||
|
||
for (int i = 0; i < points.Count; i++)
|
||
{
|
||
List<Point> row = new List<Point>();
|
||
row.Add(points[i]);
|
||
|
||
for (int j = i + 1; j < points.Count; j++)
|
||
{
|
||
if (Math.Abs(points[j].y - points[i].y) < rowDistance)
|
||
{
|
||
row.Add(points[j]);
|
||
}
|
||
}
|
||
|
||
rows.Add(row);
|
||
}
|
||
|
||
List<Point> sortedPoints = new List<Point>();
|
||
|
||
foreach (List<Point> row in rows)
|
||
{
|
||
row.Sort((x, y) => x.x - y.x);
|
||
foreach (Point point in row)
|
||
{
|
||
if (!sortedPoints.Contains(point))
|
||
{
|
||
sortedPoints.Add(point);
|
||
|
||
}
|
||
|
||
}
|
||
}
|
||
|
||
return sortedPoints;
|
||
}
|
||
//ai suggest① 先按 y 排序 → ② 一次扫描把相邻且 Δy<50 的点归并成同一行 → ③ 每行内部按 x 排序 → ④ 按行收集。
|
||
//List<Point> paixu(List<Point> points)
|
||
//{
|
||
// const int rowDistance = 50;
|
||
// if (points.Count == 0) return new List<Point>();
|
||
|
||
// // 1. 先按纵坐标排序
|
||
// var src = points.OrderBy(p => p.y).ThenBy(p => p.x).ToList();
|
||
|
||
// var rows = new List<List<Point>>();
|
||
// List<Point> curRow = new List<Point> { src[0] };
|
||
// float baseY = src[0].y;
|
||
|
||
// // 2. 一次扫描分好行
|
||
// for (int i = 1; i < src.Count; i++)
|
||
// {
|
||
// if (Math.Abs(src[i].y - baseY) < rowDistance)
|
||
// {
|
||
// curRow.Add(src[i]);
|
||
// }
|
||
// else
|
||
// {
|
||
// rows.Add(curRow);
|
||
// curRow = new List<Point> { src[i] };
|
||
// baseY = src[i].y;
|
||
// }
|
||
// }
|
||
// rows.Add(curRow); // 别忘了最后一行
|
||
|
||
// // 3. 行内再按 x 排一次(虽然 OrderBy 已做过,保险)
|
||
// foreach (var row in rows)
|
||
// row.Sort((a, b) => a.x.CompareTo(b.x));
|
||
|
||
// // 4. 按行先后汇总
|
||
// var sorted = new List<Point>();
|
||
// foreach (var row in rows)
|
||
// sorted.AddRange(row);
|
||
|
||
// return sorted;
|
||
//}
|
||
#endregion
|
||
|
||
#region OCR结果处理
|
||
private void OCRResult(Bitmap bmp)
|
||
{
|
||
try
|
||
{
|
||
if (InvokeRequired)
|
||
{
|
||
Invoke(new OcrResultDelegate(OCRResult), new object[] { bmp });
|
||
return;
|
||
}
|
||
|
||
//CogToolGroup myTG = myJob2.VisionTool as CogToolGroup;
|
||
//CogAcqFifoTool myImage = myTG.Tools["CogAcqFifoTool1"] as CogAcqFifoTool;
|
||
|
||
//把vpro图像先转为bitmap
|
||
//ICogImage cogimg = myImage.OutputImage;
|
||
//Bitmap bmp = new Bitmap(cogimg.ToBitmap()); //有时会丢图cogimg为空,改为SDK取图
|
||
MemoryStream ms = new MemoryStream();
|
||
bmp.Save(ms, System.Drawing.Imaging.ImageFormat.Bmp);
|
||
byte[] bytes = ms.GetBuffer();
|
||
ms.Close();
|
||
string strtimef = DateTime.Now.ToString("yyyy-MM-dd");
|
||
//保存ocr图像
|
||
if (!Directory.Exists(SaveImageFileOCR + '\\' + strtimef))
|
||
{
|
||
Directory.CreateDirectory(SaveImageFileOCR + '\\' + strtimef);
|
||
}
|
||
string strTime = System.DateTime.Now.ToString("yyyyMMddHHmmss");
|
||
//string strtimef = DateTime.Now.ToString("yyyy-MM-dd");
|
||
FileStream fs = new FileStream(SaveImageFileOCR + '\\' + strtimef + '\\' + strTime + ".bmp", FileMode.Create);
|
||
BinaryWriter bw = new BinaryWriter(fs);
|
||
bw.Write(bytes, 0, bytes.Length);
|
||
bw.Close();
|
||
fs.Close();
|
||
log.Info("OCR存图已完成");
|
||
|
||
CutPicture(SaveImageFileOCR + '\\' + strtimef + '\\' + strTime + ".bmp", 200, 1400, 5052, 1600);
|
||
//List<PointD> temps = new List<PointD>();
|
||
|
||
GetOCRImage getOCRImage = new GetOCRImage();
|
||
GetOCRImage.FileTimeInfo file = getOCRImage.GetLatesFileImageName(SaveImageFileOCR + '\\' + strtimef, ".bmp");
|
||
if (file != null)
|
||
{
|
||
byte[] ocrimagebyte = File.ReadAllBytes(file.FileName);
|
||
Bitmap Bmp = new Bitmap(new MemoryStream(ocrimagebyte));
|
||
List<string> lastocr = new List<string>();
|
||
OCRResult ocrResult = Engine.DetectText(ocrimagebyte);
|
||
|
||
|
||
// log.Debug("读取原始数据1:" + ocrResult.JsonText);
|
||
List<Point> pointsList = new List<Point>();
|
||
|
||
string[] sd = Design.Split('-');
|
||
foreach (var item in ocrResult.TextBlocks) //将检测框绘制在图片上
|
||
{
|
||
if (item.Text.Contains(sd[1]))
|
||
{
|
||
using (Graphics g = Graphics.FromImage(Bmp))
|
||
{
|
||
g.DrawPolygon(new Pen(Brushes.Red, 2), item.BoxPoints.Select(x => new PointF() { X = x.X, Y = x.Y }).ToArray());
|
||
}
|
||
//lastocr.Add(item.Text);
|
||
|
||
pointsList.Add(new Point(item.BoxPoints[0].X, item.BoxPoints[0].Y,item.Text));
|
||
|
||
}
|
||
}
|
||
|
||
List<Point> paixujeguo = paixu(pointsList);
|
||
foreach (var it in paixujeguo)
|
||
{
|
||
lastocr.Add(it.txt);
|
||
}
|
||
|
||
|
||
|
||
//对图像显示区更新
|
||
Ocr_picBox.BackgroundImage = null;
|
||
Ocr_picBox.BackgroundImage = Bmp;
|
||
|
||
txt_readOcrResultShow.Clear();
|
||
|
||
if (!Coprinted_ordeFlag) //判断是否为共印订单
|
||
{
|
||
txt_readOcrResultShow.Text = GETOCR(lastocr, Design);
|
||
log.Info("字符读取结果:" + GETOCR(lastocr, Design));
|
||
|
||
int distance = CalculateAcc(ExecelGetOcrDealWithForShow(Design, Layers), GETOCR(lastocr, Design));
|
||
float maxLength = Math.Max(ExecelGetOcrDealWithForShow(Design, Layers).Length, GETOCR(lastocr, Design).Length);
|
||
float strSimilarity = (maxLength - distance) / maxLength;
|
||
ShowTheLansRs(mMatchingStr, strSimilarity);
|
||
}
|
||
else
|
||
{
|
||
txt_readOcrResultShow.Text = GETOCR(lastocr, Design);
|
||
log.Info("字符读取结果:" + GETOCR(lastocr, Design));
|
||
|
||
int distance = CalculateAcc(verocr[mMatchingStr], GETOCR(lastocr, Design));
|
||
float maxLength = Math.Max(verocr[mMatchingStr].Length, GETOCR(lastocr, Design).Length);
|
||
float strSimilarity = (maxLength - distance) / maxLength;
|
||
|
||
ShowTheLansRs(mMatchingStr, strSimilarity);
|
||
|
||
}
|
||
|
||
if (this.check_Autorun.Checked == false)
|
||
{
|
||
byte[] datas = DataConverter.FloatToByte(0.0f);
|
||
|
||
cc24?.NotifyCamAcqComplete(1); //通知PLC OCR相机已完成采集
|
||
cc24?.NotifyCamInspectionComplete(1, datas);
|
||
}
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
log.Error(ex.Message + "未检测到字符");
|
||
if (this.check_Autorun.Checked == false)
|
||
{
|
||
byte[] datax = DataConverter.FloatToByte(0.0f, true);
|
||
cc24?.NotifyCamInspectionComplete(1, datax);
|
||
cc24?.NotifyCamAcqComplete(1);
|
||
}
|
||
}
|
||
}
|
||
|
||
#region 图片裁剪
|
||
private void CutPicture(String picPath, int x, int y, int width, int height)
|
||
{
|
||
//图片路径
|
||
String oldPath = picPath;
|
||
//新图片路径
|
||
String newPath = System.IO.Path.GetExtension(oldPath);
|
||
//计算新的文件名,在新文件名后加_new
|
||
newPath = oldPath.Substring(0, oldPath.Length - newPath.Length) + "_new"+ mMatchingStr + newPath;
|
||
//定义截取矩形
|
||
System.Drawing.Rectangle cropArea = new System.Drawing.Rectangle(x, y, width, height);
|
||
//要截取的区域大小
|
||
//加载图片
|
||
System.Drawing.Image img = System.Drawing.Image.FromStream(new System.IO.MemoryStream(System.IO.File.ReadAllBytes(oldPath)));
|
||
//判断超出的位置否
|
||
if ((img.Width < x + width) || img.Height < y + height)
|
||
{
|
||
MessageBox.Show("裁剪尺寸超出原有尺寸!");
|
||
img.Dispose();
|
||
return;
|
||
}
|
||
//定义Bitmap对象
|
||
System.Drawing.Bitmap bmpImage = new System.Drawing.Bitmap(img);
|
||
//进行裁剪
|
||
System.Drawing.Bitmap bmpCrop = bmpImage.Clone(cropArea, bmpImage.PixelFormat);
|
||
//保存成新文件
|
||
bmpCrop.Save(newPath);
|
||
//释放对象
|
||
img.Dispose();
|
||
bmpCrop.Dispose();
|
||
}
|
||
#endregion
|
||
|
||
|
||
|
||
/// <summary>
|
||
/// 使用正则表达式提取结果
|
||
/// </summary>
|
||
/// <param name="readOCR">读到的所有字符</param>
|
||
/// <param name="design">设计</param>
|
||
/// <param name="colours"></param>
|
||
/// <returns></returns>
|
||
private string GETOCR(List<string> readOCR, string design)
|
||
{
|
||
string ocrresult="";
|
||
string[] d = design.Split('-');
|
||
string pattern = @""+d[1]+"[A-Z0-9]{8}";
|
||
for (int i = 0; i < readOCR.Count; i++)
|
||
{
|
||
readOCR[i]=readOCR[i].Replace("_", "");
|
||
readOCR[i] = readOCR[i].Replace(" ", "");
|
||
}
|
||
MatchCollection matchResults;
|
||
|
||
try
|
||
{
|
||
foreach (var item in readOCR)
|
||
{
|
||
matchResults = Regex.Matches(item, pattern);
|
||
for (int i = 0; i < matchResults.Count; i++)
|
||
{
|
||
ocrresult = ocrresult + matchResults[i];
|
||
}
|
||
}
|
||
}
|
||
catch
|
||
{
|
||
ocrresult = null;
|
||
}
|
||
if (ocrresult != null)
|
||
{
|
||
return ocrresult;
|
||
}
|
||
else
|
||
{
|
||
return "未能匹配到对应字符请查看产品是否超标,或订单号是否正确";
|
||
}
|
||
}
|
||
/// <summary>
|
||
/// 使用Levenshtein Distance计算字符串相似度
|
||
/// </summary>
|
||
/// <param name="readocr">excel取到的验证字符</param>
|
||
/// <param name="getocr">读取到的字符</param>
|
||
int CalculateAcc(string readocr, string getocr)
|
||
{
|
||
int columnSize = getocr.Length;
|
||
int rowSize = readocr.Length;
|
||
if (columnSize == 0)
|
||
{
|
||
return rowSize;
|
||
}
|
||
if (rowSize == 0)
|
||
{
|
||
return columnSize;
|
||
}
|
||
int[,] matrix = new int[rowSize + 1, columnSize + 1];
|
||
for (int i = 0; i <= columnSize; i++)
|
||
{
|
||
matrix[0, 1] = i;//ai提示此处应为matrix[0,i]=i;
|
||
}
|
||
for (int j = 1; j <= rowSize; j++)//ai提示此处应为j=0
|
||
{
|
||
matrix[j, 0] = j;
|
||
}
|
||
|
||
for (int i = 0; i < rowSize; i++)
|
||
{
|
||
for (int j = 0; j < columnSize; j++)
|
||
{
|
||
int sign;
|
||
if (getocr[j].Equals(readocr[i]))
|
||
sign = 0;
|
||
else
|
||
sign = 1;
|
||
matrix[i + 1, j + 1] = Math.Min(Math.Min(matrix[i, j] + sign, matrix[i + 1, j] + 1), matrix[i, j + 1] + 1);
|
||
}
|
||
}
|
||
|
||
return matrix[rowSize, columnSize];
|
||
|
||
}
|
||
/// <summary>
|
||
/// 将结果显示在对应状态栏
|
||
/// </summary>
|
||
/// <param name="mM">PLC给的当前在第几道拍照</param>
|
||
/// <param name="s">OCR字符相似度结果</param>
|
||
void ShowTheLansRs(float mM, float s)
|
||
{
|
||
int mMnum = Convert.ToInt32(mM);
|
||
//s = 1;//**************************************************************************************************注意
|
||
switch (mMnum)
|
||
{
|
||
case 1:
|
||
this.lbl_L1_verOcrRs.BackColor = Color.Lime;
|
||
if (s < 0.9)
|
||
{
|
||
lbl_L1_verOcrRs.BackColor = Color.Red;
|
||
}
|
||
else if(s>0.9 & s<1)
|
||
{
|
||
lbl_L1_verOcrRs.BackColor = Color.Lime;
|
||
s = 1;
|
||
}
|
||
ocrAcc.Add(s);
|
||
this.lbl_L1_verOcrRs.Text = s * 100 + "%";
|
||
log.Info("字符对比结果:当前第" + mMnum + "道的读取字符与验证字符相似度为" + s * 100 + "%");
|
||
break;
|
||
case 2:
|
||
this.lbl_L2_verOcrRs.BackColor = Color.Lime;
|
||
if (s < 0.9)
|
||
{
|
||
lbl_L2_verOcrRs.BackColor = Color.Red;
|
||
}
|
||
else if (s > 0.9 & s < 1)
|
||
{
|
||
lbl_L2_verOcrRs.BackColor = Color.Lime;
|
||
s = 1;
|
||
}
|
||
ocrAcc.Add(s);
|
||
this.lbl_L2_verOcrRs.Text = s * 100 + "%";
|
||
log.Info("字符对比结果:当前第" + mMnum + "道的读取字符与验证字符相似度为" + s * 100 + "%");
|
||
break;
|
||
case 3:
|
||
this.lbl_L3_verOcrRs.BackColor = Color.Lime;
|
||
if (s < 0.9)
|
||
{
|
||
lbl_L3_verOcrRs.BackColor = Color.Red;
|
||
}
|
||
else if (s > 0.9 & s < 1)
|
||
{
|
||
lbl_L3_verOcrRs.BackColor = Color.Lime;
|
||
s = 1;
|
||
}
|
||
ocrAcc.Add(s);
|
||
this.lbl_L3_verOcrRs.Text = s * 100 + "%";
|
||
log.Info("字符对比结果:当前第" + mMnum + "道的读取字符与验证字符相似度为" + s * 100 + "%");
|
||
break;
|
||
case 4:
|
||
this.lbl_L4_verOcrRs.BackColor = Color.Lime;
|
||
if (s < 0.9)
|
||
{
|
||
lbl_L4_verOcrRs.BackColor = Color.Red;
|
||
}
|
||
else if (s > 0.9 & s < 1)
|
||
{
|
||
lbl_L4_verOcrRs.BackColor = Color.Lime;
|
||
s = 1;
|
||
}
|
||
ocrAcc.Add(s);
|
||
this.lbl_L4_verOcrRs.Text = s * 100 + "%";
|
||
log.Info("字符对比结果:当前第" + mMnum + "道的读取字符与验证字符相似度为" + s * 100 + "%");
|
||
break;
|
||
case 5:
|
||
this.lbl_L5_verOcrRs.BackColor = Color.Lime;
|
||
if (s < 0.9)
|
||
{
|
||
lbl_L5_verOcrRs.BackColor = Color.Red;
|
||
}
|
||
else if (s > 0.9 & s < 1)
|
||
{
|
||
lbl_L5_verOcrRs.BackColor = Color.Lime;
|
||
s = 1;
|
||
}
|
||
ocrAcc.Add(s);
|
||
this.lbl_L5_verOcrRs.Text = s * 100 + "%";
|
||
log.Info("字符对比结果:当前第" + mMnum + "道的读取字符与验证字符相似度为" + s * 100 + "%");
|
||
break;
|
||
case 6:
|
||
this.lbl_L6_verOcrRs.BackColor = Color.Lime;
|
||
if (s < 0.9)
|
||
{
|
||
lbl_L6_verOcrRs.BackColor = Color.Red;
|
||
}
|
||
else if (s > 0.9 & s < 1)
|
||
{
|
||
lbl_L6_verOcrRs.BackColor = Color.Lime;
|
||
s = 1;
|
||
}
|
||
ocrAcc.Add(s);
|
||
this.lbl_L6_verOcrRs.Text = s * 100 + "%";
|
||
log.Info("字符对比结果:当前第" + mMnum + "道的读取字符与验证字符相似度为" + s * 100 + "%");
|
||
break;
|
||
case 7:
|
||
this.lbl_L7_verOcrRs.BackColor = Color.Lime;
|
||
if (s < 0.9)
|
||
{
|
||
lbl_L7_verOcrRs.BackColor = Color.Red;
|
||
}
|
||
else if (s > 0.9 & s < 1)
|
||
{
|
||
lbl_L7_verOcrRs.BackColor = Color.Lime;
|
||
s = 1;
|
||
}
|
||
ocrAcc.Add(s);
|
||
this.lbl_L7_verOcrRs.Text = s * 100 + "%";
|
||
log.Info("字符对比结果:当前第" + mMnum + "道的读取字符与验证字符相似度为" + s * 100 + "%");
|
||
break;
|
||
case 8:
|
||
this.lbl_L8_verOcrRs.BackColor = Color.Lime;
|
||
if (s < 0.9)
|
||
{
|
||
lbl_L8_verOcrRs.BackColor = Color.Red;
|
||
}
|
||
else if (s > 0.9 & s < 1)
|
||
{
|
||
lbl_L8_verOcrRs.BackColor = Color.Lime;
|
||
s = 1;
|
||
}
|
||
ocrAcc.Add(s);
|
||
this.lbl_L8_verOcrRs.Text = s * 100 + "%";
|
||
log.Info("字符对比结果:当前第" + mMnum + "道的读取字符与验证字符相似度为" + s * 100 + "%");
|
||
break;
|
||
case 9:
|
||
this.lbl_L9_verOcrRs.BackColor = Color.Lime;
|
||
if (s < 0.9)
|
||
{
|
||
lbl_L9_verOcrRs.BackColor = Color.Red;
|
||
}
|
||
else if (s > 0.9 & s < 1)
|
||
{
|
||
lbl_L9_verOcrRs.BackColor = Color.Lime;
|
||
s = 1;
|
||
}
|
||
ocrAcc.Add(s);
|
||
this.lbl_L9_verOcrRs.Text = s * 100 + "%";
|
||
log.Info("字符对比结果:当前第" + mMnum + "道的读取字符与验证字符相似度为" + s * 100 + "%");
|
||
break;
|
||
}
|
||
}
|
||
#endregion
|
||
|
||
#endregion
|
||
|
||
#region 通讯相关
|
||
|
||
#region 通讯初始化
|
||
void InitializeCC24()
|
||
{
|
||
try
|
||
{
|
||
cc24 = new CC24();
|
||
|
||
cc24.VisionReceivedNewUserData += CC24_NewUserDataReceived;
|
||
cc24.PlcConnectionStatusChanged += CC24_PlcConnectionStatusChanged;
|
||
cc24.PlcTriggerCamAcqStart += CC24_PlcTriggerCamAcqStart;
|
||
cc24.PlcTriggerCamAcqStop += CC24_PlcTriggerCamAcqStop;
|
||
cc24.NotifyCamAcqEnabled += CC24_NotifyCamAcqEnabled;
|
||
cc24.NotifyCamAcqDisabled += CC24_NotifyCamAcqDisabled;
|
||
|
||
|
||
|
||
cc24.Initialize();
|
||
cc24.NotifyCamAcqEnable(0);
|
||
cc24.NotifyCamAcqEnable(1);
|
||
|
||
this.Invoke(new Action(() =>
|
||
{
|
||
if (cc24.SignalState.PlcConnectionStatus)
|
||
{
|
||
ttls_PCLStatusShow.Visible = true;
|
||
}
|
||
else
|
||
{
|
||
ttls_PCLStatusShow.Visible = false;
|
||
|
||
}
|
||
}));
|
||
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
log.Error($"CommCard Initialize Error: {ex.Message}");
|
||
}
|
||
|
||
}
|
||
#endregion
|
||
|
||
#region 相机采集使能状态
|
||
private void CC24_NotifyCamAcqEnabled(int cameraIndex, bool isEnabled)
|
||
{
|
||
|
||
this.Invoke(new Action(() =>
|
||
{
|
||
if (isEnabled)
|
||
{
|
||
this.ttls_AcqEnableShow.Visible = true;
|
||
}
|
||
else
|
||
{
|
||
this.ttls_AcqEnableShow.Visible = false;
|
||
}
|
||
}));
|
||
}
|
||
|
||
private void CC24_NotifyCamAcqDisabled(int cameraIndex, bool isEnabled)
|
||
{
|
||
this.Invoke(new Action(() =>
|
||
{
|
||
if (isEnabled)
|
||
{
|
||
this.ttls_AcqEnableShow.Visible = true;
|
||
}
|
||
else
|
||
{
|
||
this.ttls_AcqEnableShow.Visible = false;
|
||
}
|
||
}));
|
||
|
||
}
|
||
#endregion
|
||
|
||
#region 接收PLC数据
|
||
void CC24_NewUserDataReceived(object sender, CogNdmNewUserDataEventArgs e)
|
||
{
|
||
if (InvokeRequired)
|
||
{
|
||
Invoke(new CogNdmNewUserDataEventHandler(CC24_NewUserDataReceived), new object[] { sender, e });
|
||
return;
|
||
}
|
||
|
||
byte[] data = cc24.ReadBytesFromPLC(0, 4);
|
||
|
||
float mMatchingStrf = DataConverter.ByteToFloat(data, true);
|
||
mMatchingStr = Convert.ToInt32(mMatchingStrf);
|
||
|
||
log.Info("PC接收PLC数据:数据内容:" + mMatchingStr);
|
||
if (NumberOfLanes+1 == mMatchingStr)
|
||
{
|
||
if(ocrAcc.Min()<0.95)
|
||
{
|
||
MessageBox.Show("当前检测中出现严重错误请注意!",this.Text, MessageBoxButtons.OK,MessageBoxIcon.Error);
|
||
}
|
||
else if(ocrAcc.Min()>0.95 & ocrAcc.Min()<1)
|
||
{
|
||
MessageBox.Show("当前检测中出现可允许误差请注意!", this.Text, MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||
}
|
||
ocrAcc.Clear();
|
||
}
|
||
|
||
}
|
||
#endregion
|
||
|
||
#region 接收触发相机信号
|
||
void CC24_PlcTriggerCamAcqStart(object sender, CogNdmTriggerAcquisitionEventArgs e)
|
||
{
|
||
if (InvokeRequired)
|
||
{
|
||
Invoke(new CogNdmTriggerAcquisitionEventHandler(CC24_PlcTriggerCamAcqStart), new object[] { sender, e });
|
||
return;
|
||
}
|
||
try
|
||
{
|
||
|
||
|
||
#region 接收到定位拍照信号
|
||
if (e.CameraIndex == 0)
|
||
{
|
||
DetCamTriger();
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region 接收到OCR拍照信号
|
||
if (e.CameraIndex == 1)
|
||
{
|
||
Thread.Sleep(100);
|
||
OcrCamTriger();
|
||
}
|
||
|
||
#endregion
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
log.Error($"Trigger AcqStart Error: {ex.Message}");
|
||
}
|
||
}
|
||
#endregion
|
||
|
||
#region 相机停止
|
||
private void CC24_PlcTriggerCamAcqStop(object sender, CogNdmTriggerAcquisitionStopEventArgs e)
|
||
{
|
||
|
||
if (InvokeRequired)
|
||
{
|
||
Invoke(new CogNdmTriggerAcquisitionStopEventHandler(CC24_PlcTriggerCamAcqStop), new object[] { sender, e });
|
||
return;
|
||
}
|
||
if (e.CameraIndex == 0)
|
||
{
|
||
log.Info("PLC中断定位相机拍照。");
|
||
}
|
||
if (e.CameraIndex == 1)
|
||
{
|
||
log.Info("PLC中断OCR相机拍照。");
|
||
}
|
||
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region 通讯状态发生改变
|
||
private void CC24_PlcConnectionStatusChanged(object sender, CogNdmProtocolStatusChangedEventArgs e)
|
||
{
|
||
// The event is raised from a non-GUI thread.
|
||
// Invoke this function on the GUI thread.
|
||
if (InvokeRequired)
|
||
{
|
||
Invoke(new CogNdmProtocolStatusChangedEventHandler(CC24_PlcConnectionStatusChanged), new object[] { sender, e });
|
||
return;
|
||
}
|
||
if (e.ProtocolStatus == CogNdmConnectionStatusConstants.Connected)
|
||
{
|
||
//PlcContinueFlag = true;
|
||
log.Info("PLC已连接PC,可以进行相关操作");
|
||
ttls_PCLStatusShow.Visible = true;
|
||
}
|
||
else if (e.ProtocolStatus != CogNdmConnectionStatusConstants.Connecting)
|
||
{
|
||
//PlcContinueFlag = false;
|
||
log.Info("PLC已断开PC,请查看相关设备是否连接");
|
||
ttls_PCLStatusShow.Visible = false;
|
||
}
|
||
}
|
||
#endregion
|
||
|
||
#region 通讯发送坐标
|
||
private void sendToPLC(double x, double y, double r)
|
||
{
|
||
|
||
try
|
||
{
|
||
string[] col = Colours.Split(',');
|
||
|
||
|
||
float xx = (float)x;
|
||
|
||
float yy = (float)y;
|
||
float rr = (float)r;
|
||
List<float> ocrxx = new List<float>();
|
||
List<float> ocryy = new List<float>();
|
||
|
||
|
||
|
||
|
||
switch (ProductStandard)
|
||
{
|
||
case "TBA1000Slim":
|
||
switch (col.Length)
|
||
{
|
||
case 1:
|
||
xx = (float)x - 9.5f;
|
||
break;
|
||
case 2:
|
||
xx = (float)x - 19f;
|
||
break;
|
||
case 3:
|
||
xx = (float)x - 28.5f;
|
||
break;
|
||
case 4:
|
||
xx = (float)x - 38f;
|
||
break;
|
||
case 5:
|
||
xx = (float)x - 47.5f;
|
||
break;
|
||
case 6:
|
||
xx = (float)x - 57f;
|
||
break;
|
||
}
|
||
break;
|
||
case "TBA250B":
|
||
switch (col.Length)
|
||
{
|
||
case 1:
|
||
xx = (float)x - 9.5f;
|
||
break;
|
||
case 2:
|
||
xx = (float)x - 19f;
|
||
break;
|
||
case 3:
|
||
xx = (float)x - 28.5f;
|
||
break;
|
||
case 4:
|
||
xx = (float)x - 38f;
|
||
break;
|
||
case 5:
|
||
xx = (float)x - 38f;
|
||
break;
|
||
case 6:
|
||
xx = (float)x - 38f;
|
||
break;
|
||
}
|
||
break;
|
||
case "TBA125Slim":
|
||
switch (col.Length)
|
||
{
|
||
case 1:
|
||
xx = (float)x - 9.5f;
|
||
break;
|
||
case 2:
|
||
xx = (float)x - 19f;
|
||
break;
|
||
case 3:
|
||
xx = (float)x - 28.5f;
|
||
break;
|
||
case 4:
|
||
xx = (float)x - 28.5f;
|
||
break;
|
||
case 5:
|
||
xx = (float)x - 28.5f;
|
||
break;
|
||
case 6:
|
||
xx = (float)x - 28.5f;
|
||
break;
|
||
}
|
||
break;
|
||
case "TPA250SQ":
|
||
switch (col.Length)
|
||
{
|
||
case 1:
|
||
xx = (float)x - 9.5f;
|
||
break;
|
||
case 2:
|
||
xx = (float)x - 19f;
|
||
break;
|
||
case 3:
|
||
xx = (float)x - 19f;
|
||
break;
|
||
case 4:
|
||
xx = (float)x - 19f;
|
||
break;
|
||
case 5:
|
||
xx = (float)x - 19f;
|
||
break;
|
||
case 6:
|
||
xx = (float)x - 19f;
|
||
break;
|
||
}
|
||
break;
|
||
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
|
||
float ocrx = 0, ocry = 0;
|
||
List<float> l = new List<float>();
|
||
l.Add((float)NumberOfLanes);
|
||
int nol = Convert.ToInt32(NumberOfLanes);
|
||
log.Info("当前订单OCR区域共" + nol + "组:");
|
||
for (int item = 0; item < nol; item++)
|
||
{
|
||
|
||
if (item == 0)
|
||
{
|
||
ocrx = xx - ((float)DistX) * ((float)Math.Cos((rr * Math.PI) / 180));
|
||
l.Add(ocrx);
|
||
ocry = yy - ((float)DistY) * ((float)Math.Sin((rr * Math.PI) / 180));
|
||
l.Add(ocry);
|
||
ocrxx.Add(ocrx);
|
||
ocryy.Add(ocry);
|
||
}
|
||
else
|
||
{
|
||
ocrx = ocrx + ((float)width * ((float)Math.Cos((rr * Math.PI) / 180)));
|
||
l.Add(ocrx);
|
||
ocry = ocry - ((float)Gradient * ((float)Math.Cos((rr * Math.PI) / 180)));
|
||
l.Add(ocry);
|
||
ocrxx.Add(ocrx);
|
||
ocryy.Add(ocry);
|
||
|
||
}
|
||
|
||
log.Info("第" + (item + 1) + "组坐标为:X:" + ocrxx[item] + ",Y:" + ocryy[item] + "。");
|
||
}
|
||
|
||
if (this.check_Autorun.Checked == false)
|
||
{
|
||
List<float> d = new List<float>();
|
||
for (int i=0;i<l.Count;i++)
|
||
{
|
||
if(i ==0)
|
||
{
|
||
d.Add(l[i]);
|
||
}
|
||
else if(i%2==1)
|
||
{
|
||
d.Add( l[l.Count - i-1]);
|
||
d.Add(l[l.Count - i]);
|
||
}
|
||
}
|
||
byte[] datax = DataConverter.FloatToByte(d, true);
|
||
|
||
cc24?.NotifyCamInspectionComplete(0, datax);
|
||
cc24?.NotifyCamAcqComplete(0);
|
||
|
||
log.Info("坐标已发送完成。");
|
||
}
|
||
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
log.Error(ex.Message + "未检测到K标志");
|
||
if (check_Autorun.Checked == false)
|
||
{
|
||
|
||
byte[] datax = DataConverter.FloatToByte(0.0f, true);
|
||
cc24?.NotifyCamInspectionComplete(0, datax);
|
||
cc24?.NotifyCamAcqComplete(0);
|
||
}
|
||
}
|
||
}
|
||
#endregion
|
||
|
||
#region 通讯关闭
|
||
private void CloseCC24()
|
||
{
|
||
try
|
||
{
|
||
cc24.VisionReceivedNewUserData -= CC24_NewUserDataReceived;
|
||
cc24.PlcConnectionStatusChanged -= CC24_PlcConnectionStatusChanged;
|
||
cc24.PlcTriggerCamAcqStart -= CC24_PlcTriggerCamAcqStart;
|
||
cc24.PlcTriggerCamAcqStop -= CC24_PlcTriggerCamAcqStop;
|
||
cc24.NotifyCamAcqEnabled -= CC24_NotifyCamAcqEnabled;
|
||
cc24.NotifyCamAcqDisabled -= CC24_NotifyCamAcqDisabled;
|
||
|
||
|
||
cc24.Shutdown();
|
||
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
log.Error($"CommCard Closing Error: {ex.Message}");
|
||
}
|
||
}
|
||
#endregion
|
||
|
||
#endregion
|
||
}
|
||
}
|