add camera driver layer

This commit is contained in:
2025-12-26 14:54:32 +08:00
parent c6be81d1dd
commit d7ef283b9d
11 changed files with 324 additions and 469 deletions

View File

@@ -1,17 +1,4 @@
/************************
* 作者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 AVP.CRobot;
using Cognex.VisionPro;
using Cognex.VisionPro.Comm;
using Cognex.VisionPro.ImageProcessing;
@@ -37,10 +24,10 @@ using System.Threading;
using System.Threading.Tasks;
using System.Windows.Documents;
using System.Windows.Forms;
using ThridLibray;
using LibDataBase;
using LibReadTetraExcel;
using LibComm;
using LibCamera;
namespace TetraPackOCR
{
@@ -51,13 +38,11 @@ namespace TetraPackOCR
InitializeComponent();
LogInit();
}
#region
//创建字段log
ILog log = LogManager.GetLogger(typeof(Form1));
ICommPLC commPLC;
ICameraDriver cameraOCR, cameraDET;
/// <summary>
/// 声明一个PaddleOCR对象
/// </summary>
@@ -78,22 +63,13 @@ namespace TetraPackOCR
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>
@@ -103,9 +79,6 @@ namespace TetraPackOCR
{
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;
@@ -135,14 +108,10 @@ namespace TetraPackOCR
InitializeComm();
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;
@@ -177,7 +146,6 @@ namespace TetraPackOCR
log.Error(ex.Message);
}
}
/// <summary>
/// 窗体关闭
/// </summary>
@@ -185,7 +153,6 @@ namespace TetraPackOCR
/// <param name="e"></param>
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
try
{
ClossCam();
@@ -208,11 +175,8 @@ namespace TetraPackOCR
System.Environment.Exit(0);
}
}
#endregion
#region
private void LogInit()
{
try
@@ -229,230 +193,52 @@ namespace TetraPackOCR
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;
cameraOCR = new CameraDriver();
cameraOCR.OnCameraImage += CameraOCR_OnCameraImage;
cameraOCR.Initialize("Machine Vision:CK21686DAK00001", "BayerRG8", 500000, 2.5);
if (cameraOCR.IsOpened())
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相机断线");
else
log.Error("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)
private void CameraOCR_OnCameraImage(Bitmap bmp)
{
if (bmp == null)
return;
try
{
OCRResult(e.GrabResult.ToBitmap(true));
OCRResult(bmp);
}
catch (Exception ex)
{
log.Error(ex.ToString());
}
}
#endregion
#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;
}
cameraDET = new CameraDriver();
cameraDET.OnCameraImage += CameraDET_OnCameraImage;
cameraDET.Initialize("Machine Vision:BK27185BAK00038", "Mono", 30000, 1.0);
if (cameraDET.IsOpened())
log.Info("定位相机相机加载完毕");
else
log.Error("定位相机相机加载失败");
}
#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)
private void CameraDET_OnCameraImage(Bitmap bmp)
{
try
{
Bitmap bmp = null;
bmp = e.GrabResult.ToBitmap(true);
//Bitmap bmp = new Bitmap(cogimg.ToBitmap());
if (bmp == null)
return;
MemoryStream ms = new MemoryStream();
bmp.Save(ms, System.Drawing.Imaging.ImageFormat.Bmp);
byte[] bytes = ms.GetBuffer();
@@ -471,7 +257,6 @@ namespace TetraPackOCR
fs.Close();
log.Info("定位存图已完成");
CogImage8Grey cogimage = new CogImage8Grey(bmp);
//把图像给job中convertImagetool
@@ -489,9 +274,7 @@ namespace TetraPackOCR
log.Error(ex.ToString());
}
}
#endregion
private void EnableStartDetect()
{
if (InvokeRequired)
@@ -510,29 +293,11 @@ namespace TetraPackOCR
#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;
}
cameraDET?.Stop();
cameraOCR?.Stop();
}
#endregion
#endregion
#region OCR模型参数初始化
private void InitializePaddleOCR()
{
@@ -549,40 +314,8 @@ namespace TetraPackOCR
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>();
@@ -862,32 +595,11 @@ namespace TetraPackOCR
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)
if (cameraDET?.IsOpened() == false || cameraOCR?.IsOpened() == false)
{
MessageBox.Show("相机未打开,无法进行检测,请检查相机连接及状态!");
return;
@@ -916,14 +628,13 @@ namespace TetraPackOCR
m_startTime = DateTime.Now;
m_textWidth = 18 - (config.NumberOfLanes - 5);
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();
cameraDET.GrabImage();
list_Log.Clear();
log.Info("手动触发开始");
m_BeginOCR = true;
@@ -958,29 +669,7 @@ namespace TetraPackOCR
}
}
#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)
{
@@ -1029,7 +718,7 @@ namespace TetraPackOCR
if (xx > 350)
{
log.Error("定位横向轴偏左,疑似倒数第二张图,请重新摆放后识别");
NoticePLCCompleteDet(DataConverter.FloatToByte(0.0f, true));
NoticePLCCompleteDet(0.0f);
}
else
SendToPLC(xx, yy, rr);
@@ -1044,10 +733,9 @@ namespace TetraPackOCR
{
EnableStartDetect();
log.Error(ex.Message + "未检测到K标志");
NoticePLCCompleteDet(DataConverter.FloatToByte(0.0f, true));
NoticePLCCompleteDet(0.0f);
}
}
/// <summary>
/// 获取右下角定位标志坐标
/// </summary>
@@ -1101,7 +789,6 @@ namespace TetraPackOCR
return i;
}
#endregion
#region
List<TextPoint> paixu(List<TextPoint> points)
{
@@ -1139,9 +826,7 @@ namespace TetraPackOCR
return sortedPoints;
}
#endregion
#region OCR结果处理
private void OCRResult(Bitmap bmp)
{
@@ -1335,13 +1020,15 @@ namespace TetraPackOCR
}
private void NoticePLCCompleteOCR()
{
if (autorunFlag == false)
commPLC?.NoticeCamComplete(1, DataConverter.FloatToByte(0.0f, true));
commPLC?.NoticeCamComplete(1, 0.0f);
}
private void NoticePLCCompleteDet(byte[] datax)
private void NoticePLCCompleteDet(float data)
{
if (autorunFlag == false)
commPLC?.NoticeCamComplete(0, datax);
commPLC?.NoticeCamComplete(0, data);
}
private void NoticePLCCompleteDet(List<float> data)
{
commPLC?.NoticeCamComplete(0, data);
}
private OCRTextResult OCRBytes(byte[] ocrimagebyte)
{
@@ -1394,7 +1081,6 @@ namespace TetraPackOCR
return null;
}
}
#region
private void CutPicture(String picPath, int x, int y, int width, int height)
{
@@ -1427,9 +1113,6 @@ namespace TetraPackOCR
bmpCrop.Dispose();
}
#endregion
/// <summary>
/// 使用正则表达式提取结果
/// </summary>
@@ -1483,7 +1166,6 @@ namespace TetraPackOCR
button2.BackColor = Color.LimeGreen;
NoticePLCCompleteOCR();
}
/// <summary>
/// 将结果显示在对应状态栏
/// </summary>
@@ -1632,11 +1314,8 @@ namespace TetraPackOCR
}
}
#endregion
#endregion
#region
#region
void InitializeComm()
{
@@ -1655,7 +1334,6 @@ namespace TetraPackOCR
}
}
private void CommPLC_OnCameraStatus(int index, bool enable)
{
if (InvokeRequired)
@@ -1668,18 +1346,15 @@ namespace TetraPackOCR
else
ttls_AcqEnableShow.Visible = false;
}
private void CommPLC_OnDataReceived(byte[] data)
private void CommPLC_OnDataReceived(float data)
{
if (InvokeRequired)
{
BeginInvoke(new Action<byte[]>(CommPLC_OnDataReceived), data);
BeginInvoke(new Action<float>(CommPLC_OnDataReceived), data);
return;
}
float mMatchingStrf = DataConverter.ByteToFloat(data, true);
mMatchingStr = Convert.ToInt32(mMatchingStrf);
mMatchingStr = Convert.ToInt32(data);
log.Info("PC接收PLC数据数据内容" + mMatchingStr);
if (m_BeginOCR == false && m_GotoZero == false)
{
@@ -1716,7 +1391,6 @@ namespace TetraPackOCR
log.Info("当前检测合格,正常结束");
}
}
private void CommPLC_OnTrigCamera(int index)
{
if (InvokeRequired)
@@ -1730,7 +1404,8 @@ namespace TetraPackOCR
{
Ocr_picBox.BackgroundImage = null;
Thread.Sleep(1000);
OcrCamTriger();
log.Info("PLC触发OCR相机正在拍照计算...");
cameraOCR?.GrabImage();
}
}
catch (Exception ex)
@@ -1738,7 +1413,6 @@ namespace TetraPackOCR
log.Error($"Trigger AcqStart Error: {ex.Message}");
}
}
private void CommPLC_OnConnectStatus(bool connected)
{
if (InvokeRequired)
@@ -1764,27 +1438,21 @@ namespace TetraPackOCR
}
}
#endregion
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("零点坐标已发送");
}
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(plcXY);
log.Info("零点坐标已发送");
}
#region
private void SendToPLC(double x, double y, double r)
{
@@ -1824,7 +1492,7 @@ namespace TetraPackOCR
log.Error("横向范围 0,1600纸张向左移动一点");
else
log.Error("横向范围 0,1600纸张向右移动一点");
NoticePLCCompleteDet(DataConverter.FloatToByte(0.0f, true));
NoticePLCCompleteDet(0.0f);
return;
}
@@ -1848,41 +1516,37 @@ namespace TetraPackOCR
log.Error("纵向范围 -50,400纸张向下移动一点");
else
log.Error("纵向范围 -50,400纸张向上移动一点");
NoticePLCCompleteDet(DataConverter.FloatToByte(0.0f, true));
NoticePLCCompleteDet(0.0f);
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++)
{
List<float> plcXY = new List<float>();
for (int i = 0; i < locationXY.Count; i++)
if (i == 0)
{
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]);
}
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("坐标已发送完成。");
}
NoticePLCCompleteDet(plcXY);
log.Info("坐标已发送完成。");
}
catch (Exception ex)
{
EnableStartDetect();
log.Error(ex.Message + "未检测到K标志");
NoticePLCCompleteDet(DataConverter.FloatToByte(0.0f, true));
NoticePLCCompleteDet(0.0f);
}
}
#endregion
#region
private void StopComm()
{
@@ -1902,7 +1566,6 @@ namespace TetraPackOCR
}
}
#endregion
#endregion
}
}