1990 lines
76 KiB
C#
1990 lines
76 KiB
C#
/************************
|
||
* 作者:CVE-安翀岚
|
||
*
|
||
* Vision:1.0.23.1007 (发布使用)
|
||
* Windows10 X64(PaddleOCR不能部署在32位操作系统上)
|
||
* PaddleOCR 3.10
|
||
* Vpro: 9.5 SR2
|
||
*
|
||
***********************/
|
||
|
||
|
||
using AVP.CRobot;
|
||
using Bjcve.Comm.FFP;
|
||
using CLIDelegate;
|
||
using Cognex.VisionPro;
|
||
using Cognex.VisionPro.Comm;
|
||
using Cognex.VisionPro.ImageProcessing;
|
||
using Cognex.VisionPro.PMAlign;
|
||
using Cognex.VisionPro.QuickBuild;
|
||
using Cognex.VisionPro.ToolBlock;
|
||
using Cognex.VisionPro.ToolGroup;
|
||
using log4net;
|
||
using LogShowLib;
|
||
using OfficeOpenXml;
|
||
using OpenCvSharp;
|
||
using PaddleOCRSharp;
|
||
using System;
|
||
using System.Collections.Generic;
|
||
using System.ComponentModel;
|
||
using System.Data;
|
||
using System.Drawing;
|
||
using System.IO;
|
||
using System.Linq;
|
||
using System.Text;
|
||
using System.Text.RegularExpressions;
|
||
using System.Threading;
|
||
using System.Threading.Tasks;
|
||
using System.Windows.Documents;
|
||
using System.Windows.Forms;
|
||
using ThridLibray;
|
||
using LibDataBase;
|
||
using LibReadTetraExcel;
|
||
|
||
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>
|
||
/// 表格路径
|
||
/// </summary>
|
||
string execlFileName = AppDomain.CurrentDomain.BaseDirectory + "Data\\Excle\\OCR文件0602.xlsx";
|
||
OrderConfig config = null;
|
||
/// <summary>
|
||
/// 定位Vpp文件
|
||
/// </summary>
|
||
string vppdetFile = AppDomain.CurrentDomain.BaseDirectory + "Data\\VPPFile\\liledet.vpp";
|
||
/// <summary>
|
||
/// 存图路径
|
||
/// </summary>
|
||
string SaveImageFileOCR = System.IO.Path.GetPathRoot(Application.ExecutablePath) + "SaveImage\\OCR";//ocr存图
|
||
string SaveImageFileDET = System.IO.Path.GetPathRoot(Application.ExecutablePath) + "SaveImage\\Det";//ocr存图
|
||
private CogJobManager myJobManagerDET;
|
||
private CogJob myJobDET;
|
||
|
||
bool PlcContinueFlag = false; //PLC状态旗帜
|
||
int mMatchingStr = 0;//接收当前OCR拍照位置
|
||
|
||
List<double> ocrAcc = new List<double>();
|
||
/// <summary>
|
||
/// 相机对象 1和2
|
||
/// </summary>
|
||
IDevice m_dev_cam_ocr, m_dev_cam_det;
|
||
|
||
delegate void DetResultDelegate(Object Sender, CogJobManagerActionEventArgs e);
|
||
delegate void OcrResultDelegate(Bitmap bmp);
|
||
#endregion
|
||
|
||
#region 窗体加载和关闭
|
||
|
||
/// <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;
|
||
btn_StarDet_manual.BackColor = Color.LightGray;
|
||
button1.BackColor = Color.LightGray;
|
||
button2.Enabled = false;
|
||
button2.BackColor = Color.LightGray;
|
||
btn_OrderNum.Enabled = false;
|
||
btn_OrderNum.BackColor = Color.LightGray;
|
||
log.Info("软件正在加载...");
|
||
Enabled = false;
|
||
Action action = (() =>
|
||
{
|
||
InitializeCamerOCR();
|
||
InitializeCamerDET();
|
||
InitializePaddleOCR();
|
||
|
||
log.Info("VPP文件加载中...");
|
||
try
|
||
{
|
||
myJobManagerDET = CogSerializer.LoadObjectFromFile(vppdetFile) as CogJobManager;
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
log.Error("定位VPP文件加载失败,请检查文件路径是否正确:" + ex.Message);
|
||
myJobManagerDET = null;
|
||
}
|
||
log.Info("定位VPP文件加载完成");
|
||
InitializeCC24();
|
||
|
||
log.Info("模型文件加载完成");
|
||
check_Autorun.BackgroundImage = Image.FromFile(Application.StartupPath + "\\logo_image\\ON.png");
|
||
ttls_SystemStatusShow.Visible = true;
|
||
ttls_CamStatusShow.Visible = true;
|
||
Invoke(new Action(() =>
|
||
{
|
||
btn_manualOcr.Enabled = true;
|
||
btn_manualDet.Enabled = true;
|
||
check_Autorun.Enabled = true;
|
||
Enabled = true;
|
||
btn_OrderNum.Enabled = true;
|
||
btn_OrderNum.BackColor = Color.DeepSkyBlue;
|
||
}));
|
||
});
|
||
|
||
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 =>
|
||
{
|
||
if (myJobManagerDET != null)
|
||
{
|
||
myJobDET = myJobManagerDET.Job(0);
|
||
|
||
// 注册结果队列事件
|
||
myJobManagerDET.UserResultAvailable += new CogJobManager.CogUserResultAvailableEventHandler(DetResult);
|
||
}
|
||
});
|
||
}
|
||
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
|
||
{
|
||
ClossCam();
|
||
|
||
//// 注销结果队列事件
|
||
if (myJobManagerDET != null)
|
||
{
|
||
myJobManagerDET.UserResultAvailable -= new CogJobManager.CogUserResultAvailableEventHandler(DetResult);
|
||
myJobManagerDET.Shutdown();
|
||
}
|
||
|
||
CloseCC24();
|
||
|
||
if (myJobManagerDET == null)
|
||
System.Environment.Exit(0);
|
||
}
|
||
catch
|
||
{
|
||
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 InitializeCamerOCR()
|
||
{
|
||
try
|
||
{
|
||
camOCROpened = false;
|
||
List<IDeviceInfo> deviceList = Enumerator.EnumerateDevices(); //发现设备,搜索所有大华相机
|
||
m_dev_cam_ocr = Enumerator.GetDeviceByKey("Machine Vision:CK21686DAK00001");//通过"设备厂商名:设备序列号"获取
|
||
if (m_dev_cam_ocr == null)
|
||
{
|
||
log.Error("未发现OCR相机,请检查相机连接");
|
||
return;
|
||
}
|
||
m_dev_cam_ocr.CameraOpened += m_dev_cam_ocr_CameraOpened;
|
||
m_dev_cam_ocr.CameraClosed += m_dev_cam_ocr_CameraClosed;
|
||
m_dev_cam_ocr.ConnectionLost += m_dev_cam_ocr_ConnectionLost;
|
||
|
||
if (!m_dev_cam_ocr.Open())
|
||
{
|
||
MessageBox.Show("OCR相机打开失败");
|
||
}
|
||
// 设置图像格式
|
||
using (IEnumParameter p = m_dev_cam_ocr.ParameterCollection[ParametrizeNameSet.ImagePixelFormat])
|
||
{
|
||
p.SetValue("BayerRG8");
|
||
}
|
||
|
||
// 设置曝光
|
||
using (IFloatParameter p = m_dev_cam_ocr.ParameterCollection[ParametrizeNameSet.ExposureTime])
|
||
{
|
||
p.SetValue(500000);
|
||
}
|
||
// 设置增益
|
||
|
||
using (IFloatParameter p = m_dev_cam_ocr.ParameterCollection[ParametrizeNameSet.GainRaw])
|
||
{
|
||
p.SetValue(2.5);
|
||
}
|
||
using (IEnumParameter p = m_dev_cam_ocr.ParameterCollection[ParametrizeNameSet.AcquisitionMode])
|
||
{
|
||
p.SetValue("Continuous");
|
||
}
|
||
using (IEnumParameter p = m_dev_cam_ocr.ParameterCollection[ParametrizeNameSet.TriggerMode])
|
||
{
|
||
p.SetValue("On");
|
||
}
|
||
|
||
m_dev_cam_ocr.StreamGrabber.ImageGrabbed += StreamGrabber_ImageGrabbed_OCR;
|
||
m_dev_cam_ocr.StreamGrabber.GrabStarted += StreamGrabber_GrabStarted_OCR;
|
||
// 打开Software Trigger
|
||
m_dev_cam_ocr.TriggerSet.Open(TriggerSourceEnum.Software);
|
||
if (!m_dev_cam_ocr.GrabUsingGrabLoopThread())
|
||
{
|
||
// 开启采集失败
|
||
log.Error("开启采集失败");
|
||
return;
|
||
}
|
||
camOCROpened = true;
|
||
log.Info("OCR相机加载完毕");
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
camOCROpened = false;
|
||
log.Error("OCR相机加载失败:" + ex.Message);
|
||
m_dev_cam_ocr = null;
|
||
}
|
||
}
|
||
private bool camOCROpened = false;
|
||
private bool camDETOpened = false;
|
||
#endregion
|
||
|
||
#region 相机1事件响应
|
||
|
||
void m_dev_cam_ocr_ConnectionLost(object sender, EventArgs e)
|
||
{
|
||
log.Error(m_dev_cam_ocr.DeviceInfo.Key + "OCR相机断线");
|
||
}
|
||
|
||
void m_dev_cam_ocr_CameraClosed(object sender, EventArgs e)
|
||
{
|
||
log.Error(m_dev_cam_ocr.DeviceInfo.Key + "OCR相机关闭");
|
||
}
|
||
|
||
void m_dev_cam_ocr_CameraOpened(object sender, EventArgs e)
|
||
{
|
||
|
||
}
|
||
|
||
void StreamGrabber_GrabStarted_OCR(object sender, EventArgs e)
|
||
{
|
||
log.Info("OCR相机启动码流");
|
||
}
|
||
|
||
/// <summary>
|
||
/// 拍照完成后触发
|
||
/// </summary>
|
||
/// <param name="sender"></param>
|
||
/// <param name="e"></param>
|
||
private void StreamGrabber_ImageGrabbed_OCR(object sender, GrabbedEventArgs e)
|
||
{
|
||
try
|
||
{
|
||
OCRResult(e.GrabResult.ToBitmap(true));
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
log.Error(ex.ToString());
|
||
}
|
||
}
|
||
#endregion
|
||
|
||
#region 相机2 定义为定位相机
|
||
private void InitializeCamerDET()
|
||
{
|
||
try
|
||
{
|
||
camDETOpened = false;
|
||
List<IDeviceInfo> deviceList = Enumerator.EnumerateDevices(); //发现设备,搜索所有大华相机
|
||
|
||
m_dev_cam_det = Enumerator.GetDeviceByKey("Machine Vision:BK27185BAK00038");//通过"设备厂商名:设备序列号"获取
|
||
if (m_dev_cam_det == null)
|
||
{
|
||
log.Error("未发现OCR相机,请检查相机连接");
|
||
return;
|
||
}
|
||
m_dev_cam_det.CameraOpened += m_dev_cam_det_CameraOpened;
|
||
m_dev_cam_det.CameraClosed += m_dev_cam_det_CameraClosed;
|
||
m_dev_cam_det.ConnectionLost += m_dev_cam_det_ConnectionLost;
|
||
|
||
if (!m_dev_cam_det.Open())
|
||
{
|
||
MessageBox.Show("定位相机打开失败");
|
||
}
|
||
// 设置图像格式
|
||
using (IEnumParameter p = m_dev_cam_det.ParameterCollection[ParametrizeNameSet.ImagePixelFormat])
|
||
{
|
||
p.SetValue("Mono");
|
||
}
|
||
|
||
// 设置曝光
|
||
using (IFloatParameter p = m_dev_cam_det.ParameterCollection[ParametrizeNameSet.ExposureTime])
|
||
{
|
||
p.SetValue(30000);
|
||
}
|
||
// 设置增益
|
||
using (IFloatParameter p = m_dev_cam_det.ParameterCollection[ParametrizeNameSet.GainRaw])
|
||
{
|
||
p.SetValue(1.0);
|
||
}
|
||
using (IEnumParameter p = m_dev_cam_det.ParameterCollection[ParametrizeNameSet.AcquisitionMode])
|
||
{
|
||
p.SetValue("Continuous");
|
||
}
|
||
using (IEnumParameter p = m_dev_cam_det.ParameterCollection[ParametrizeNameSet.TriggerMode])
|
||
{
|
||
p.SetValue("On");
|
||
}
|
||
m_dev_cam_det.StreamGrabber.ImageGrabbed += StreamGrabber_ImageGrabbed_DET;
|
||
m_dev_cam_det.StreamGrabber.GrabStarted += StreamGrabber_GrabStarted_DET;
|
||
// 打开Software Trigger
|
||
// Set Software Trigger
|
||
m_dev_cam_det.TriggerSet.Open(TriggerSourceEnum.Software);
|
||
if (!m_dev_cam_det.GrabUsingGrabLoopThread())
|
||
{
|
||
// 开启采集失败
|
||
log.Error("开启采集失败");
|
||
return;
|
||
}
|
||
camDETOpened = true;
|
||
log.Info("定位相机加载完毕");
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
camDETOpened = false;
|
||
log.Error("定位相机加载失败:" + ex.Message);
|
||
m_dev_cam_det = null;
|
||
}
|
||
|
||
}
|
||
#endregion
|
||
|
||
#region 相机2事件响应
|
||
|
||
void m_dev_cam_det_ConnectionLost(object sender, EventArgs e)
|
||
{
|
||
log.Error(m_dev_cam_det.DeviceInfo.Key + "定位相机断线");
|
||
}
|
||
|
||
void m_dev_cam_det_CameraClosed(object sender, EventArgs e)
|
||
{
|
||
log.Error(m_dev_cam_det.DeviceInfo.Key + "定位相机关闭");
|
||
}
|
||
|
||
void m_dev_cam_det_CameraOpened(object sender, EventArgs e)
|
||
{
|
||
|
||
}
|
||
|
||
void StreamGrabber_GrabStarted_DET(object sender, EventArgs e)
|
||
{
|
||
log.Info("定位相机启动码流");
|
||
}
|
||
|
||
/// <summary>
|
||
/// 拍照完成后触发
|
||
/// </summary>
|
||
/// <param name="sender"></param>
|
||
/// <param name="e"></param>
|
||
private void StreamGrabber_ImageGrabbed_DET(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 = myJobDET.VisionTool as CogToolGroup;
|
||
CogToolBlock myTB = myTG.Tools["CogToolBlock1"] as CogToolBlock;
|
||
CogImageConvertTool cogImageConvert = myTB.Tools["CogImageConvertTool1"] as CogImageConvertTool;
|
||
|
||
cogImageConvert.InputImage = cogimage;
|
||
//运行jobmanager
|
||
myJobManagerDET.Run();
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
EnableStartDetect();
|
||
log.Error(ex.ToString());
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
private void EnableStartDetect()
|
||
{
|
||
if (InvokeRequired)
|
||
{
|
||
BeginInvoke(new Action(EnableStartDetect));
|
||
return;
|
||
}
|
||
btn_StarDet_manual.Enabled = true;
|
||
btn_StarDet_manual.BackColor = Color.LimeGreen;
|
||
button2.Enabled = true;
|
||
button2.BackColor = Color.LimeGreen;
|
||
button1.Enabled = false;
|
||
button1.BackColor = Color.LightGray;
|
||
}
|
||
|
||
#region 相机关闭
|
||
void ClossCam()
|
||
{
|
||
//注销相机事件
|
||
if (m_dev_cam_ocr != null)
|
||
{
|
||
m_dev_cam_ocr.CameraOpened -= m_dev_cam_ocr_CameraOpened;
|
||
m_dev_cam_ocr.CameraClosed -= m_dev_cam_ocr_CameraClosed;
|
||
m_dev_cam_ocr.ConnectionLost -= m_dev_cam_ocr_ConnectionLost;
|
||
m_dev_cam_ocr.ShutdownGrab();
|
||
m_dev_cam_ocr.Dispose();
|
||
m_dev_cam_ocr = null;
|
||
}
|
||
if (m_dev_cam_det != null)
|
||
{
|
||
m_dev_cam_det.CameraOpened -= m_dev_cam_det_CameraOpened;
|
||
m_dev_cam_det.CameraClosed -= m_dev_cam_det_CameraClosed;
|
||
m_dev_cam_det.ConnectionLost -= m_dev_cam_det_ConnectionLost;
|
||
m_dev_cam_det.ShutdownGrab();
|
||
m_dev_cam_det.Dispose();
|
||
m_dev_cam_det = null;
|
||
}
|
||
}
|
||
#endregion
|
||
#endregion
|
||
|
||
#region OCR模型参数初始化
|
||
private void InitializePaddleOCR()
|
||
{
|
||
try
|
||
{
|
||
//模型初始化
|
||
OCRModelConfig config = null;
|
||
//初始化OCR
|
||
Engine = new PaddleOCREngine(config, "");
|
||
log.Info("OCR模型初始化完成");
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
log.Error(ex.Message + ex.StackTrace);
|
||
}
|
||
}
|
||
|
||
#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)
|
||
{
|
||
log.Info("PC断开PLC连接,只可进行本地操作。");
|
||
check_Autorun.BackgroundImage = Image.FromFile(Application.StartupPath + "\\logo_image\\OFF.png");
|
||
panel_Manual.Visible = true;
|
||
btn_StarDet_manual.Enabled = false;
|
||
btn_StarDet_manual.BackColor = Color.LightGray;
|
||
ttls_PCLStatusShow.Visible = false;
|
||
}
|
||
else if (!check_Autorun.Checked)
|
||
{
|
||
log.Info("PC加载PLC已完成");
|
||
check_Autorun.BackgroundImage = Image.FromFile(Application.StartupPath + "\\logo_image\\ON.png");
|
||
panel_Manual.Visible = false;
|
||
if (orderLoaded)
|
||
{
|
||
btn_StarDet_manual.Enabled = true;
|
||
btn_StarDet_manual.BackColor = Color.LimeGreen;
|
||
}
|
||
ttls_PCLStatusShow.Visible = true;
|
||
}
|
||
}
|
||
private bool orderLoaded = false;
|
||
private Dictionary<int, List<string>> ocrTextRequest = new Dictionary<int, List<string>>();
|
||
private Dictionary<int, string> ocrTextDesign = new Dictionary<int, string>();
|
||
private Dictionary<string, bool> ocrTextResult = new Dictionary<string, bool>();
|
||
/// <summary>
|
||
/// 此按钮事件主要是获取excel表格内的数据
|
||
/// 包括定位偏移量,需要验证的字符
|
||
/// </summary>
|
||
/// <param name="sender"></param>
|
||
/// <param name="e"></param>
|
||
private void btn_OrderNum_Click(object sender, EventArgs e)
|
||
{
|
||
try
|
||
{
|
||
button1.Enabled = false;
|
||
orderLoaded = false;
|
||
btn_StarDet_manual.Enabled = false;
|
||
btn_StarDet_manual.BackColor = Color.LightGray;
|
||
button2.Enabled = false;
|
||
button2.BackColor = Color.LightGray;
|
||
listBox1.Items.Clear();
|
||
ocrTextRequest.Clear();
|
||
ocrTextDesign.Clear();
|
||
ClearData();
|
||
ClearDataShow();
|
||
Invoke(new Action(() =>
|
||
{
|
||
lbl_L1_verOcrRs.Text = "未启用";
|
||
lbl_L1_verOcrRs.BackColor = Color.Gray;
|
||
lbl_L2_verOcrRs.Text = "未启用";
|
||
lbl_L2_verOcrRs.BackColor = Color.Gray;
|
||
lbl_L3_verOcrRs.Text = "未启用";
|
||
lbl_L3_verOcrRs.BackColor = Color.Gray;
|
||
lbl_L4_verOcrRs.Text = "未启用";
|
||
lbl_L4_verOcrRs.BackColor = Color.Gray;
|
||
lbl_L5_verOcrRs.Text = "未启用";
|
||
lbl_L5_verOcrRs.BackColor = Color.Gray;
|
||
lbl_L6_verOcrRs.Text = "未启用";
|
||
lbl_L6_verOcrRs.BackColor = Color.Gray;
|
||
lbl_L7_verOcrRs.Text = "未启用";
|
||
lbl_L7_verOcrRs.BackColor = Color.Gray;
|
||
lbl_L8_verOcrRs.Text = "未启用";
|
||
lbl_L8_verOcrRs.BackColor = Color.Gray;
|
||
lbl_L9_verOcrRs.Text = "未启用";
|
||
lbl_L9_verOcrRs.BackColor = Color.Gray;
|
||
}));
|
||
btn_OrderNum.Enabled = false;
|
||
btn_OrderNum.BackColor = Color.LightGray;
|
||
//通过订单号获取表格中需要的值
|
||
string order = txt_OrderNum.Text;
|
||
if (string.IsNullOrEmpty(order))
|
||
{
|
||
log.Warn("订单号为空,请输入订单号。");
|
||
btn_OrderNum.Enabled = true;
|
||
btn_OrderNum.BackColor = Color.DeepSkyBlue;
|
||
return;
|
||
}
|
||
|
||
log.Info("当前订单号为:" + order);
|
||
config = ExcelHelper.ReadOCROrder(execlFileName, order);
|
||
if (config.ParseQSV)
|
||
{
|
||
lbl_QSV.Text = config.QSV;
|
||
log.Info("当前订单QSV:" + config.QSV);
|
||
log.Info("当前订单Number Of Lanes:" + config.NumberOfLanes);
|
||
lbl_NO.Text = config.NumberOfLanes.ToString();
|
||
|
||
var result = config.OCRDesign
|
||
.GroupBy(kvp => kvp.Value, kvp => kvp.Key)
|
||
.ToDictionary(g => g.Key, g => g.ToList());
|
||
foreach (var kvp in result)
|
||
{
|
||
listBox1.Items.Add(string.Join(",", kvp.Value));
|
||
listBox1.Items.Add(string.Join(",", config.OCRRequest[kvp.Value[0]]));
|
||
}
|
||
}
|
||
else
|
||
{
|
||
log.Debug("QSV未找到,请检查订单号是否正确");
|
||
btn_OrderNum.Enabled = true;
|
||
btn_OrderNum.BackColor = Color.DeepSkyBlue;
|
||
return;
|
||
}
|
||
if (config.ParseProduct)
|
||
{
|
||
lbl_ProductStandard.Text = config.ProductStandard;
|
||
log.Info("当前订单产品编号:" + config.ProductStandard);
|
||
lbl_width.Text = config.Width.ToString();
|
||
log.Info("当前订单幅宽:" + config.Width);
|
||
lbl_height.Text = config.Height.ToString();
|
||
log.Info("当前订单幅高:" + config.Height);
|
||
lbl_Gradient.Text = config.Gradient.ToString();
|
||
log.Info("当前订单梯度:" + config.Gradient);
|
||
}
|
||
else
|
||
{
|
||
log.Debug("ProductStandard未找到,请检查订单号是否正确");
|
||
btn_OrderNum.Enabled = true;
|
||
btn_OrderNum.BackColor = Color.DeepSkyBlue;
|
||
return;
|
||
}
|
||
if (config.ParseArrange)
|
||
{
|
||
lbl_DistX.Text = config.DistX.ToString();
|
||
log.Info("当前订单X偏移:" + config.DistX);
|
||
lbl_DistY.Text = config.DistY.ToString();
|
||
log.Info("当前订单Y偏移:" + config.DistY);
|
||
log.Info("当前排布方式:" + config.ColorArray);
|
||
log.Info("单行最大数量:" + config.ColorMax.ToString());
|
||
}
|
||
else
|
||
{
|
||
log.Debug("DistX,DistY未找到,请检查订单号是否正确");
|
||
btn_OrderNum.Enabled = true;
|
||
btn_OrderNum.BackColor = Color.DeepSkyBlue;
|
||
return;
|
||
}
|
||
log.Info("相关数据已获取完成,且已显示在界面中,请查看。");
|
||
|
||
//判断当前Lans决定结果显示数量
|
||
InitLableColumn();
|
||
|
||
btn_OrderNum.Enabled = true;
|
||
btn_OrderNum.BackColor = Color.DeepSkyBlue;
|
||
orderLoaded = true;
|
||
btn_StarDet_manual.Enabled = true;
|
||
btn_StarDet_manual.BackColor = Color.LimeGreen;
|
||
button2.Enabled = true;
|
||
button2.BackColor = Color.LimeGreen;
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
log.Error("数据解析错误:" + ex.Message);
|
||
btn_OrderNum.Enabled = true;
|
||
btn_OrderNum.BackColor = Color.DeepSkyBlue;
|
||
}
|
||
}
|
||
private void InitLableColumn()
|
||
{
|
||
switch (config.NumberOfLanes)
|
||
{
|
||
case 1:
|
||
Invoke(new Action(() =>
|
||
{
|
||
lbl_L1_verOcrRs.Text = "启用";
|
||
lbl_L1_verOcrRs.BackColor = Color.Yellow;
|
||
}));
|
||
break;
|
||
case 2:
|
||
Invoke(new Action(() =>
|
||
{
|
||
lbl_L1_verOcrRs.Text = "启用";
|
||
lbl_L1_verOcrRs.BackColor = Color.Yellow;
|
||
lbl_L2_verOcrRs.Text = "启用";
|
||
lbl_L2_verOcrRs.BackColor = Color.Yellow;
|
||
}));
|
||
break;
|
||
case 3:
|
||
Invoke(new Action(() =>
|
||
{
|
||
lbl_L1_verOcrRs.Text = "启用";
|
||
lbl_L1_verOcrRs.BackColor = Color.Yellow;
|
||
lbl_L2_verOcrRs.Text = "启用";
|
||
lbl_L2_verOcrRs.BackColor = Color.Yellow;
|
||
lbl_L3_verOcrRs.Text = "启用";
|
||
lbl_L3_verOcrRs.BackColor = Color.Yellow;
|
||
}));
|
||
break;
|
||
case 4:
|
||
Invoke(new Action(() =>
|
||
{
|
||
lbl_L1_verOcrRs.Text = "启用";
|
||
lbl_L1_verOcrRs.BackColor = Color.Yellow;
|
||
lbl_L2_verOcrRs.Text = "启用";
|
||
lbl_L2_verOcrRs.BackColor = Color.Yellow;
|
||
lbl_L3_verOcrRs.Text = "启用";
|
||
lbl_L3_verOcrRs.BackColor = Color.Yellow;
|
||
lbl_L4_verOcrRs.Text = "启用";
|
||
lbl_L4_verOcrRs.BackColor = Color.Yellow;
|
||
}));
|
||
break;
|
||
case 5:
|
||
Invoke(new Action(() =>
|
||
{
|
||
lbl_L1_verOcrRs.Text = "启用";
|
||
lbl_L1_verOcrRs.BackColor = Color.Yellow;
|
||
lbl_L2_verOcrRs.Text = "启用";
|
||
lbl_L2_verOcrRs.BackColor = Color.Yellow;
|
||
lbl_L3_verOcrRs.Text = "启用";
|
||
lbl_L3_verOcrRs.BackColor = Color.Yellow;
|
||
lbl_L4_verOcrRs.Text = "启用";
|
||
lbl_L4_verOcrRs.BackColor = Color.Yellow;
|
||
lbl_L5_verOcrRs.Text = "启用";
|
||
lbl_L5_verOcrRs.BackColor = Color.Yellow;
|
||
}));
|
||
break;
|
||
case 6:
|
||
Invoke(new Action(() =>
|
||
{
|
||
lbl_L1_verOcrRs.Text = "启用";
|
||
lbl_L1_verOcrRs.BackColor = Color.Yellow;
|
||
lbl_L2_verOcrRs.Text = "启用";
|
||
lbl_L2_verOcrRs.BackColor = Color.Yellow;
|
||
lbl_L3_verOcrRs.Text = "启用";
|
||
lbl_L3_verOcrRs.BackColor = Color.Yellow;
|
||
lbl_L4_verOcrRs.Text = "启用";
|
||
lbl_L4_verOcrRs.BackColor = Color.Yellow;
|
||
lbl_L5_verOcrRs.Text = "启用";
|
||
lbl_L5_verOcrRs.BackColor = Color.Yellow;
|
||
lbl_L6_verOcrRs.Text = "启用";
|
||
lbl_L6_verOcrRs.BackColor = Color.Yellow;
|
||
|
||
}));
|
||
break;
|
||
case 7:
|
||
Invoke(new Action(() =>
|
||
{
|
||
lbl_L1_verOcrRs.Text = "启用";
|
||
lbl_L1_verOcrRs.BackColor = Color.Yellow;
|
||
lbl_L2_verOcrRs.Text = "启用";
|
||
lbl_L2_verOcrRs.BackColor = Color.Yellow;
|
||
lbl_L3_verOcrRs.Text = "启用";
|
||
lbl_L3_verOcrRs.BackColor = Color.Yellow;
|
||
lbl_L4_verOcrRs.Text = "启用";
|
||
lbl_L4_verOcrRs.BackColor = Color.Yellow;
|
||
lbl_L5_verOcrRs.Text = "启用";
|
||
lbl_L5_verOcrRs.BackColor = Color.Yellow;
|
||
lbl_L6_verOcrRs.Text = "启用";
|
||
lbl_L6_verOcrRs.BackColor = Color.Yellow;
|
||
lbl_L7_verOcrRs.Text = "启用";
|
||
lbl_L7_verOcrRs.BackColor = Color.Yellow;
|
||
}));
|
||
break;
|
||
case 8:
|
||
Invoke(new Action(() =>
|
||
{
|
||
lbl_L1_verOcrRs.Text = "启用";
|
||
lbl_L1_verOcrRs.BackColor = Color.Yellow;
|
||
lbl_L2_verOcrRs.Text = "启用";
|
||
lbl_L2_verOcrRs.BackColor = Color.Yellow;
|
||
lbl_L3_verOcrRs.Text = "启用";
|
||
lbl_L3_verOcrRs.BackColor = Color.Yellow;
|
||
lbl_L4_verOcrRs.Text = "启用";
|
||
lbl_L4_verOcrRs.BackColor = Color.Yellow;
|
||
lbl_L5_verOcrRs.Text = "启用";
|
||
lbl_L5_verOcrRs.BackColor = Color.Yellow;
|
||
lbl_L6_verOcrRs.Text = "启用";
|
||
lbl_L6_verOcrRs.BackColor = Color.Yellow;
|
||
lbl_L7_verOcrRs.Text = "启用";
|
||
lbl_L7_verOcrRs.BackColor = Color.Yellow;
|
||
lbl_L8_verOcrRs.Text = "启用";
|
||
lbl_L8_verOcrRs.BackColor = Color.Yellow;
|
||
}));
|
||
break;
|
||
case 9:
|
||
Invoke(new Action(() =>
|
||
{
|
||
lbl_L1_verOcrRs.Text = "启用";
|
||
lbl_L1_verOcrRs.BackColor = Color.Yellow;
|
||
lbl_L2_verOcrRs.Text = "启用";
|
||
lbl_L2_verOcrRs.BackColor = Color.Yellow;
|
||
lbl_L3_verOcrRs.Text = "启用";
|
||
lbl_L3_verOcrRs.BackColor = Color.Yellow;
|
||
lbl_L4_verOcrRs.Text = "启用";
|
||
lbl_L4_verOcrRs.BackColor = Color.Yellow;
|
||
lbl_L5_verOcrRs.Text = "启用";
|
||
lbl_L5_verOcrRs.BackColor = Color.Yellow;
|
||
lbl_L6_verOcrRs.Text = "启用";
|
||
lbl_L6_verOcrRs.BackColor = Color.Yellow;
|
||
lbl_L7_verOcrRs.Text = "启用";
|
||
lbl_L7_verOcrRs.BackColor = Color.Yellow;
|
||
lbl_L8_verOcrRs.Text = "启用";
|
||
lbl_L8_verOcrRs.BackColor = Color.Yellow;
|
||
lbl_L9_verOcrRs.Text = "启用";
|
||
lbl_L9_verOcrRs.BackColor = Color.Yellow;
|
||
}));
|
||
break;
|
||
}
|
||
}
|
||
/// <summary>
|
||
/// 手动ocr
|
||
/// </summary>
|
||
/// <param name="sender"></param>
|
||
/// <param name="e"></param>
|
||
private void btn_manualOcr_Click(object sender, EventArgs e)
|
||
{
|
||
m_dev_cam_ocr?.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_cam_det?.ExecuteSoftwareTrigger();
|
||
log.Info("手动触发定位");
|
||
}
|
||
private bool autorunFlag = false;
|
||
private double m_textWidth = 0;
|
||
private DateTime m_startTime = DateTime.Now;
|
||
private void btn_StarDet_manual_Click(object sender, EventArgs e)
|
||
{
|
||
if (camOCROpened == false || camDETOpened == false)
|
||
{
|
||
MessageBox.Show("相机未打开,无法进行检测,请检查相机连接及状态!");
|
||
return;
|
||
}
|
||
|
||
if (PlcContinueFlag == false)
|
||
{
|
||
MessageBox.Show("PLC未处于运行状态,无法进行检测,请检查PLC连接及状态!");
|
||
return;
|
||
}
|
||
|
||
if (MessageBox.Show("确认OCR相机处于零点位置?", "提示", MessageBoxButtons.YesNo) == DialogResult.No)
|
||
{
|
||
return;
|
||
}
|
||
|
||
if (orderLoaded == false)
|
||
{
|
||
MessageBox.Show("未获取正确的订单编号!");
|
||
return;
|
||
}
|
||
|
||
InitLableColumn();
|
||
|
||
m_GotoZero = false;
|
||
m_startTime = DateTime.Now;
|
||
m_textWidth = 18 - (config.NumberOfLanes - 5);
|
||
//m_textWidth = Convert.ToDouble(textBox1.Text);
|
||
ocrAcc.Clear();
|
||
autorunFlag = check_Autorun.Checked;
|
||
btn_StarDet_manual.Enabled = false;
|
||
button2.Enabled = false;
|
||
button1.Enabled = true;
|
||
btn_StarDet_manual.BackColor = Color.LightGray;
|
||
button2.BackColor = Color.LightGray;
|
||
button1.BackColor = Color.LimeGreen;
|
||
m_dev_cam_det?.ExecuteSoftwareTrigger();
|
||
list_Log.Clear();
|
||
log.Info("手动触发开始");
|
||
m_BeginOCR = true;
|
||
}
|
||
private bool m_BeginOCR = false;
|
||
private List<string> ExecelGetOcrText(string design, string layer)
|
||
{
|
||
List<string> result = new List<string>();
|
||
string[] ll = layer.Replace("[", "").Replace("]", "").Split(',');
|
||
for (int i = 0; i < ll.Length; i++)
|
||
{
|
||
ll[i] = ll[i].Replace(" ", "");
|
||
string[] str = ll[i].Split('-');
|
||
if (str.Length < 2)
|
||
continue;
|
||
result.Add(design + str[1] + str[0]);
|
||
}
|
||
return result;
|
||
}
|
||
/// <summary>
|
||
/// 清空上次订单数据
|
||
/// </summary>
|
||
void ClearData()
|
||
{
|
||
config = new OrderConfig();
|
||
}
|
||
/// <summary>
|
||
/// 清空上次订单显示区
|
||
/// </summary>
|
||
void ClearDataShow()
|
||
{
|
||
lbl_QSV.Text = "";
|
||
lbl_NO.Text = "";
|
||
lbl_ProductStandard.Text = "";
|
||
lbl_width.Text = "";
|
||
lbl_Gradient.Text = "";
|
||
lbl_DistX.Text = "";
|
||
lbl_DistY.Text = "";
|
||
}
|
||
|
||
private void txt_OrderNum_KeyDown(object sender, KeyEventArgs e)
|
||
{
|
||
if (e.KeyCode == Keys.Enter)
|
||
{
|
||
btn_OrderNum_Click(sender, e);
|
||
}
|
||
}
|
||
#endregion
|
||
|
||
#region OCR相机拍照触发处理函数
|
||
/// <summary>
|
||
/// OCR相机拍照信号过来需要进行的操作
|
||
/// </summary>
|
||
/// <param name="sender"></param>
|
||
/// <param name="e"></param>
|
||
private void OcrCamTriger()
|
||
{
|
||
try
|
||
{
|
||
log.Info("PLC触发OCR相机,正在拍照计算...");
|
||
m_dev_cam_ocr?.ExecuteSoftwareTrigger();
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
log.Error(ex.Message);
|
||
}
|
||
}
|
||
#endregion
|
||
|
||
#region 结果处理
|
||
|
||
#region 定位结果处理
|
||
public void DetResult(object sender, CogJobManagerActionEventArgs e)
|
||
{
|
||
try
|
||
{
|
||
if (InvokeRequired)
|
||
{
|
||
Invoke(new DetResultDelegate(DetResult), new object[] { sender, e });
|
||
return;
|
||
}
|
||
//清除上次的结果显示
|
||
lbl_XShow.Text = "";
|
||
lbl_YShow.Text = "";
|
||
lbl_RShow.Text = "";
|
||
|
||
CogToolGroup myTG = myJobDET.VisionTool as CogToolGroup;
|
||
CogToolBlock myTB = myTG.Tools["CogToolBlock1"] as CogToolBlock;
|
||
CogPMAlignTool myPMA = myTB.Tools["CogPMAlignTool2"] as CogPMAlignTool;
|
||
CogImageConvertTool myImage = myTB.Tools["CogImageConvertTool1"] as CogImageConvertTool;
|
||
|
||
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);
|
||
|
||
lbl_XShow.Text = xx.ToString();
|
||
lbl_YShow.Text = yy.ToString();
|
||
lbl_RShow.Text = rr.ToString();
|
||
log.Info($"x:{xx} y:{yy} degree:{rr}");
|
||
|
||
//画模型轮廓
|
||
CogCompositeShape shape = myPMA.Results[i].CreateResultGraphics(CogPMAlignResultGraphicConstants.MatchFeatures);
|
||
CogCompositeShape shape1 = myPMA.Results[i].CreateResultGraphics(CogPMAlignResultGraphicConstants.CoordinateAxes);
|
||
Location_Display.InteractiveGraphics.Add(shape, "", false);
|
||
Location_Display.InteractiveGraphics.Add(shape1, "", false);
|
||
//画定位的十字点
|
||
CPMARunStatus.DrawPointMarker(xx, yy, CogMisc.DegToRad(rr), CogColorConstants.Orange, Location_Display, ".");
|
||
log.Info("定位计算已完成。");
|
||
|
||
if (xx > 350)
|
||
{
|
||
log.Error("定位横向轴偏左,疑似倒数第二张图,请重新摆放后识别");
|
||
NoticePLCCompleteDet(DataConverter.FloatToByte(0.0f, true));
|
||
}
|
||
else
|
||
SendToPLC(xx, yy, rr);
|
||
}
|
||
else
|
||
{
|
||
EnableStartDetect();
|
||
log.Info("没有定位到K标志,请查看图像或相机是否正常");
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
EnableStartDetect();
|
||
log.Error(ex.Message + "未检测到K标志");
|
||
NoticePLCCompleteDet(DataConverter.FloatToByte(0.0f, true));
|
||
}
|
||
}
|
||
|
||
/// <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<TextPoint> paixu(List<TextPoint> points)
|
||
{
|
||
int rowDistance = 50;
|
||
List<List<TextPoint>> rows = new List<List<TextPoint>>();
|
||
|
||
for (int i = 0; i < points.Count; i++)
|
||
{
|
||
List<TextPoint> row = new List<TextPoint>();
|
||
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<TextPoint> sortedPoints = new List<TextPoint>();
|
||
|
||
foreach (List<TextPoint> row in rows)
|
||
{
|
||
row.Sort((x, y) => x.x - y.x);
|
||
foreach (TextPoint point in row)
|
||
{
|
||
if (!sortedPoints.Contains(point))
|
||
{
|
||
sortedPoints.Add(point);
|
||
}
|
||
}
|
||
}
|
||
|
||
return sortedPoints;
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region OCR结果处理
|
||
private void OCRResult(Bitmap bmp)
|
||
{
|
||
try
|
||
{
|
||
if (InvokeRequired)
|
||
{
|
||
Invoke(new OcrResultDelegate(OCRResult), new object[] { bmp });
|
||
return;
|
||
}
|
||
|
||
if (m_GotoZero)
|
||
{
|
||
log.Info("零点拍照");
|
||
NoticePLCCompleteOCR();
|
||
return;
|
||
}
|
||
|
||
ocrTextResult = new Dictionary<string, bool>();
|
||
if (!ocrTextRequest.ContainsKey(mMatchingStr))
|
||
{
|
||
log.Error($"未知列{mMatchingStr},舍弃图片");
|
||
NoticePLCCompleteOCR();
|
||
return;
|
||
}
|
||
foreach (var item in ocrTextRequest[mMatchingStr])
|
||
{
|
||
ocrTextResult[item] = false;
|
||
}
|
||
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 savePath = Path.Combine(SaveImageFileOCR + '\\' + strtimef, m_startTime.ToString("HHmmss"));
|
||
if (!Directory.Exists(savePath))
|
||
{
|
||
Directory.CreateDirectory(savePath);
|
||
}
|
||
string strTime = System.DateTime.Now.ToString("yyyyMMddHHmmss");
|
||
FileStream fs = new FileStream(savePath + '\\' + strTime + ".bmp", FileMode.Create);
|
||
BinaryWriter bw = new BinaryWriter(fs);
|
||
bw.Write(bytes, 0, bytes.Length);
|
||
bw.Close();
|
||
fs.Close();
|
||
log.Info("OCR存图已完成");
|
||
|
||
CutPicture(savePath + '\\' + strTime + ".bmp", 400 + 200 * (6 - config.ColorMax), 2000, 3400 + 200 * config.ColorMax, 1600);
|
||
if (Engine == null)
|
||
{
|
||
log.Error("Engine未初始化");
|
||
NoticePLCCompleteOCR();
|
||
return;
|
||
}
|
||
|
||
GetOCRImage getOCRImage = new GetOCRImage();
|
||
GetOCRImage.FileTimeInfo file = getOCRImage.GetLatesFileImageName(savePath, ".bmp");
|
||
if (file != null)
|
||
{
|
||
Mat bgr = Cv2.ImRead(file.FileName, ImreadModes.Color); // 读入 BGR
|
||
if (bgr.Empty())
|
||
{
|
||
log.Error("OCR图片转换失败");
|
||
NoticePLCCompleteOCR();
|
||
return;
|
||
}
|
||
bool matchOK = false;
|
||
OCRTextResult rgbResult = null;
|
||
List<PointF[]> pointRGB = null;
|
||
rgbResult = OCRBytes(bgr.ToBytes());
|
||
if (rgbResult == null)
|
||
{
|
||
log.Error("彩色通道,OCR字符识别失败");
|
||
NoticePLCCompleteOCR();
|
||
return;
|
||
}
|
||
txt_readOcrResultShow.Text = rgbResult.text;
|
||
log.Info("彩色通道字符读取结果:" + rgbResult.text);
|
||
matchOK = rgbResult.match;
|
||
pointRGB = rgbResult.points;
|
||
|
||
Mat hsv = null;
|
||
OCRTextResult hResult = null;
|
||
OCRTextResult sResult = null;
|
||
OCRTextResult vResult = null;
|
||
|
||
List<PointF[]> pointS = null;
|
||
List<PointF[]> pointH = null;
|
||
List<PointF[]> pointV = null;
|
||
if (!matchOK)
|
||
{
|
||
hsv = new Mat();
|
||
Cv2.CvtColor(bgr, hsv, ColorConversionCodes.BGR2HSV); // 1. 转 HSV
|
||
Mat[] channels = Cv2.Split(hsv); // 2. 拆通道
|
||
Mat h = channels[0]; // Hue 0-180
|
||
Mat s = channels[1]; // Saturation 0-255
|
||
Mat v = channels[2]; // Value 0-255
|
||
|
||
sResult = OCRBytes(s.ImEncode(".png"));
|
||
if (sResult == null)
|
||
{
|
||
log.Error("s通道,OCR字符识别失败");
|
||
NoticePLCCompleteOCR();
|
||
return;
|
||
}
|
||
txt_readOcrResultShow.Text = "\n" + sResult.text;
|
||
log.Info("s通道字符读取结果:" + sResult.text);
|
||
matchOK = sResult.match;
|
||
pointS = sResult.points;
|
||
|
||
if (!matchOK)
|
||
{
|
||
hResult = OCRBytes(h.ImEncode(".png"));
|
||
if (hResult == null)
|
||
{
|
||
log.Error("h通道,OCR字符识别失败");
|
||
NoticePLCCompleteOCR();
|
||
return;
|
||
}
|
||
txt_readOcrResultShow.Text += "\n" + hResult.text;
|
||
log.Info("h通道字符读取结果:" + hResult.text);
|
||
matchOK = hResult.match;
|
||
pointH = hResult.points;
|
||
}
|
||
if (!matchOK)
|
||
{
|
||
vResult = OCRBytes(v.ImEncode(".png"));
|
||
if (vResult == null)
|
||
{
|
||
log.Error("v通道,OCR字符识别失败");
|
||
NoticePLCCompleteOCR();
|
||
return;
|
||
}
|
||
txt_readOcrResultShow.Text += "\n" + vResult.text;
|
||
log.Info("v通道字符读取结果:" + vResult.text);
|
||
matchOK = vResult.match;
|
||
pointV = vResult.points;
|
||
}
|
||
}
|
||
|
||
byte[] ocrimagebyte = File.ReadAllBytes(file.FileName);
|
||
Bitmap Bmp = new Bitmap(new MemoryStream(ocrimagebyte));
|
||
if ((pointRGB != null && pointRGB.Count > 0) || (pointS != null && pointS.Count > 0) || (pointH != null && pointH.Count > 0) || (pointV != null && pointV.Count > 0))
|
||
{
|
||
using (Graphics g = Graphics.FromImage(Bmp))
|
||
{
|
||
if (pointRGB != null && pointRGB.Count > 0)
|
||
{
|
||
foreach (var item in pointRGB)
|
||
g.DrawPolygon(new Pen(Brushes.Red, 2), item.Select(x => new PointF() { X = x.X, Y = x.Y }).ToArray());
|
||
}
|
||
if (pointS != null && pointS.Count > 0)
|
||
{
|
||
foreach (var item in pointS)
|
||
g.DrawPolygon(new Pen(Brushes.Red, 2), item.Select(x => new PointF() { X = x.X, Y = x.Y }).ToArray());
|
||
}
|
||
if (pointH != null && pointH.Count > 0)
|
||
{
|
||
foreach (var item in pointH)
|
||
g.DrawPolygon(new Pen(Brushes.Red, 2), item.Select(x => new PointF() { X = x.X, Y = x.Y }).ToArray());
|
||
}
|
||
if (pointV != null && pointV.Count > 0)
|
||
{
|
||
foreach (var item in pointV)
|
||
g.DrawPolygon(new Pen(Brushes.Red, 2), item.Select(x => new PointF() { X = x.X, Y = x.Y }).ToArray());
|
||
}
|
||
}
|
||
int m1 = ocrTextResult.Count(x => x.Value);
|
||
log.Info($"OCR识别完成,匹配成功{m1}个字符,匹配失败{ocrTextResult.Count - m1}个字符");
|
||
ShowTheLansRs(mMatchingStr, (double)m1 / (double)ocrTextResult.Count);
|
||
}
|
||
else
|
||
{
|
||
ShowTheLansRs(mMatchingStr, 0);
|
||
log.Info("OCR识别完成,匹配失败");
|
||
}
|
||
Ocr_picBox.BackgroundImage = Bmp;
|
||
NoticePLCCompleteOCR();
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
log.Error(ex.Message + "未检测到字符");
|
||
NoticePLCCompleteOCR();
|
||
}
|
||
}
|
||
private void NoticePLCCompleteOCR()
|
||
{
|
||
if (autorunFlag == false)
|
||
{
|
||
byte[] datax = DataConverter.FloatToByte(0.0f, true);
|
||
cc24?.NotifyCamInspectionComplete(1, datax);
|
||
cc24?.NotifyCamAcqComplete(1);
|
||
}
|
||
}
|
||
private void NoticePLCCompleteDet(byte[] datax)
|
||
{
|
||
if (autorunFlag == false)
|
||
{
|
||
cc24?.NotifyCamInspectionComplete(0, datax);
|
||
cc24?.NotifyCamAcqComplete(0);
|
||
}
|
||
}
|
||
private OCRTextResult OCRBytes(byte[] ocrimagebyte)
|
||
{
|
||
try
|
||
{
|
||
OCRTextResult result = new OCRTextResult();
|
||
List<string> lastocr = new List<string>();
|
||
OCRResult ocrResult = Engine.DetectText(ocrimagebyte);
|
||
List<TextPoint> pointsList = new List<TextPoint>();
|
||
|
||
foreach (var item in ocrResult.TextBlocks)
|
||
{
|
||
if (item.Text.Contains(ocrTextDesign[mMatchingStr]))
|
||
{
|
||
result.points.Add(item.BoxPoints.Select(x => new PointF() { X = x.X, Y = x.Y }).ToArray());
|
||
pointsList.Add(new TextPoint(item.BoxPoints[0].X, item.BoxPoints[0].Y, item.Text));
|
||
}
|
||
}
|
||
|
||
List<TextPoint> paixujeguo = paixu(pointsList);
|
||
foreach (var it in paixujeguo)
|
||
{
|
||
lastocr.Add(it.txt);
|
||
}
|
||
result.text = GETOCR(lastocr, ocrTextDesign[mMatchingStr]);
|
||
|
||
var keysToUpdate = new List<string>();
|
||
foreach (var item in ocrTextResult)
|
||
{
|
||
if (result.text.Contains(item.Key))
|
||
keysToUpdate.Add(item.Key);
|
||
}
|
||
|
||
foreach (var item in keysToUpdate)
|
||
{
|
||
ocrTextResult[item] = true;
|
||
}
|
||
|
||
result.match = true;
|
||
foreach (var item in ocrTextResult)
|
||
{
|
||
if (!item.Value)
|
||
result.match = false;
|
||
}
|
||
return result;
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
log.Error(ex.Message + ex.StackTrace);
|
||
return null;
|
||
}
|
||
}
|
||
|
||
#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 pattern = @"" + design + "[A-Z0-9]{8}";
|
||
for (int i = 0; i < readOCR.Count; i++)
|
||
{
|
||
readOCR[i] = readOCR[i].Replace("_", "");
|
||
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 "未能匹配到对应字符请查看产品是否超标,或订单号是否正确";
|
||
}
|
||
}
|
||
private void button1_Click(object sender, EventArgs e)
|
||
{
|
||
btn_StarDet_manual.Enabled = true;
|
||
button1.Enabled = false;
|
||
button2.Enabled = true;
|
||
btn_StarDet_manual.BackColor = Color.LimeGreen;
|
||
button1.BackColor = Color.LightGray;
|
||
button2.BackColor = Color.LimeGreen;
|
||
NoticePLCCompleteOCR();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 将结果显示在对应状态栏
|
||
/// </summary>
|
||
/// <param name="mM">PLC给的当前在第几道拍照</param>
|
||
/// <param name="s">OCR字符相似度结果</param>
|
||
void ShowTheLansRs(int mM, double s)
|
||
{
|
||
int mMnum = Convert.ToInt32(mM);
|
||
switch (mMnum)
|
||
{
|
||
case 1:
|
||
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);
|
||
lbl_L1_verOcrRs.Text = s * 100 + "%";
|
||
log.Info("字符对比结果:当前第" + mMnum + "道的读取字符与验证字符相似度为" + s * 100 + "%");
|
||
break;
|
||
case 2:
|
||
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);
|
||
lbl_L2_verOcrRs.Text = s * 100 + "%";
|
||
log.Info("字符对比结果:当前第" + mMnum + "道的读取字符与验证字符相似度为" + s * 100 + "%");
|
||
break;
|
||
case 3:
|
||
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);
|
||
lbl_L3_verOcrRs.Text = s * 100 + "%";
|
||
log.Info("字符对比结果:当前第" + mMnum + "道的读取字符与验证字符相似度为" + s * 100 + "%");
|
||
break;
|
||
case 4:
|
||
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);
|
||
lbl_L4_verOcrRs.Text = s * 100 + "%";
|
||
log.Info("字符对比结果:当前第" + mMnum + "道的读取字符与验证字符相似度为" + s * 100 + "%");
|
||
break;
|
||
case 5:
|
||
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);
|
||
lbl_L5_verOcrRs.Text = s * 100 + "%";
|
||
log.Info("字符对比结果:当前第" + mMnum + "道的读取字符与验证字符相似度为" + s * 100 + "%");
|
||
break;
|
||
case 6:
|
||
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);
|
||
lbl_L6_verOcrRs.Text = s * 100 + "%";
|
||
log.Info("字符对比结果:当前第" + mMnum + "道的读取字符与验证字符相似度为" + s * 100 + "%");
|
||
break;
|
||
case 7:
|
||
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);
|
||
lbl_L7_verOcrRs.Text = s * 100 + "%";
|
||
log.Info("字符对比结果:当前第" + mMnum + "道的读取字符与验证字符相似度为" + s * 100 + "%");
|
||
break;
|
||
case 8:
|
||
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);
|
||
lbl_L8_verOcrRs.Text = s * 100 + "%";
|
||
log.Info("字符对比结果:当前第" + mMnum + "道的读取字符与验证字符相似度为" + s * 100 + "%");
|
||
break;
|
||
case 9:
|
||
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);
|
||
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);
|
||
|
||
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)
|
||
{
|
||
|
||
Invoke(new Action(() =>
|
||
{
|
||
if (isEnabled)
|
||
{
|
||
ttls_AcqEnableShow.Visible = true;
|
||
}
|
||
else
|
||
{
|
||
ttls_AcqEnableShow.Visible = false;
|
||
}
|
||
}));
|
||
}
|
||
|
||
private void CC24_NotifyCamAcqDisabled(int cameraIndex, bool isEnabled)
|
||
{
|
||
Invoke(new Action(() =>
|
||
{
|
||
if (isEnabled)
|
||
{
|
||
ttls_AcqEnableShow.Visible = true;
|
||
}
|
||
else
|
||
{
|
||
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 (m_BeginOCR == false && m_GotoZero == false)
|
||
{
|
||
NoticePLCCompleteOCR();
|
||
return;
|
||
}
|
||
|
||
if (m_GotoZero)
|
||
{
|
||
if (mMatchingStr == 2)
|
||
{
|
||
Thread.Sleep(3000);
|
||
EnableStartDetect();
|
||
return;
|
||
}
|
||
return;
|
||
}
|
||
|
||
if (config.NumberOfLanes + 1 == mMatchingStr)
|
||
{
|
||
Thread.Sleep(3000);
|
||
EnableStartDetect();
|
||
if (ocrAcc.Count == 0)
|
||
return;
|
||
if (ocrAcc.Min() < 0.95)
|
||
{
|
||
MessageBox.Show("当前检测中出现严重错误请注意!", Text, MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||
}
|
||
else if (ocrAcc.Min() > 0.95 & ocrAcc.Min() < 1)
|
||
{
|
||
MessageBox.Show("当前检测中出现可允许误差请注意!", Text, MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||
}
|
||
else
|
||
log.Info("当前检测合格,正常结束");
|
||
}
|
||
}
|
||
private bool m_GotoZero = false;
|
||
private void button2_Click(object sender, EventArgs e)
|
||
{
|
||
autorunFlag = check_Autorun.Checked;
|
||
if (check_Autorun.Checked == false)
|
||
{
|
||
button1.Enabled = true;
|
||
button1.BackColor = Color.LimeGreen;
|
||
btn_StarDet_manual.Enabled = false;
|
||
btn_StarDet_manual.BackColor = Color.LightGray;
|
||
m_GotoZero = true;
|
||
List<float> plcXY = new List<float>();
|
||
plcXY.Add(1);
|
||
plcXY.Add(0);
|
||
plcXY.Add(0);
|
||
NoticePLCCompleteDet(DataConverter.FloatToByte(plcXY, true));
|
||
log.Info("零点坐标已发送");
|
||
}
|
||
}
|
||
#endregion
|
||
|
||
#region 接收触发相机信号
|
||
void CC24_PlcTriggerCamAcqStart(object sender, CogNdmTriggerAcquisitionEventArgs e)
|
||
{
|
||
if (InvokeRequired)
|
||
{
|
||
Invoke(new CogNdmTriggerAcquisitionEventHandler(CC24_PlcTriggerCamAcqStart), new object[] { sender, e });
|
||
return;
|
||
}
|
||
try
|
||
{
|
||
if (e.CameraIndex == 1)
|
||
{
|
||
Ocr_picBox.BackgroundImage = null;
|
||
Thread.Sleep(1000);
|
||
OcrCamTriger();
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
log.Error($"Trigger AcqStart Error: {ex.Message}");
|
||
}
|
||
}
|
||
#endregion
|
||
|
||
#region 相机停止
|
||
private void CC24_PlcTriggerCamAcqStop(object sender, CogNdmTriggerAcquisitionStopEventArgs e)
|
||
{
|
||
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region 通讯状态发生改变
|
||
private void CC24_PlcConnectionStatusChanged(object sender, CogNdmProtocolStatusChangedEventArgs e)
|
||
{
|
||
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;
|
||
button2.Enabled = true;
|
||
button2.BackColor = Color.LimeGreen;
|
||
}
|
||
else if (e.ProtocolStatus != CogNdmConnectionStatusConstants.Connecting)
|
||
{
|
||
PlcContinueFlag = false;
|
||
log.Info("PLC已断开PC,请查看相关设备是否连接");
|
||
ttls_PCLStatusShow.Visible = false;
|
||
button2.Enabled = false;
|
||
button2.BackColor = Color.LightGray;
|
||
}
|
||
}
|
||
#endregion
|
||
|
||
#region 通讯发送坐标
|
||
private void SendToPLC(double x, double y, double r)
|
||
{
|
||
try
|
||
{
|
||
if (ocrTextRequest[1].Count == 0)
|
||
return;
|
||
|
||
double xx = x - (m_textWidth * config.ColorMax) / 2.0;
|
||
double yy = y;
|
||
double rr = r;
|
||
|
||
List<float> locationXY = new List<float>();
|
||
double ocrx = 0, ocry = 0;
|
||
locationXY.Add((float)config.NumberOfLanes);
|
||
int nol = Convert.ToInt32(config.NumberOfLanes);
|
||
log.Info("当前订单OCR区域共" + nol + "组:");
|
||
double degree = (rr * Math.PI) / 180;
|
||
for (int item = 0; item < nol; item++)
|
||
{
|
||
if (item == 0)
|
||
{
|
||
ocrx = xx - config.DistX * Math.Cos(degree) - config.DistY * Math.Sin(degree);
|
||
ocry = yy + config.DistY * Math.Cos(degree) - config.DistX * Math.Sin(degree);
|
||
}
|
||
else
|
||
{
|
||
ocrx = ocrx + config.Width * Math.Cos(degree) + config.Gradient * Math.Sin(degree);
|
||
ocry = ocry - config.Gradient * Math.Cos(degree) + config.Width * Math.Sin(degree);
|
||
}
|
||
|
||
log.Info("第" + (item + 1) + "组坐标为:X:" + ocrx + ",Y:" + ocry + "。");
|
||
if (ocrx < 0 || ocrx > 1600)
|
||
{
|
||
EnableStartDetect();
|
||
if (ocrx < 0)
|
||
log.Error("横向范围 0,1600!纸张向左移动一点");
|
||
else
|
||
log.Error("横向范围 0,1600!纸张向右移动一点");
|
||
NoticePLCCompleteDet(DataConverter.FloatToByte(0.0f, true));
|
||
return;
|
||
}
|
||
|
||
if (ocry < - 50)
|
||
{
|
||
ocrx = ocrx - config.Height * Math.Sin(degree);
|
||
ocry = ocry + config.Height * Math.Cos(degree);
|
||
log.Info("更新第" + (item + 1) + "组坐标为:X:" + ocrx + ",Y:" + ocry + "。");
|
||
}
|
||
else if (ocry > 400)
|
||
{
|
||
ocrx = ocrx + config.Height * Math.Sin(degree);
|
||
ocry = ocry - config.Height * Math.Cos(degree);
|
||
log.Info("更新第" + (item + 1) + "组坐标为:X:" + ocrx + ",Y:" + ocry + "。");
|
||
}
|
||
|
||
if (ocry < -50 || ocry > 400)
|
||
{
|
||
EnableStartDetect();
|
||
if (ocry < -50)
|
||
log.Error("纵向范围 -50,400!纸张向下移动一点");
|
||
else
|
||
log.Error("纵向范围 -50,400!纸张向上移动一点");
|
||
NoticePLCCompleteDet(DataConverter.FloatToByte(0.0f, true));
|
||
return;
|
||
}
|
||
locationXY.Add((float)ocrx);
|
||
locationXY.Add((float)ocry);
|
||
}
|
||
|
||
if (check_Autorun.Checked == false)
|
||
{
|
||
List<float> plcXY = new List<float>();
|
||
for (int i = 0; i < locationXY.Count; i++)
|
||
{
|
||
if (i == 0)
|
||
{
|
||
plcXY.Add(locationXY[i]);
|
||
}
|
||
else if (i % 2 == 1)
|
||
{
|
||
plcXY.Add(locationXY[locationXY.Count - i - 1]);
|
||
plcXY.Add(locationXY[locationXY.Count - i]);
|
||
}
|
||
}
|
||
NoticePLCCompleteDet(DataConverter.FloatToByte(plcXY, true));
|
||
log.Info("坐标已发送完成。");
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
EnableStartDetect();
|
||
log.Error(ex.Message + "未检测到K标志");
|
||
NoticePLCCompleteDet(DataConverter.FloatToByte(0.0f, true));
|
||
}
|
||
}
|
||
#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
|
||
}
|
||
}
|