firt commit

This commit is contained in:
xhm\HP 2024-05-31 10:14:57 +08:00
commit 3c72adc00f
27 changed files with 9095 additions and 0 deletions

190
.gitignore vendored Normal file
View File

@ -0,0 +1,190 @@
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
# User-specific files
*.suo
*.user
*.sln.docstates
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
build/
bld/
[Bb]in/
[Oo]bj/
# Visual Studio 2015 cache/options directory
.vs/
/.vs/
# Roslyn cache directories
*.ide/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
#NUNIT
*.VisualState.xml
TestResult.xml
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c
*_i.c
*_p.c
*_i.h
*.ilk
*.meta
*.obj
*.pch
*.pdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc
# Chutzpah Test files
_Chutzpah*
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opensdf
*.sdf
*.cachefile
# Visual Studio profiler
*.psess
*.vsp
*.vspx
# TFS 2012 Local Workspace
$tf/
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# JustCode is a .NET coding addin-in
.JustCode
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# NCrunch
_NCrunch_*
.*crunch*.local.xml
# MightyMoose
*.mm.*
AutoTest.Net/
# Web workbench (sass)
.sass-cache/
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
## TODO: Comment the next line if you want to checkin your
## web deploy settings but do note that will include unencrypted
## passwords
*.pubxml
# NuGet Packages
packages/*
*.nupkg
## TODO: If the tool you use requires repositories.config
## uncomment the next line
#!packages/repositories.config
# Enable "build/" folder in the NuGet Packages folder since
# NuGet packages use it for MSBuild targets.
# This line needs to be after the ignore of the build folder
# (and the packages folder if the line above has been uncommented)
!packages/build/
# Windows Azure Build Output
csx/
*.build.csdef
# Windows Store app package directory
AppPackages/
# Others
sql/
*.Cache
ClientBin/
[Ss]tyle[Cc]op.*
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.pfx
*.publishsettings
node_modules/
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
# SQL Server files
*.mdf
*.ldf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
# Microsoft Fakes
FakesAssemblies/

31
HisenceYoloDetection.sln Normal file
View File

@ -0,0 +1,31 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.8.34316.72
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HisenceYoloDetection", "HisenceYoloDetection\HisenceYoloDetection.csproj", "{0DE28139-2917-4B58-8240-4B4E11114730}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|X64 = Debug|X64
Release|Any CPU = Release|Any CPU
Release|X64 = Release|X64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{0DE28139-2917-4B58-8240-4B4E11114730}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0DE28139-2917-4B58-8240-4B4E11114730}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0DE28139-2917-4B58-8240-4B4E11114730}.Debug|X64.ActiveCfg = Debug|X64
{0DE28139-2917-4B58-8240-4B4E11114730}.Debug|X64.Build.0 = Debug|X64
{0DE28139-2917-4B58-8240-4B4E11114730}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0DE28139-2917-4B58-8240-4B4E11114730}.Release|Any CPU.Build.0 = Release|Any CPU
{0DE28139-2917-4B58-8240-4B4E11114730}.Release|X64.ActiveCfg = Release|X64
{0DE28139-2917-4B58-8240-4B4E11114730}.Release|X64.Build.0 = Release|X64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {323307B2-E1FD-47AE-B3FF-4BAAD1305BF6}
EndGlobalSection
EndGlobal

View File

@ -0,0 +1,51 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net7.0-windows</TargetFramework>
<Nullable>enable</Nullable>
<UseWindowsForms>true</UseWindowsForms>
<ImplicitUsings>enable</ImplicitUsings>
<Platforms>AnyCPU;X64</Platforms>
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
</PropertyGroup>
<ItemGroup>
<None Remove="MelsecPLCTCPDriver.cs~RFacf25a.TMP" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="OpenCvSharp4" Version="4.5.3.20210817" />
<PackageReference Include="OpenCvSharp4.runtime.win" Version="4.5.3.20210817" />
<PackageReference Include="STTech.BytesIO.Core" Version="2.14.6" />
<PackageReference Include="STTech.BytesIO.Tcp" Version="2.14.6" />
<PackageReference Include="System.Data.SQLite" Version="1.0.118" />
</ItemGroup>
<ItemGroup>
<Reference Include="DVPCameraCS64">
<HintPath>..\libs\DVPCameraCS_Net6.0\x64\DVPCameraCS64.dll</HintPath>
</Reference>
<Reference Include="HslCommunication">
<HintPath>..\libs\HslCommunication.dll</HintPath>
</Reference>
<Reference Include="PaddleOCRSharp">
<HintPath>bin\X64\Debug\net7.0-windows\PaddleOCRSharp.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Update="Properties\Resources.Designer.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
</ItemGroup>
</Project>

View File

@ -0,0 +1,394 @@
namespace HisenceYoloDetection
{
partial class InsertSqlFrm
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
panel1 = new Panel();
button1 = new Button();
OpenTwoDirBtn = new Button();
OpenDirBtn = new Button();
Cam2MatCbx = new TextBox();
label3 = new Label();
Cam1MatCbx = new TextBox();
label4 = new Label();
QueryoneBtn = new Button();
DetectBArMatbox = new TextBox();
label11 = new Label();
InsertBtn = new Button();
moveTwoZbox = new TextBox();
label5 = new Label();
moveTwoYbox = new TextBox();
label9 = new Label();
moveTwoXbox = new TextBox();
label10 = new Label();
moveZbox = new TextBox();
label6 = new Label();
moveYbox = new TextBox();
label7 = new Label();
moveXbox = new TextBox();
label8 = new Label();
OcrBarBox = new TextBox();
label2 = new Label();
TypeBox = new TextBox();
queryALLBtn = new Button();
label1 = new Label();
InsertDataDgv = new DataGridView();
panel1.SuspendLayout();
((System.ComponentModel.ISupportInitialize)InsertDataDgv).BeginInit();
SuspendLayout();
//
// panel1
//
panel1.Controls.Add(button1);
panel1.Controls.Add(OpenTwoDirBtn);
panel1.Controls.Add(OpenDirBtn);
panel1.Controls.Add(Cam2MatCbx);
panel1.Controls.Add(label3);
panel1.Controls.Add(Cam1MatCbx);
panel1.Controls.Add(label4);
panel1.Controls.Add(QueryoneBtn);
panel1.Controls.Add(DetectBArMatbox);
panel1.Controls.Add(label11);
panel1.Controls.Add(InsertBtn);
panel1.Controls.Add(moveTwoZbox);
panel1.Controls.Add(label5);
panel1.Controls.Add(moveTwoYbox);
panel1.Controls.Add(label9);
panel1.Controls.Add(moveTwoXbox);
panel1.Controls.Add(label10);
panel1.Controls.Add(moveZbox);
panel1.Controls.Add(label6);
panel1.Controls.Add(moveYbox);
panel1.Controls.Add(label7);
panel1.Controls.Add(moveXbox);
panel1.Controls.Add(label8);
panel1.Controls.Add(OcrBarBox);
panel1.Controls.Add(label2);
panel1.Controls.Add(TypeBox);
panel1.Controls.Add(queryALLBtn);
panel1.Controls.Add(label1);
panel1.Controls.Add(InsertDataDgv);
panel1.Location = new Point(0, -3);
panel1.Name = "panel1";
panel1.Size = new Size(934, 533);
panel1.TabIndex = 0;
//
// button1
//
button1.Location = new Point(696, 152);
button1.Name = "button1";
button1.Size = new Size(75, 23);
button1.TabIndex = 32;
button1.Text = "打开文件";
button1.UseVisualStyleBackColor = true;
button1.Click += button1_Click;
//
// OpenTwoDirBtn
//
OpenTwoDirBtn.Location = new Point(696, 241);
OpenTwoDirBtn.Name = "OpenTwoDirBtn";
OpenTwoDirBtn.Size = new Size(75, 23);
OpenTwoDirBtn.TabIndex = 31;
OpenTwoDirBtn.Text = "打开文件";
OpenTwoDirBtn.UseVisualStyleBackColor = true;
OpenTwoDirBtn.Click += OpenTwoDirBtn_Click;
//
// OpenDirBtn
//
OpenDirBtn.Location = new Point(696, 193);
OpenDirBtn.Name = "OpenDirBtn";
OpenDirBtn.Size = new Size(75, 23);
OpenDirBtn.TabIndex = 30;
OpenDirBtn.Text = "打开文件";
OpenDirBtn.UseVisualStyleBackColor = true;
OpenDirBtn.Click += OpenDirBtn_Click;
//
// Cam2MatCbx
//
Cam2MatCbx.Location = new Point(478, 244);
Cam2MatCbx.Name = "Cam2MatCbx";
Cam2MatCbx.Size = new Size(188, 23);
Cam2MatCbx.TabIndex = 29;
//
// label3
//
label3.AutoSize = true;
label3.Location = new Point(371, 244);
label3.Name = "label3";
label3.Size = new Size(80, 17);
label3.TabIndex = 28;
label3.Text = "面板第二张图";
//
// Cam1MatCbx
//
Cam1MatCbx.Location = new Point(478, 193);
Cam1MatCbx.Name = "Cam1MatCbx";
Cam1MatCbx.Size = new Size(188, 23);
Cam1MatCbx.TabIndex = 27;
//
// label4
//
label4.AutoSize = true;
label4.Location = new Point(372, 199);
label4.Name = "label4";
label4.Size = new Size(80, 17);
label4.TabIndex = 26;
label4.Text = "面板第一张图";
//
// QueryoneBtn
//
QueryoneBtn.Location = new Point(827, 108);
QueryoneBtn.Name = "QueryoneBtn";
QueryoneBtn.Size = new Size(93, 23);
QueryoneBtn.TabIndex = 25;
QueryoneBtn.Text = "条件查询";
QueryoneBtn.UseVisualStyleBackColor = true;
QueryoneBtn.Click += QueryoneBtn_Click;
//
// DetectBArMatbox
//
DetectBArMatbox.Location = new Point(477, 152);
DetectBArMatbox.Name = "DetectBArMatbox";
DetectBArMatbox.Size = new Size(188, 23);
DetectBArMatbox.TabIndex = 24;
//
// label11
//
label11.AutoSize = true;
label11.Location = new Point(402, 158);
label11.Name = "label11";
label11.Size = new Size(56, 17);
label11.TabIndex = 23;
label11.Text = "条码录入";
//
// InsertBtn
//
InsertBtn.Location = new Point(827, 18);
InsertBtn.Name = "InsertBtn";
InsertBtn.Size = new Size(93, 23);
InsertBtn.TabIndex = 22;
InsertBtn.Text = "插入";
InsertBtn.UseVisualStyleBackColor = true;
InsertBtn.Click += InsertBtn_Click;
//
// moveTwoZbox
//
moveTwoZbox.Location = new Point(477, 101);
moveTwoZbox.Name = "moveTwoZbox";
moveTwoZbox.Size = new Size(188, 23);
moveTwoZbox.TabIndex = 21;
//
// label5
//
label5.AutoSize = true;
label5.Location = new Point(371, 107);
label5.Name = "label5";
label5.Size = new Size(87, 17);
label5.TabIndex = 20;
label5.Text = "第二次拍照Z轴";
//
// moveTwoYbox
//
moveTwoYbox.Location = new Point(477, 54);
moveTwoYbox.Name = "moveTwoYbox";
moveTwoYbox.Size = new Size(188, 23);
moveTwoYbox.TabIndex = 19;
//
// label9
//
label9.AutoSize = true;
label9.Location = new Point(371, 60);
label9.Name = "label9";
label9.Size = new Size(87, 17);
label9.TabIndex = 18;
label9.Text = "第二次拍照Y轴";
//
// moveTwoXbox
//
moveTwoXbox.Location = new Point(477, 12);
moveTwoXbox.Name = "moveTwoXbox";
moveTwoXbox.Size = new Size(188, 23);
moveTwoXbox.TabIndex = 17;
//
// label10
//
label10.AutoSize = true;
label10.Location = new Point(371, 18);
label10.Name = "label10";
label10.Size = new Size(88, 17);
label10.TabIndex = 16;
label10.Text = "第二次拍照X轴";
//
// moveZbox
//
moveZbox.Location = new Point(111, 193);
moveZbox.Name = "moveZbox";
moveZbox.Size = new Size(188, 23);
moveZbox.TabIndex = 15;
//
// label6
//
label6.AutoSize = true;
label6.Location = new Point(17, 199);
label6.Name = "label6";
label6.Size = new Size(87, 17);
label6.TabIndex = 14;
label6.Text = "第一次拍照Z轴";
//
// moveYbox
//
moveYbox.Location = new Point(111, 146);
moveYbox.Name = "moveYbox";
moveYbox.Size = new Size(188, 23);
moveYbox.TabIndex = 13;
//
// label7
//
label7.AutoSize = true;
label7.Location = new Point(17, 152);
label7.Name = "label7";
label7.Size = new Size(87, 17);
label7.TabIndex = 12;
label7.Text = "第一次拍照Y轴";
//
// moveXbox
//
moveXbox.Location = new Point(111, 104);
moveXbox.Name = "moveXbox";
moveXbox.Size = new Size(188, 23);
moveXbox.TabIndex = 11;
//
// label8
//
label8.AutoSize = true;
label8.Location = new Point(17, 110);
label8.Name = "label8";
label8.Size = new Size(88, 17);
label8.TabIndex = 10;
label8.Text = "第一次拍照X轴";
//
// OcrBarBox
//
OcrBarBox.Location = new Point(111, 54);
OcrBarBox.Name = "OcrBarBox";
OcrBarBox.Size = new Size(188, 23);
OcrBarBox.TabIndex = 5;
//
// label2
//
label2.AutoSize = true;
label2.Location = new Point(14, 60);
label2.Name = "label2";
label2.Size = new Size(32, 17);
label2.TabIndex = 4;
label2.Text = "条码";
//
// TypeBox
//
TypeBox.Location = new Point(111, 12);
TypeBox.Name = "TypeBox";
TypeBox.Size = new Size(188, 23);
TypeBox.TabIndex = 3;
TypeBox.TextChanged += TypeBox_TextChanged;
//
// queryALLBtn
//
queryALLBtn.Location = new Point(827, 59);
queryALLBtn.Name = "queryALLBtn";
queryALLBtn.Size = new Size(93, 23);
queryALLBtn.TabIndex = 2;
queryALLBtn.Text = "查询全部";
queryALLBtn.UseVisualStyleBackColor = true;
queryALLBtn.Click += queryALLBtn_Click;
//
// label1
//
label1.AutoSize = true;
label1.Location = new Point(14, 18);
label1.Name = "label1";
label1.Size = new Size(32, 17);
label1.TabIndex = 1;
label1.Text = "类型";
//
// InsertDataDgv
//
InsertDataDgv.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
InsertDataDgv.Location = new Point(12, 281);
InsertDataDgv.Name = "InsertDataDgv";
InsertDataDgv.RowTemplate.Height = 25;
InsertDataDgv.Size = new Size(919, 235);
InsertDataDgv.TabIndex = 0;
//
// InsertSqlFrm
//
AutoScaleDimensions = new SizeF(7F, 17F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(946, 525);
Controls.Add(panel1);
Name = "InsertSqlFrm";
Text = "InsertSqlFrm";
panel1.ResumeLayout(false);
panel1.PerformLayout();
((System.ComponentModel.ISupportInitialize)InsertDataDgv).EndInit();
ResumeLayout(false);
}
#endregion
private Panel panel1;
private Button queryALLBtn;
private Label label1;
private DataGridView InsertDataDgv;
private TextBox moveZbox;
private Label label6;
private TextBox moveYbox;
private Label label7;
private TextBox moveXbox;
private Label label8;
private TextBox OcrBarBox;
private Label label2;
private TextBox TypeBox;
private TextBox DetectBArMatbox;
private Label label11;
private Button InsertBtn;
private TextBox moveTwoZbox;
private Label label5;
private TextBox moveTwoYbox;
private Label label9;
private TextBox moveTwoXbox;
private Label label10;
private Button QueryoneBtn;
private TextBox Cam2MatCbx;
private Label label3;
private TextBox Cam1MatCbx;
private Label label4;
private Button button1;
private Button OpenTwoDirBtn;
private Button OpenDirBtn;
}
}

View File

@ -0,0 +1,198 @@
using OpenCvSharp;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Xml.Linq;
using XKRS.Device.SimboVision.SimboHelper;
namespace HisenceYoloDetection
{
public partial class InsertSqlFrm : Form
{
public InsertSqlFrm()
{
InitializeComponent();
}
public SimboObjectDetection simboObjectDetection;
public PaddleOcrModel paddleOcrModel ;
public PaddleOcrModelCountry paddleOcrModelCountry ;
private void TypeBox_TextChanged(object sender, EventArgs e)
{
}
string BarPath = "";
string Cam1OnePath = "";
string Cam1TwoPath = "";
private void InsertBtn_Click(object sender, EventArgs e)
{
try
{
string type = TypeBox.Text;
string OcrBar = OcrBarBox.Text;
string moveX = moveXbox.Text;
string moveY = moveYbox.Text;
string moveZ = moveZbox.Text;
string Detect = DetectBArMatbox.Text;
string movetwoX = moveTwoXbox.Text;
string movetwoY = moveTwoYbox.Text;
string movetwoZ = moveTwoZbox.Text;
if (!Regex.IsMatch(moveX, @"^[0-9]+$"))
{
MessageBox.Show("第一次拍照移动的X只能是数字");
return;
}
if (!Regex.IsMatch(moveY, @"^[0-9]+$"))
{
MessageBox.Show("第一次拍照移动的Y只能是数字");
return;
}
if (!Regex.IsMatch(moveZ, @"^[0-9]+$"))
{
MessageBox.Show("第一次拍照移动的Z只能是数字");
return;
}
if (!Regex.IsMatch(movetwoX, @"^[0-9]+$"))
{
MessageBox.Show("第二次拍照移动的X只能是数字");
return;
}
if (!Regex.IsMatch(movetwoY, @"^[0-9]+$"))
{
MessageBox.Show("第二次拍照移动的Y只能是数字");
return;
}
if (!Regex.IsMatch(movetwoZ, @"^[0-9]+$"))
{
MessageBox.Show("第二次拍照移动的Z只能是数字");
return;
}
if (OcrBar != "" && Detect != "")
{
string sql = "insert into XK_Hisence VALUES('" + type + "','" + OcrBar + "',null,null," + moveX + "," + moveY + "," + moveZ + ",'" + Detect + "',null," + movetwoX + "," + movetwoY + "," + movetwoZ + ")";
SQLiteHelper.ExecuteSql(sql);
}
else
{
MessageBox.Show("插入的数据不能为NULL");
}
}
catch (Exception es)
{
}
}
private void queryALLBtn_Click(object sender, EventArgs e)
{
try
{
DataSet dataSet = SQLiteHelper.Query("select * from XK_Hisence");
InsertDataDgv.DataSource = dataSet.Tables[0];
}
catch (Exception es)
{
}
}
private void QueryoneBtn_Click(object sender, EventArgs e)
{
try
{
string type = TypeBox.Text;
string OcrBar = OcrBarBox.Text;
string moveX = moveXbox.Text;
string moveY = moveYbox.Text;
string moveZ = moveZbox.Text;
string Detect = DetectBArMatbox.Text;
string movetwoX = moveTwoXbox.Text;
string movetwoY = moveTwoYbox.Text;
string movetwoZ = moveTwoZbox.Text;
string sql = "select * from XK_Hisence where type='" + type + "' or OcrBar='" + OcrBar + "'";
DataSet dataSet = SQLiteHelper.Query(sql);
InsertDataDgv.DataSource = dataSet.Tables[0];
}
catch (Exception es)
{
}
}
/// <summary>
/// 打开条码的图片
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button1_Click(object sender, EventArgs e)
{
OpenFileDialog openFileDialog = new OpenFileDialog();
openFileDialog.Title = "请打开图片";
if (openFileDialog.ShowDialog() == DialogResult.OK)
{
string fName = openFileDialog.FileName;
//File fileOpen = new File(fName);
//isFileHaveName = true;
//richTextBox1.Text = fileOpen.ReadFile();
//richTextBox1.AppendText("");
DetectBArMatbox.Text = fName;
BarPath = fName;
}
}
private void OpenDirBtn_Click(object sender, EventArgs e)
{
OpenFileDialog openFileDialog = new OpenFileDialog();
openFileDialog.Title = "请打开图片";
if (openFileDialog.ShowDialog() == DialogResult.OK)
{
string fName = openFileDialog.FileName;
//File fileOpen = new File(fName);
//isFileHaveName = true;
//richTextBox1.Text = fileOpen.ReadFile();
//richTextBox1.AppendText("");
Cam1MatCbx.Text = fName;
Cam1OnePath = fName;
}
}
private void OpenTwoDirBtn_Click(object sender, EventArgs e)
{
OpenFileDialog openFileDialog = new OpenFileDialog();
openFileDialog.Title = "请打开图片";
if (openFileDialog.ShowDialog() == DialogResult.OK)
{
string fName = openFileDialog.FileName;
//File fileOpen = new File(fName);
//isFileHaveName = true;
//richTextBox1.Text = fileOpen.ReadFile();
//richTextBox1.AppendText("");
Cam2MatCbx.Text = fName;
Cam1TwoPath = fName;
}
}
}
}

View File

@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@ -0,0 +1,713 @@

using DVPCameraType;
using OpenCvSharp;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net.NetworkInformation;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Xml.Linq;
using static DVPCameraType.DVPCamera;
using static System.Windows.Forms.VisualStyles.VisualStyleElement;
public class MGSCameraDriver
{
private uint m_handle = 0;
private dvpCameraInfo stDevInfo = new dvpCameraInfo();
private dvpStatus nRet = dvpStatus.DVP_STATUS_OK;
private DVPCamera.dvpEventCallback pCallBackFunc;
/// <summary>
/// 相机拍照计数
/// </summary>
public volatile int SnapshotCount = 0;
/// <summary>
/// 当前相机的配置
/// </summary>
public bool IfSuccess=false;
private float _lastExposure = 0;
private float _lastGain = 0;
#region CameraBase
public bool IsValidHandle(uint handle)
{
bool bValidHandle = false;
dvpStatus status = DVPCamera.dvpIsValid(handle, ref bValidHandle);
if (status == dvpStatus.DVP_STATUS_OK)
{
return bValidHandle;
}
return false;
}
/// <summary>
/// 获取曝光
/// </summary>
/// <returns></returns>
public double dvpGetExposure()
{
dvpStatus status;
double exposure = 0;
float gain = 0;
if (IsValidHandle(m_handle))
{
// 读取曝光
status = DVPCamera.dvpGetExposure(m_handle, ref exposure);
if (status == dvpStatus.DVP_STATUS_OK)
{
//opConfig.Exposure = (float)exposure;
return exposure;
}
}
return exposure;
}
/// <summary>
/// 获取增益
/// </summary>
/// <returns></returns>
public float dvpGetAnalogGain()
{
dvpStatus status;
double exposure = 0;
float gain = 0;
if (IsValidHandle(m_handle))
{
// 读取曝光
status = DVPCamera.dvpGetAnalogGain(m_handle, ref gain);
if (status == dvpStatus.DVP_STATUS_OK)
{
//opConfig.Exposure = (float)exposure;
return gain;
}
}
return gain;
}
//public override IOperationConfig GetOperationConfigFromDevice()
//{
// MGSCameraOperationConfig opConfig = new MGSCameraOperationConfig();
// dvpStatus status;
// double exposure = 0;
// float gain = 0;
// if (IsValidHandle(m_handle))
// {
// // 读取曝光
// status = DVPCamera.dvpGetExposure(m_handle, ref exposure);
// if (status == dvpStatus.DVP_STATUS_OK)
// {
// opConfig.Exposure = (float)exposure;
// }
// // 读取增益
// status = DVPCamera.dvpGetAnalogGain(m_handle, ref gain);
// if (status == dvpStatus.DVP_STATUS_OK)
// {
// opConfig.Gain = gain;
// }
// }
// return opConfig;
//}
//public override void UploadOperationConfig(IOperationConfig config)
//{
// if (CurrentState != DeviceState.DSOpen)
// {
// return;
// }
// if (!IsValidHandle(m_handle))
// {
// return;
// }
// CameraOprerationConfigBase opConfig = config as CameraOprerationConfigBase;
// if (opConfig.Exposure != 0 && opConfig.Exposure != _lastExposure)
// {
// SetExposure(opConfig.Exposure);
// _lastExposure = opConfig.Exposure;
// }
// if (opConfig.Gain != 0 && opConfig.Gain != _lastGain)
// {
// SetGain(opConfig.Gain);
// _lastGain = opConfig.Gain;
// }
//}
public void Init()
{
DVPCamera.dvpGetCameraInfo(m_handle, ref stDevInfo);
_bufferImgSet = new Mat();
pCallBackFunc = new DVPCamera.dvpEventCallback(cbExceptiondelegate);
}
protected void Pause()
{
}
protected void Resume()
{
}
public class CamConfig
{
public string CameraName = "Cam1";
public double DefaultExposure;
public float Gain;
public bool IsDirectHardwareTrigger = true;
}
public CamConfig IIConfig;
public void Start(string DeviceName)
{
try
{
DVPCamera.dvpGetCameraInfo(m_handle, ref stDevInfo);
_bufferImgSet = new Mat();
pCallBackFunc = new DVPCamera.dvpEventCallback(cbExceptiondelegate);
nRet = DVPCamera.dvpOpenByUserId(DeviceName,
dvpOpenMode.OPEN_NORMAL,
ref m_handle);
// ch:打开设备 | en:Open device
if (dvpStatus.DVP_STATUS_OK != nRet)
{
throw new Exception($"Create device failed:{nRet:x8}");
}
nRet = DVPCamera.dvpSetTargetFormat(m_handle, (dvpStreamFormat)dvpImageFormat.FORMAT_BGR24);
if (dvpStatus.DVP_STATUS_OK != nRet)
{
throw new Exception($"Set image format failed:{nRet:x8}");
}
// ch:注册异常回调函数 | en:Register Exception Callback
nRet = DVPCamera.dvpRegisterEventCallback(m_handle, pCallBackFunc, dvpEvent.EVENT_DISCONNECTED, IntPtr.Zero);
if (nRet != dvpStatus.DVP_STATUS_OK)
{
throw new Exception($"Register expection callback failed:{nRet}");
}
GC.KeepAlive(pCallBackFunc);
dvpStatus status;
double exposure = 0;
float gain = 0;
if (IsValidHandle(m_handle))
{
// 读取曝光
//status = DVPCamera.dvpGetExposure(m_handle, ref exposure);
//if (status == dvpStatus.DVP_STATUS_OK)
//{
// IIConfig.DefaultExposure = (float)exposure;
//}
//// 读取增益
//status = DVPCamera.dvpGetAnalogGain(m_handle, ref gain);
//if (status == dvpStatus.DVP_STATUS_OK)
//{
// IIConfig.Gain = gain;
//}
}
// ch:设置采集连续模式 | en:Set Continues Aquisition Mode
if (false)//IIConfig.IsContinueMode)
{
// ch:设置触发模式为off || en:set trigger mode as off
nRet = DVPCamera.dvpSetTriggerState(m_handle, false);
if (dvpStatus.DVP_STATUS_OK != nRet)
{
throw new Exception("Set TriggerMode failed!");
}
}
else
{
// ch:设置触发模式为on || en:set trigger mode as on
nRet = DVPCamera.dvpSetTriggerState(m_handle, true);
if (dvpStatus.DVP_STATUS_OK != nRet)
{
throw new Exception("Set TriggerMode failed!");
}
// 硬触发
if (false)//IIConfig.IsHardwareTrigger)
{
// ch:触发源选择:1 - Line1; | en:Trigger source select:1 - Line1;
nRet = DVPCamera.dvpSetTriggerSource(m_handle, dvpTriggerSource.TRIGGER_SOURCE_LINE1);
if (dvpStatus.DVP_STATUS_OK != nRet)
{
throw new Exception("Set Line1 Trigger failed!");
}
// ch:注册回调函数 | en:Register image callback
ImageCallback = new DVPCamera.dvpStreamCallback(ImageCallbackFunc);
nRet = DVPCamera.dvpRegisterStreamCallback(m_handle, ImageCallback, dvpStreamEvent.STREAM_EVENT_PROCESSED, IntPtr.Zero);
if (dvpStatus.DVP_STATUS_OK != nRet)
{
throw new Exception("Register image callback failed!");
}
}
else // 软触发
{
nRet = DVPCamera.dvpSetTriggerSource(m_handle, dvpTriggerSource.TRIGGER_SOURCE_SOFTWARE);
if (dvpStatus.DVP_STATUS_OK != nRet)
{
throw new Exception("Set Software Trigger failed!");
}
//_proc = _dvpStreamCallback;
//nRet = DVPCamera.dvpRegisterStreamCallback(m_handle, _proc, dvpStreamEvent.STREAM_EVENT_PROCESSED, IntPtr.Zero);
//if (dvpStatus.DVP_STATUS_OK != nRet)
//{
// throw new Exception("Register image callback failed!");
//}
// ch:注册回调函数 | en:Register image callback
ImageCallback = new DVPCamera.dvpStreamCallback(ImageCallbackFunc);
nRet = DVPCamera.dvpRegisterStreamCallback(m_handle, ImageCallback, dvpStreamEvent.STREAM_EVENT_PROCESSED, IntPtr.Zero);
if (dvpStatus.DVP_STATUS_OK != nRet)
{
throw new Exception("Register image callback failed!");
}
using (Process curProcess = Process.GetCurrentProcess())
using (ProcessModule curModule = curProcess.MainModule)
{
status = DVPCamera.dvpRegisterStreamCallback(m_handle, _proc, dvpStreamEvent.STREAM_EVENT_PROCESSED, IntPtr.Zero);
//Debug.Assert(status == dvpStatus.DVP_STATUS_OK);
}
}
m_dfDisplayCount = 0;
if (IsValidHandle(m_handle))
{
dvpStreamState state = new dvpStreamState();
// Implement a button to start and stop according to the current video's status.
status = DVPCamera.dvpGetStreamState(m_handle, ref state);
if (state == dvpStreamState.STATE_STARTED)
{
nRet = DVPCamera.dvpStop(m_handle);
}
else
{
nRet = DVPCamera.dvpStart(m_handle);
}
Debug.Assert(status == dvpStatus.DVP_STATUS_OK);
nRet = DVPCamera.dvpSetTriggerSource(m_handle, dvpTriggerSource.TRIGGER_SOURCE_SOFTWARE);
if (dvpStatus.DVP_STATUS_OK != nRet)
{
throw new Exception("Set Software Trigger failed!");
}
else
{
IfSuccess = true;
}
}
// ch:开启抓图 || en: start grab image
//nRet = DVPCamera.dvpStart(m_handle);
//if (dvpStatus.DVP_STATUS_OK != nRet)
//{
// throw new Exception($"Start grabbing failed:{nRet:x8}");
//}
// 曝光
//if (IIConfig.DefaultExposure != 0)
//{
// SetExposure(IIConfig.DefaultExposure);
//}
//// 增益
//if (IIConfig.Gain >= 0)
//{
// SetGain(IIConfig.Gain);
//}
// 设置 触发延迟
//if (IIConfig.TriggerDelay > 0)
//{
// nRet = DVPCamera.dvpSetTriggerDelay(m_handle, IIConfig.TriggerDelay);
// if (nRet != dvpStatus.DVP_STATUS_OK)
// {
// throw new Exception("Set TriggerDelay failed!");
// }
//}
// 信号消抖
//if (IIConfig.LineDebouncerTime > 0)
//{
// nRet = DVPCamera.dvpSetTriggerJitterFilter(m_handle, IIConfig.LineDebouncerTime);
// if (nRet != dvpStatus.DVP_STATUS_OK)
// {
// throw new Exception($"LineDebouncerTime set failed:{nRet}");
// }
//}
}
}
catch (Exception e)
{
}
}
public void Stop()
{
// ch:停止抓图 | en:Stop grab image
// check camear
dvpStreamState StreamState = new dvpStreamState();
nRet = DVPCamera.dvpGetStreamState(m_handle, ref StreamState);
Debug.Assert(nRet == dvpStatus.DVP_STATUS_OK);
if (StreamState == dvpStreamState.STATE_STARTED)
{
// stop camera
nRet = DVPCamera.dvpStop(m_handle);
Debug.Assert(nRet == dvpStatus.DVP_STATUS_OK);
if (nRet != dvpStatus.DVP_STATUS_OK)
{
throw new Exception($"Stop grabbing failed{nRet:x8}");
}
}
nRet = DVPCamera.dvpUnregisterEventCallback(m_handle, pCallBackFunc, dvpEvent.EVENT_DISCONNECTED, IntPtr.Zero);
if (nRet != dvpStatus.DVP_STATUS_OK)
{
throw new Exception($"Unregister expection callback failed:{nRet}");
}
// ch:关闭设备 | en:Close device
nRet = DVPCamera.dvpClose(m_handle);
if (nRet != dvpStatus.DVP_STATUS_OK)
{
throw new Exception($"Close device failed{nRet:x8}");
}
m_handle = 0;
}
#endregion
#region MGSCamera
private DVPCamera.dvpStreamCallback ImageCallback;
private DVPCamera.dvpStreamCallback _proc;
private dvpFrameBuffer _frame = new dvpFrameBuffer();
private readonly ManualResetEvent _snapHandle = new ManualResetEvent(false);
private bool _snapFlag = false;
private Mat _bufferImgSet = null;
private readonly ManualResetEvent _bufferHandle = new ManualResetEvent(false);
public Action<DateTime,Mat,int> OnHImageOutput { get; set; }
public static bool m_bTriggerMode = false;
// Display param
public static Stopwatch m_Stopwatch = new Stopwatch();
public static Double m_dfDisplayCount = 0;
public static dvpCameraInfo[] m_info = new dvpCameraInfo[16];
public static int m_CamCount = 0;
/// <summary>
/// 设置曝光值
/// </summary>
/// <param name="exposure">曝光值</param>
/// <exception cref="Exception"></exception>
private void SetExposure(double exposure)
{
// 使用自动曝光
if (false)
{
// 设置自动曝光
//nRet = DVPCamera.dvpSetAeOperation(m_handle, dvpAeOperation.AE_OP_CONTINUOUS);
if (nRet != dvpStatus.DVP_STATUS_OK)
{
throw new Exception($"Exposure set failed:{nRet}");
}
// 设置曝光值
nRet = DVPCamera.dvpSetAeTarget(m_handle, (int)exposure);
if (nRet != dvpStatus.DVP_STATUS_OK)
{
throw new Exception($"Exposure set failed:{nRet}");
}
}
else // 不适用自动曝光
{
// 关闭自动曝光
nRet = DVPCamera.dvpSetAeOperation(m_handle, dvpAeOperation.AE_OP_OFF);
if (nRet != dvpStatus.DVP_STATUS_OK)
{
throw new Exception($"Exposure set failed:{nRet}");
}
// 设置曝光值
nRet = DVPCamera.dvpSetExposure(m_handle, exposure);
if (nRet != dvpStatus.DVP_STATUS_OK)
{
throw new Exception($"Exposure set failed:{nRet}");
}
}
}
/// <summary>
/// 设置增益
/// </summary>
/// <param name="gain"></param>
/// <exception cref="Exception"></exception>
private void SetGain(float gain)
{
// 设置增益
nRet = DVPCamera.dvpSetAnalogGain(m_handle, gain);
if (nRet != dvpStatus.DVP_STATUS_OK)
{
throw new Exception($"Gain set failed:{nRet}");
}
}
public int ImageCallbackFunc(uint handle, dvpStreamEvent _event, IntPtr pContext, ref dvpFrame refFrame, IntPtr pBuffer)
{
try
{
if (true)//硬触发
{
int nWidth = refFrame.iWidth;
int nHeight = refFrame.iHeight;
MatType matType = MatType.CV_8UC1;
if (refFrame.format == dvpImageFormat.FORMAT_RGB24)
{
IntPtr pTemp = pBuffer;
}
else if (refFrame.format == dvpImageFormat.FORMAT_BGR24)
{
IntPtr pTemp = pBuffer;
matType = MatType.CV_8UC3;
}
Mat _mat = new Mat( nHeight,nWidth, matType, pBuffer);
//加入内部队列
//if (IIConfig.IsDirectHardwareTrigger)
//{
// 传感器直接触发 收到图片后 传出
OnHImageOutput?.Invoke(DateTime.Now, _mat, SnapshotCount);
// }
//else
//{
// _bufferImgSet = _mat;
// // _bufferImgSetQueue.Enqueue(outImgSet);
// _bufferHandle.Set();
//}
//处理完图片 会清理内部队列的图像
//DisplayAndSaveOriginImage(imgSet.Id);
}
else if (_snapFlag)
{
_snapFlag = false;
_frame = new dvpFrameBuffer
{
frame = refFrame,
pData = pBuffer,
};
_snapHandle.Set();
}
}
catch (Exception ex)
{
return dvpStatus.DVP_STATUS_GRAB_FAILED.ToInt();
}
return dvpStatus.DVP_STATUS_OK.ToInt();
}
private object _bufferLock = new object();
public void Snapshot()
{
try
{
Stopwatch sw = new Stopwatch();
sw.Start();
// ImageSet set = new ImageSet();
dvpFrameBuffer frameInfo = new dvpFrameBuffer();
nRet = dvpStatus.DVP_STATUS_OK;
if (true)//如果不是持续模式
{
// ch: 触发命令 || en: Trigger command
nRet = DVPCamera.dvpTriggerFire(m_handle);
if (dvpStatus.DVP_STATUS_OK != nRet)
{
throw new Exception($"相机拍照触发失败:{nRet}");
}
}
else
{
_snapHandle.Reset();
_snapFlag = true;
_snapHandle.WaitOne();
//lock (_imgCallBackLock)
{
frameInfo.frame = _frame.frame;
frameInfo.pData = _frame.pData;
}
}
// ch:获取一帧图像 | en:Get one image
if (dvpStatus.DVP_STATUS_OK == nRet)
{
Interlocked.Increment(ref SnapshotCount);
if (frameInfo.pData != IntPtr.Zero)
{
if (nRet == dvpStatus.DVP_STATUS_OK)
{
dvpFrame pFrameInfo = frameInfo.frame;
MatType matType = MatType.CV_8UC1;
if (pFrameInfo.format == dvpImageFormat.FORMAT_RGB24)
{
}
else if (pFrameInfo.format == dvpImageFormat.FORMAT_BGR24)
{
matType = MatType.CV_8UC3;
}
//HImage hImage = new HImage();
//hImage.GenImage1("byte", pFrameInfo.iWidth, pFrameInfo.iHeight, frameInfo.pData);
Mat _mat = new Mat(pFrameInfo.iHeight, pFrameInfo.iWidth, matType, frameInfo.pData);
OnHImageOutput?.Invoke(DateTime.Now, _mat,SnapshotCount);
//_mat.ImWrite("D://123.jpg");
}
}
}
else
{
throw new Exception($"Grap Image Failed:{nRet:x8}");
}
sw.Stop();
// LogAsync(DateTime.Now, LogLevel.Information, $"取像耗时:{sw.ElapsedMilliseconds} ms");
}
catch (Exception ex) {
}
}
/// <summary>
/// 回调函数
/// </summary>
/// <param name="handle"></param>
/// <param name="_event"></param>
/// <param name="pContext"></param>
/// <param name="param"></param>
/// <param name="refVariant"></param>
/// <returns></returns>
public int cbExceptiondelegate(uint handle, dvpEvent _event, IntPtr pContext, int param, ref dvpVariant refVariant)
{
if (_event == dvpEvent.EVENT_DISCONNECTED)
{
int reTryTimes = 3;
do
{
try
{
Task.Delay(1000).Wait();
Stop();
//Start();
reTryTimes = -1;
}
catch (Exception ex)
{
reTryTimes--;
if (reTryTimes > 0)
{
// LogAsync(DateTime.Now, LogLevel.Information, $"{Name}重新连接异常,{ex.GetExceptionMessage()}");
}
else
{
throw ex;
}
}
} while (reTryTimes > 0);
}
return dvpStatus.DVP_STATUS_OK.ToInt();
}
#endregion
}

1899
HisenceYoloDetection/MainForm.Designer.cs generated Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,147 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="timer1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
<metadata name="timer2.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>109, 17</value>
</metadata>
<metadata name="timer3.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>201, 17</value>
</metadata>
<metadata name="timer4.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>293, 17</value>
</metadata>
<metadata name="timer5.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>385, 17</value>
</metadata>
<metadata name="timer6.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>477, 17</value>
</metadata>
<metadata name="contextMenuStrip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>569, 17</value>
</metadata>
<metadata name="backgroundWorker1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>733, 17</value>
</metadata>
<metadata name="$this.TrayHeight" type="System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>28</value>
</metadata>
</root>

View File

@ -0,0 +1,358 @@

using HslCommunication;
using HslCommunication.Profinet.Melsec;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using System.Xml.Linq;
using static OpenCvSharp.FileStorage;
public class MelsecPLCTCPDriver
{
private MelsecMcNet melsecMc = new MelsecMcNet();
// private HslCommunication.ModBus.ModbusTcpNet melsecMc = new HslCommunication.ModBus.ModbusTcpNet();
//HslCommunication.Profinet.Melsec.MelsecMcServer melsecMc = new HslCommunication.Profinet.Melsec.MelsecMcServer();
#region PLCBase
public List<int> Read(string startAddress, int length)
{
PLCItem item = new PLCItem();
item.Address = startAddress;
item.ItemLength = length;
ReadItem(item);
//List<int> valueList = new List<int>();
//if (!string.IsNullOrWhiteSpace(item.ItemValue))
//{
// valueList = item.ItemValue.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).ToList().ConvertAll(s => int.Parse(s)).ToList();
//}
return item.ItemValues;
}
public void ReadItem(PLCItem item)
{
// item.PLCOpType = PLCOpType.Read;
item.ItemValues.Clear();
try
{
// 读取Int变量
var result = melsecMc.ReadInt32("D"+item.Address, (ushort)item.ItemLength);
if (result.IsSuccess)
{
for (int i = 0; i < result.Content.Length; i++)
{
item.ItemValues.Add(result.Content[i]);
}
}
else
{
// LogAsync(DateTime.Now, LogLevel.Error, $"{Name}未读取到数据:" + "地址:" + item.Address + ";长度:" + item.ItemLength + ";提示:" + result.Message);
}
}
catch (Exception ex)
{
// LogAsync(DateTime.Now, LogLevel.Exception, $"{Name}读取异常:" + ex.GetExceptionMessage());
}
}
public int ReadInt(string address)
{
try
{
// 读取Int变量
var result = melsecMc.ReadInt32("D"+address);
if (result.IsSuccess)
{
return result.Content;
}
else
{
// LogAsync(DateTime.Now, LogLevel.Error, $"{Name}未读取到数据:" + "地址:" + address + ";提示:" + result.Message);
return -1;
}
}
catch (Exception ex)
{
// LogAsync(DateTime.Now, LogLevel.Exception, $"{Name}读取异常:" + ex.GetExceptionMessage());
return -1;
}
}
public void WriteItem(PLCItem item, bool waitForReply = true)
{
item.PLCOpType = PLCOpType.Write;
if (item.ItemValues == null || item.ItemValues.Count < 1)
{
// LogAsync(DateTime.Now, LogLevel.Error, $"{Name} 数据写入值不能为空");
return;
}
int repeatTime = 3;
Stopwatch sw = new Stopwatch();
do
{
try
{
var result = melsecMc.Write(item.Address, item.ItemValues.First());
if (result.IsSuccess)
{
repeatTime = 0;
}
}
catch (Exception ex)
{
if (repeatTime < 0)
{
//LogAsync(DateTime.Now, LogLevel.Exception, $"{Name}数据写入异常:{ex.GetExceptionMessage()}");
}
}
} while (repeatTime > 0);
sw.Stop();
// LogAsync(DateTime.Now, LogLevel.Assist, $"{Name} WriteItem{item.GetDisplayText()},写入 {item.ItemValues.First()}完成,耗时:{sw.ElapsedMilliseconds} ms");
}
/// <summary>
/// 写单独地址
/// </summary>
/// <param name="address">地址</param>
/// <param name="writeValue"></param>
/// <param name="waitForReply"></param>
public void WriteInt(string address, int writeValue, bool waitForReply = true)
{
if (string.IsNullOrEmpty(address))
{
// LogAsync(DateTime.Now, LogLevel.Error, $"{Name} 数据写入参数不能为空!");
return;
}
int repeatTime = 3;
Stopwatch sw = new Stopwatch();
do
{
try
{
var result = melsecMc.Write("D"+address, writeValue);
if (result.IsSuccess)
{
repeatTime = 0;
}
}
catch (Exception ex)
{
if (repeatTime < 0)
{
// LogAsync(DateTime.Now, LogLevel.Exception, $"{Name}数据写入异常:{ex.GetExceptionMessage()}");
}
}
} while (repeatTime > 0);
sw.Stop();
// LogAsync(DateTime.Now, LogLevel.Assist, $"{Name} {address},写入 {writeValue} 完成,耗时:{sw.ElapsedMilliseconds} ms");
}
/// <summary>
/// 写单独地址 string值
/// </summary>
/// <param name="address">地址</param>
/// <param name="writeValue"></param>
/// <param name="waitForReply"></param>
public void WriteString(string address, string writeValue, bool waitForReply = true)
{
if (string.IsNullOrEmpty(address) || string.IsNullOrEmpty(writeValue))
{
// LogAsync(DateTime.Now, LogLevel.Error, $"{Name} 数据写入参数不能为空!");
return;
}
int repeatTime = 3;
Stopwatch sw = new Stopwatch();
do
{
try
{
var result = melsecMc.Write(address, writeValue);
if (result.IsSuccess)
{
repeatTime = 0;
}
}
catch (Exception ex)
{
if (repeatTime < 0)
{
// LogAsync(DateTime.Now, LogLevel.Exception, $"{Name}数据写入异常:{ex.GetExceptionMessage()}");
}
}
} while (repeatTime > 0);
sw.Stop();
// LogAsync(DateTime.Now, LogLevel.Assist, $"{Name} {address},写入{writeValue}完成,耗时:{sw.ElapsedMilliseconds} ms");
}
/// <summary>
/// 写单独地址 float值
/// </summary>
/// <param name="address">地址</param>
/// <param name="writeValue"></param>
/// <param name="waitForReply"></param>
public void WriteFloat(string address, float writeValue, bool waitForReply = true)
{
if (string.IsNullOrEmpty(address))
{
//LogAsync(DateTime.Now, LogLevel.Error, $"{Name} 数据写入参数不能为空!");
return;
}
int repeatTime = 3;
Stopwatch sw = new Stopwatch();
do
{
try
{
var result = melsecMc.Write(address, writeValue);
if (result.IsSuccess)
{
repeatTime = 0;
}
}
catch (Exception ex)
{
if (repeatTime < 0)
{
// LogAsync(DateTime.Now, LogLevel.Exception, $"{Name}数据写入异常:{ex.GetExceptionMessage()}");
}
}
} while (repeatTime > 0);
sw.Stop();
// LogAsync(DateTime.Now, LogLevel.Assist, $"{Name} {address},写入{writeValue}完成,耗时:{sw.ElapsedMilliseconds} ms");
}
#endregion
#region DeviceBase
public void Start()
{
// IConfig.ip
melsecMc = new MelsecMcNet( "192.168.3.39", 502);
// 如果网络不太理想,配置了两个端口,一个有问题,立即切换另一个的话,可以配置如下的代码
// melsecMc.GetPipeSocket().SetMultiPorts(new int[] { 6000, 6001 });
//melsecMc = new HslCommunication.ModBus.ModbusTcpNet();
//melsecMc.IpAddress = "192.168.3.39";
//melsecMc.Port = 502;
//melsecMc.ConnectTimeOut = 10000; // 连接超时,单位毫秒
//melsecMc.ReceiveTimeOut = 5000; // 接收超时,单位毫秒
//melsecMc.Station = 1;
//melsecMc.AddressStartWithZero = true;
//melsecMc.IsStringReverse = false;
//melsecMc.DataFormat = HslCommunication.Core.DataFormat.CDAB;
// melsecMc.ServerStart(6000);
// 连接对象
OperateResult connect = melsecMc.ConnectServer();
if (connect.IsSuccess)
{
Task.Run(() =>
{
HeartbeatMonitor();
});
}
else
{
// LogAsync(DateTime.Now, LogLevel.Exception, $"{Name}已开启异常:{connect.Message}");
}
}
protected void Stop()
{
try
{
// 断开连接
// melsecMc.RemoteStop();
// OmronUDPNet.Stop();
}
catch (Exception ex)
{
// LogAsync(DateTime.Now, LogLevel.Exception, $"{Name}关闭异常:{ex.GetExceptionMessage()}");
}
}
#endregion
#region IMonitor
readonly byte[] scanBuffer = new byte[2048];
public List<int> GetMonitorValues(int startAddress, int length)
{
List<int> res = new List<int>();
// var result = melsecMc.ReadUInt16(startAddress.ToString(), (ushort)length);
// var result = melsecMc.ReadInt32("D" + startAddress, (ushort)length);
var result = melsecMc.ReadInt32("D" + startAddress, (ushort)length);
if (result.IsSuccess)
{
res = new List<int>(result.Content);
}
else
{
//LogAsync(DateTime.Now, LogLevel.Error, $"{Name}未读取到数据:" + "地址W" + startAddress + ";长度:" + length + ";提示:" + result.Message);
}
return res;
}
#endregion
int HeartbeatCycle = 2;
string HeartbeatAddress = "D800";
bool CurrentState = false;
public event Action<int> Heartbeat;
public async void HeartbeatMonitor()
{
if (HeartbeatCycle <= 0)
{
return;
}
await Task.Run(async () =>
{
if (!string.IsNullOrEmpty(HeartbeatAddress)
&& HeartbeatCycle > 0)
{
while (CurrentState != false)
{
if (HeartbeatCycle <= 0)
{
return;
}
try
{
await Task.Delay(HeartbeatCycle * 1000);
var result = melsecMc.Write(HeartbeatAddress, 1);
if (!result.IsSuccess)
{
Heartbeat?.Invoke(1);
//LogAsync(DateTime.Now, LogLevel.Error, $"{this.Name} 心跳监听失败");
}
}
catch (Exception ex)
{
}
}
}
});
}
}

View File

@ -0,0 +1,53 @@

using System;
using System.Collections.Generic;
using System.ComponentModel;
public enum PLCOpType
{
[Description("读取")]
Read = 1,
[Description("写入")]
Write = 2,
[Description("监控")]
Monitor = 4,
/// <summary>
/// 报警监控 1+8
/// </summary>
[Description("报警监控")]
WarningMonitor = 9,
/// <summary>
/// CT监控 1+16
/// </summary>
[Description("CT监控")]
CTMonitor = 17,
}
public class PLCItem
{
/// <summary>
/// 读写地址
/// </summary>
public string Address { get; set; } = "";
/// <summary>
/// 读写地址长度
/// </summary>
public int ItemLength { get; set; } = 1;
/// <summary>
/// PLC项目值
/// </summary>
public List<int> ItemValues { get; set; } = new List<int>();
/// <summary>
/// 是否写数据 1读数据 2写数据 4:监控 参见枚举PLCOpType
/// </summary>
public PLCOpType PLCOpType { get; set; } = PLCOpType.Read;
public DateTime OpTimeStamp { get; set; } = DateTime.Now;
}

View File

@ -0,0 +1,286 @@

using Newtonsoft.Json;
using OpenCvSharp;
using OpenCvSharp.Extensions;
using PaddleOCRSharp;
using STTech.BytesIO.Core;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.ExceptionServices;
using System.Runtime.InteropServices;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using static System.Net.Mime.MediaTypeNames;
using Point = OpenCvSharp.Point;
namespace XKRS.Device.SimboVision.SimboHelper
{
public class SegResult
{
public List<Result> SegmentResult;
public class Result
{
public double fScore;
public int classId;
public string classname;
public double area;
public List<List<int>> rect;
}
}
public class PaddleOcrModel
{
IntPtr Model;
public bool Load(string ModelFile,string Device)
{
bool res = false;
try
{
Model = OcrEngine.InitModel(ModelFile, Device);
res = true;
#if USE_MULTI_THREAD
IsCreated = true;
if (IsCreated)
{
if (_runHandleBefore == null)
{
_runHandleBefore = new AutoResetEvent(false);
}
if (_runHandleAfter == null)
{
_runHandleAfter = new ManualResetEvent(false);
}
if (_runTask == null)
{
_runTask = Task.Factory.StartNew(() =>
{
while (IsCreated)
{
_runHandleBefore.WaitOne();
if (IsCreated)
{
_result = RunInferenceFixed(_req);
_runHandleAfter.Set();
}
}
}, TaskCreationOptions.LongRunning);
}
}
#endif
}
catch (Exception ex)
{
throw ex;
}
return res;
}
#if USE_MULTI_THREAD
MLRequest _req = null;
MLResult _result = null;
public bool IsCreated { get; set; } = false;
Task _runTask = null;
AutoResetEvent _runHandleBefore = new AutoResetEvent(false);
ManualResetEvent _runHandleAfter = new ManualResetEvent(false);
object _runLock = new object();
#endif
[HandleProcessCorruptedStateExceptions]
public MLResultModel RunInference(MLRequest req)
{
#if USE_MULTI_THREAD
MLResult mlResult = null;
lock (_runLock)
{
_result = new MLResult();
_req = req;
_runHandleAfter.Reset();
_runHandleBefore.Set();
_runHandleAfter.WaitOne();
mlResult = _result;
}
return mlResult;
#else
return RunInferenceFixed(req);
#endif
}
private void ConvertJsonResult(string json, ref MLResultModel result)
{
// json = "{\"FastDetResult\":[{\"cls_id\":0,\"cls\":\"liewen\",\"fScore\":0.654843,\"rect\":[175,99,110,594]},{\"cls_id\":0,\"cls\":\"liewen\",\"fScore\":0.654589,\"rect\":[2608,19,104,661]},{\"cls_id\":0,\"cls\":\"liewen\",\"fScore\":0.654285,\"rect\":[1275,19,104,662]},{\"cls_id\":0,\"cls\":\"liewen\",\"fScore\":0.620762,\"rect\":[1510,95,107,600]},{\"cls_id\":0,\"cls\":\"liewen\",\"fScore\":0.617812,\"rect\":[2844,93,106,602]}]}";
//
Console.WriteLine("检测结果JSON" + json);
SegResult detResult = JsonConvert.DeserializeObject<SegResult>(json);
if (detResult == null)
{
return;
}
int iNum = detResult.SegmentResult.Count;
int IokNum = 0;
for (int ix = 0; ix < iNum; ix++)
{
var det = detResult.SegmentResult[ix];
var rect = det.rect;
List<Point> points = new List<Point>();
List<float> maxYs = new List<float>();
//把字体打印在矩形框的下面考虑矩形框最靠下的角点Y值不能超过边框值 否则就往上写
for (int n = 0; n < det.rect.Count(); n++)
{
points.Add(new Point(det.rect[n][0], det.rect[n][1]));
maxYs.Add(det.rect[n][1]);
}
// 定义矩形左上角和右下角的坐标
Point topLeft = points[0];
Point bottomRight = points[2];
// 计算矩形的长和宽
int width = bottomRight.X - topLeft.X;//矩形宽度
int height = bottomRight.Y - topLeft.Y;//矩形高度
//下面定义一个矩形区域,以后在这个矩形里画上白底黑字
float rectX = points[0].X;
float rectY = points[0].Y;
float rectWidth = width;
float rectHeight = height;
if(det.classname!="")
{
DetectionResultDetail detectionResultDetail = new DetectionResultDetail();
detectionResultDetail.LabelNo = det.classId;
//todo: 标签名相对应
detectionResultDetail.LabelDisplay = det.classname;
detectionResultDetail.Rect = new Rectangle(rectX.ToInt(), rectY.ToInt(), rectWidth.ToInt(), rectHeight.ToInt());
detectionResultDetail.Score = det.fScore;
detectionResultDetail.LabelName = det.classname;
detectionResultDetail.Area = det.area;
result.ResultDetails.Add(detectionResultDetail);
}
}
}
[HandleProcessCorruptedStateExceptions]
public MLResultModel RunInferenceFixed(MLRequest req)
{
MLResultModel mlResult = new MLResultModel();
Mat originMat = new Mat();
try
{
originMat = req.currentMat;//1ms
int iWidth = originMat.Cols;
int iHeight = originMat.Rows;
//输入数据转化为字节
var inputByte = new byte[originMat.Total() * 3];//这里必须乘以通道数不然数组越界也可以用w*h*c差不多
Marshal.Copy(originMat.Data, inputByte, 0, inputByte.Length);
byte[] labellist = new byte[20480]; //新建字节数组label1_str label2_str
byte[] outputByte = new byte[originMat.Total() * 3];
Stopwatch sw = new Stopwatch();
sw.Start();
unsafe
{
mlResult.IsSuccess = OcrEngine.Inference(Model, inputByte, iWidth, iHeight, 3, ref outputByte[0], ref labellist[0]);
}
sw.Stop();
if (mlResult.IsSuccess)
{
mlResult.ResultMessage = $"深度学习推理成功,耗时:{sw.ElapsedMilliseconds} ms";
Mat maskWeighted = new Mat(iHeight, iWidth, MatType.CV_8UC3, outputByte);
mlResult.ResultMap = BitmapConverter.ToBitmap(maskWeighted);//4ms
//将字节数组转换为字符串
mlResult.ResultMap = originMat.ToBitmap();//4ms
string strGet = System.Text.Encoding.Default.GetString(labellist, 0, labellist.Length);
Console.WriteLine("strGet:", strGet);
ConvertJsonResult(strGet, ref mlResult);
maskWeighted?.Dispose();
maskWeighted = null;
//解析json字符串
return mlResult;
}
else
{
mlResult.ResultMessage = $"异常:深度学习执行推理失败!";
return mlResult;
}
}
catch (Exception ex)
{
mlResult.ResultMessage = $"深度学习执行推理异常:{ex.Message}";
return mlResult;
}
finally
{
originMat?.Dispose();
originMat = null;
// GC.Collect();
}
}
[HandleProcessCorruptedStateExceptions]
public void FreeModel()
{
OcrEngine.FreePredictor(Model);
}
}
}

View File

@ -0,0 +1,304 @@

using Newtonsoft.Json;
using OpenCvSharp;
using OpenCvSharp.Extensions;
using PaddleOCRSharp;
using STTech.BytesIO.Core;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.ExceptionServices;
using System.Runtime.InteropServices;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using static System.Net.Mime.MediaTypeNames;
using Point = OpenCvSharp.Point;
namespace XKRS.Device.SimboVision.SimboHelper
{
public class SegResultCountry
{
public List<ResultCountry> SegmentResult;
public class ResultCountry
{
public double fScore;
public int classId;
public string classname;
public double area;
public List<List<int>> rect;
}
}
public class PaddleOcrModelCountry
{
IntPtr Model;
public bool Load(string ModelFile,string Device)
{
bool res = false;
try
{
Model = OcrEngine.InitModel(ModelFile, Device);
res = true;
#if USE_MULTI_THREAD
IsCreated = true;
if (IsCreated)
{
if (_runHandleBefore == null)
{
_runHandleBefore = new AutoResetEvent(false);
}
if (_runHandleAfter == null)
{
_runHandleAfter = new ManualResetEvent(false);
}
if (_runTask == null)
{
_runTask = Task.Factory.StartNew(() =>
{
while (IsCreated)
{
_runHandleBefore.WaitOne();
if (IsCreated)
{
_result = RunInferenceFixed(_req);
_runHandleAfter.Set();
}
}
}, TaskCreationOptions.LongRunning);
}
}
#endif
}
catch (Exception ex)
{
throw ex;
}
return res;
}
#if USE_MULTI_THREAD
MLRequest _req = null;
MLResult _result = null;
public bool IsCreated { get; set; } = false;
Task _runTask = null;
AutoResetEvent _runHandleBefore = new AutoResetEvent(false);
ManualResetEvent _runHandleAfter = new ManualResetEvent(false);
object _runLock = new object();
#endif
[HandleProcessCorruptedStateExceptions]
public MLResultModel RunInference(MLRequest req)
{
#if USE_MULTI_THREAD
MLResult mlResult = null;
lock (_runLock)
{
_result = new MLResult();
_req = req;
_runHandleAfter.Reset();
_runHandleBefore.Set();
_runHandleAfter.WaitOne();
mlResult = _result;
}
return mlResult;
#else
return RunInferenceFixed(req);
#endif
}
private void ConvertJsonResult(string json, ref MLResultModel result)
{
// json = "{\"FastDetResult\":[{\"cls_id\":0,\"cls\":\"liewen\",\"fScore\":0.654843,\"rect\":[175,99,110,594]},{\"cls_id\":0,\"cls\":\"liewen\",\"fScore\":0.654589,\"rect\":[2608,19,104,661]},{\"cls_id\":0,\"cls\":\"liewen\",\"fScore\":0.654285,\"rect\":[1275,19,104,662]},{\"cls_id\":0,\"cls\":\"liewen\",\"fScore\":0.620762,\"rect\":[1510,95,107,600]},{\"cls_id\":0,\"cls\":\"liewen\",\"fScore\":0.617812,\"rect\":[2844,93,106,602]}]}";
//
Console.WriteLine("检测结果JSON" + json);
SegResultCountry detResult = JsonConvert.DeserializeObject<SegResultCountry>(json);
if (detResult == null)
{
return;
}
int iNum = detResult.SegmentResult.Count;
int IokNum = 0;
for (int ix = 0; ix < iNum; ix++)
{
var det = detResult.SegmentResult[ix];
var rect = det.rect;
List<Point> points = new List<Point>();
List<float> maxYs = new List<float>();
//把字体打印在矩形框的下面考虑矩形框最靠下的角点Y值不能超过边框值 否则就往上写
for (int n = 0; n < det.rect.Count(); n++)
{
points.Add(new Point(det.rect[n][0], det.rect[n][1]));
maxYs.Add(det.rect[n][1]);
}
// 定义矩形左上角和右下角的坐标
Point topLeft = points[0];
Point bottomRight = points[2];
// 计算矩形的长和宽
int width = bottomRight.X - topLeft.X;//矩形宽度
int height = bottomRight.Y - topLeft.Y;//矩形高度
//下面定义一个矩形区域,以后在这个矩形里画上白底黑字
float rectX = points[0].X;
float rectY = points[0].Y;
float rectWidth = width;
float rectHeight = height;
DetectionResultDetail detectionResultDetail = new DetectionResultDetail();
detectionResultDetail.LabelNo = det.classId;
//todo: 标签名相对应
detectionResultDetail.LabelDisplay = det.classname;
detectionResultDetail.Rect = new Rectangle(rectX.ToInt(), rectY.ToInt(), rectWidth.ToInt(), rectHeight.ToInt());
detectionResultDetail.Score = det.fScore;
detectionResultDetail.LabelName = det.classname;
detectionResultDetail.Area = det.area;
result.ResultDetails.Add(detectionResultDetail);
//if (det.classname.Contains("Model:") || det.classname.Contains("Batch:"))
//{
// string[] sArray = Regex.Split(det.classname, "Model:", RegexOptions.IgnoreCase);
// string splitBar = "";
// if (sArray.Count() > 1)
// {
// result.WashMachineBar = sArray[1];
// string[] aBatch = Regex.Split(sArray[0], "Batch:", RegexOptions.IgnoreCase);
// if (aBatch.Count() > 1)
// {
// result.WashMachineBatch = aBatch[1];
// }
// }
//}
//if (det.classname.Contains("SN:") )
//{
// string[] sArray = Regex.Split(det.classname, "SN:", RegexOptions.IgnoreCase);
// string splitBar = "";
// if (sArray.Count() > 1)
// {
// result.WashMachineSN = sArray[1];
// }
//}
}
}
[HandleProcessCorruptedStateExceptions]
public MLResultModel RunInferenceFixed(MLRequest req)
{
MLResultModel mlResult = new MLResultModel();
Mat originMat = new Mat();
try
{
originMat = req.currentMat;//1ms
int iWidth = originMat.Cols;
int iHeight = originMat.Rows;
//输入数据转化为字节
var inputByte = new byte[originMat.Total() * 3];//这里必须乘以通道数不然数组越界也可以用w*h*c差不多
Marshal.Copy(originMat.Data, inputByte, 0, inputByte.Length);
byte[] labellist = new byte[20480]; //新建字节数组label1_str label2_str
byte[] outputByte = new byte[originMat.Total() * 3];
Stopwatch sw = new Stopwatch();
sw.Start();
unsafe
{
mlResult.IsSuccess = OcrEngine.Inference(Model, inputByte, iWidth, iHeight, 3, ref outputByte[0], ref labellist[0]);
}
sw.Stop();
if (mlResult.IsSuccess)
{
mlResult.ResultMessage = $"深度学习推理成功,耗时:{sw.ElapsedMilliseconds} ms";
Mat maskWeighted = new Mat(iHeight, iWidth, MatType.CV_8UC3, outputByte);
mlResult.ResultMap = BitmapConverter.ToBitmap(maskWeighted);//4ms
//将字节数组转换为字符串
mlResult.ResultMap = originMat.ToBitmap();//4ms
string strGet = System.Text.Encoding.Default.GetString(labellist, 0, labellist.Length);
Console.WriteLine("strGet:", strGet);
ConvertJsonResult(strGet, ref mlResult);
maskWeighted?.Dispose();
maskWeighted = null;
//解析json字符串
return mlResult;
}
else
{
mlResult.ResultMessage = $"异常:深度学习执行推理失败!";
return mlResult;
}
}
catch (Exception ex)
{
mlResult.ResultMessage = $"深度学习执行推理异常:{ex.Message}";
return mlResult;
}
finally
{
//originMat?.Dispose();
//originMat = null;
// GC.Collect();
}
}
public void FreeModel()
{
OcrEngine.FreePredictor(Model);
}
}
}

View File

@ -0,0 +1,68 @@
namespace HisenceYoloDetection
{
internal static class Program
{
static MainForm? mainFrm = null;
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
try
{
// To customize application configuration such as set high DPI settings or default font,
// see https://aka.ms/applicationconfiguration.
ApplicationConfiguration.Initialize();
mainFrm = new MainForm();
Application.Run(mainFrm);
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
Application.ThreadException += Application_ThreadException;
}catch (Exception ex)
{
}
}
private static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e)
{
string msg = e.Exception.Message;
using (StreamWriter sw = new StreamWriter("D://ThreadException.log", true))
{
sw.WriteLine("================================");
sw.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"));
sw.WriteLine(msg);
sw.Flush();
}
if (mainFrm != null)
{
// mainFrm.DockFrm_OnLogMsgOutput(new LogMsg(DateTime.Now, EnumHelper.LogLevel.Exception, msg));
}
//MessageBox.Show(msg, "线程异常报警");
}
private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
string msg = (e.ExceptionObject as Exception).Message;
using (StreamWriter sw = new StreamWriter("D://UnhandledException.log", true))
{
sw.WriteLine("================================");
sw.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"));
sw.WriteLine(msg);
sw.Flush();
}
if (mainFrm != null)
{
//mainFrm.DockFrm_OnLogMsgOutput(new LogMsg(DateTime.Now, EnumHelper.LogLevel.Exception, msg));
//MessageBox.Show(msg, "未处理异常");
}
}
}
}

View File

@ -0,0 +1,63 @@
//------------------------------------------------------------------------------
// <auto-generated>
// 此代码由工具生成。
// 运行时版本:4.0.30319.42000
//
// 对此文件的更改可能会导致不正确的行为,并且如果
// 重新生成代码,这些更改将会丢失。
// </auto-generated>
//------------------------------------------------------------------------------
namespace HisenceYoloDetection.Properties {
using System;
/// <summary>
/// 一个强类型的资源类,用于查找本地化的字符串等。
/// </summary>
// 此类是由 StronglyTypedResourceBuilder
// 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。
// 若要添加或移除成员,请编辑 .ResX 文件,然后重新运行 ResGen
// (以 /str 作为命令选项),或重新生成 VS 项目。
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Resources() {
}
/// <summary>
/// 返回此类使用的缓存的 ResourceManager 实例。
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("HisenceYoloDetection.Properties.Resources", typeof(Resources).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// 重写当前线程的 CurrentUICulture 属性,对
/// 使用此强类型资源类的所有资源查找执行重写。
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
}
}

View File

@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@ -0,0 +1,612 @@
using System;
using System.Collections;
using System.Collections.Specialized;
using System.Data;
using System.Data.SQLite;
using System.Configuration;
public class SQLiteHelper
{
//数据库连接字符串
// public static string connectionString = ConfigurationManager.ConnectionStrings["ProcessDB"].ConnectionString;
public static string connectionString = "Data Source = D:\\Hisence\\DataBase\\ProcessDB.db;BinaryGUID=False;";
// public SQLiteHelper() { }
#region
public static int GetMaxID(string FieldName, string TableName)
{
string strsql = "select max(" + FieldName + ")+1 from " + TableName;
object obj = GetSingle(strsql);
if (obj == null)
{
return 1;
}
else
{
return int.Parse(obj.ToString());
}
}
public static bool Exists(string strSql)
{
object obj = GetSingle(strSql);
int cmdresult;
if ((Object.Equals(obj, null)) || (Object.Equals(obj, System.DBNull.Value)))
{
cmdresult = 0;
}
else
{
cmdresult = int.Parse(obj.ToString());
}
if (cmdresult == 0)
{
return false;
}
else
{
return true;
}
}
public static bool Exists(string strSql, params SQLiteParameter[] cmdParms)
{
object obj = GetSingle(strSql, cmdParms);
int cmdresult;
if ((Object.Equals(obj, null)) || (Object.Equals(obj, System.DBNull.Value)))
{
cmdresult = 0;
}
else
{
cmdresult = int.Parse(obj.ToString());
}
if (cmdresult == 0)
{
return false;
}
else
{
return true;
}
}
#endregion
#region SQL语句
/// <summary>
/// 执行SQL语句返回影响的记录数
/// </summary>
/// <param name="SQLString">SQL语句</param>
/// <returns>影响的记录数</returns>
public static int ExecuteSql(string SQLString)
{
using (SQLiteConnection connection = new SQLiteConnection(connectionString))
{
using (SQLiteCommand cmd = new SQLiteCommand(SQLString, connection))
{
try
{
connection.Open();
int rows = cmd.ExecuteNonQuery();
return rows;
}
catch (System.Data.SQLite.SQLiteException E)
{
connection.Close();
throw new Exception(E.Message);
}
}
}
}
/// <summary>
/// 执行SQL语句设置命令的执行等待时间
/// </summary>
/// <param name="SQLString"></param>
/// <param name="Times"></param>
/// <returns></returns>
public static int ExecuteSqlByTime(string SQLString, int Times)
{
using (SQLiteConnection connection = new SQLiteConnection(connectionString))
{
using (SQLiteCommand cmd = new SQLiteCommand(SQLString, connection))
{
try
{
connection.Open();
cmd.CommandTimeout = Times;
int rows = cmd.ExecuteNonQuery();
return rows;
}
catch (System.Data.SQLite.SQLiteException E)
{
connection.Close();
throw new Exception(E.Message);
}
}
}
}
/// <summary>
/// 执行多条SQL语句实现数据库事务。
/// </summary>
/// <param name="SQLStringList">多条SQL语句</param>
public static bool ExecuteSqlTran(ArrayList SQLStringList)
{
bool isSuccess = false;
using (SQLiteConnection conn = new SQLiteConnection(connectionString))
{
conn.Open();
SQLiteCommand cmd = new SQLiteCommand();
cmd.Connection = conn;
cmd.CommandText = "PRAGMA synchronous = OFF;";
cmd.ExecuteNonQuery();
SQLiteTransaction tx = conn.BeginTransaction();
cmd.Transaction = tx;
try
{
for (int n = 0; n < SQLStringList.Count; n++)
{
string strsql = SQLStringList[n].ToString();
if (strsql.Trim().Length > 1)
{
cmd.CommandText = strsql;
cmd.ExecuteNonQuery();
}
}
tx.Commit();
isSuccess = true;
}
catch (System.Data.SQLite.SQLiteException E)
{
tx.Rollback();
isSuccess = false;
throw new Exception(E.Message);
}
}
return isSuccess;
}
/// <summary>
/// 执行带一个存储过程参数的的SQL语句。
/// </summary>
/// <param name="SQLString">SQL语句</param>
/// <param name="content">参数内容,比如一个字段是格式复杂的文章,有特殊符号,可以通过这个方式添加</param>
/// <returns>影响的记录数</returns>
public static int ExecuteSql(string SQLString, string content)
{
using (SQLiteConnection connection = new SQLiteConnection(connectionString))
{
SQLiteCommand cmd = new SQLiteCommand(SQLString, connection);
SQLiteParameter myParameter = new SQLiteParameter("@content", DbType.String);
myParameter.Value = content;
cmd.Parameters.Add(myParameter);
try
{
connection.Open();
int rows = cmd.ExecuteNonQuery();
return rows;
}
catch (System.Data.SQLite.SQLiteException E)
{
throw new Exception(E.Message);
}
finally
{
cmd.Dispose();
connection.Close();
}
}
}
/// <summary>
/// 执行带一个存储过程参数的的SQL语句。
/// </summary>
/// <param name="SQLString">SQL语句</param>
/// <param name="content">参数内容,比如一个字段是格式复杂的文章,有特殊符号,可以通过这个方式添加</param>
/// <returns>影响的记录数</returns>
public static object ExecuteSqlGet(string SQLString, string content)
{
using (SQLiteConnection connection = new SQLiteConnection(connectionString))
{
SQLiteCommand cmd = new SQLiteCommand(SQLString, connection);
SQLiteParameter myParameter = new SQLiteParameter("@content", DbType.String);
myParameter.Value = content;
cmd.Parameters.Add(myParameter);
try
{
connection.Open();
object obj = cmd.ExecuteScalar();
if ((Object.Equals(obj, null)) || (Object.Equals(obj, System.DBNull.Value)))
{
return null;
}
else
{
return obj;
}
}
catch (System.Data.SQLite.SQLiteException E)
{
throw new Exception(E.Message);
}
finally
{
cmd.Dispose();
connection.Close();
}
}
}
/// <summary>
/// 向数据库里插入图像格式的字段(和上面情况类似的另一种实例)
/// </summary>
/// <param name="strSQL">SQL语句</param>
/// <param name="fs">图像字节,数据库的字段类型为image的情况</param>
/// <returns>影响的记录数</returns>
public static int ExecuteSqlInsertImg(string strSQL, byte[] fs)
{
using (SQLiteConnection connection = new SQLiteConnection(connectionString))
{
SQLiteCommand cmd = new SQLiteCommand(strSQL, connection);
SQLiteParameter myParameter = new SQLiteParameter("@fs", DbType.Binary);
myParameter.Value = fs;
cmd.Parameters.Add(myParameter);
try
{
connection.Open();
int rows = cmd.ExecuteNonQuery();
return rows;
}
catch (System.Data.SQLite.SQLiteException E)
{
throw new Exception(E.Message);
}
finally
{
cmd.Dispose();
connection.Close();
}
}
}
/// <summary>
/// 执行一条计算查询结果语句返回查询结果object
/// </summary>
/// <param name="SQLString">计算查询结果语句</param>
/// <returns>查询结果object</returns>
public static object GetSingle(string SQLString)
{
using (SQLiteConnection connection = new SQLiteConnection(connectionString))
{
using (SQLiteCommand cmd = new SQLiteCommand(SQLString, connection))
{
try
{
connection.Open();
object obj = cmd.ExecuteScalar();
if ((Object.Equals(obj, null)) || (Object.Equals(obj, System.DBNull.Value)))
{
return null;
}
else
{
return obj;
}
}
catch (System.Data.SQLite.SQLiteException e)
{
connection.Close();
throw new Exception(e.Message);
}
}
}
}
/// <summary>
/// 执行查询语句返回SQLiteDataReader(使用该方法切记要手工关闭SQLiteDataReader和连接)
/// </summary>
/// <param name="strSQL">查询语句</param>
/// <returns>SQLiteDataReader</returns>
public static SQLiteDataReader ExecuteReader(string strSQL)
{
SQLiteConnection connection = new SQLiteConnection(connectionString);
SQLiteCommand cmd = new SQLiteCommand(strSQL, connection);
try
{
connection.Open();
SQLiteDataReader myReader = cmd.ExecuteReader();
return myReader;
}
catch (System.Data.SQLite.SQLiteException e)
{
throw new Exception(e.Message);
}
//finally //不能在此关闭,否则,返回的对象将无法使用
//{
// cmd.Dispose();
// connection.Close();
//}
}
/// <summary>
/// 执行查询语句返回DataSet
/// </summary>
/// <param name="SQLString">查询语句</param>
/// <returns>DataSet</returns>
public static DataSet Query(string SQLString)
{
using (SQLiteConnection connection = new SQLiteConnection(connectionString))
{
DataSet ds = new DataSet();
try
{
connection.Open();
SQLiteDataAdapter command = new SQLiteDataAdapter(SQLString, connection);
command.Fill(ds, "ds");
connection.Close();
command.Dispose();
}
catch (System.Data.SQLite.SQLiteException ex)
{
throw new Exception(ex.Message);
}
return ds;
}
}
public static DataSet Query(string SQLString, string TableName)
{
using (SQLiteConnection connection = new SQLiteConnection(connectionString))
{
DataSet ds = new DataSet();
try
{
connection.Open();
SQLiteDataAdapter command = new SQLiteDataAdapter(SQLString, connection);
command.Fill(ds, TableName);
}
catch (System.Data.SQLite.SQLiteException ex)
{
throw new Exception(ex.Message);
}
return ds;
}
}
/// <summary>
/// 执行查询语句返回DataSet,设置命令的执行等待时间
/// </summary>
/// <param name="SQLString"></param>
/// <param name="Times"></param>
/// <returns></returns>
public static DataSet Query(string SQLString, int Times)
{
using (SQLiteConnection connection = new SQLiteConnection(connectionString))
{
DataSet ds = new DataSet();
try
{
connection.Open();
SQLiteDataAdapter command = new SQLiteDataAdapter(SQLString, connection);
command.SelectCommand.CommandTimeout = Times;
command.Fill(ds, "ds");
}
catch (System.Data.SQLite.SQLiteException ex)
{
throw new Exception(ex.Message);
}
return ds;
}
}
#endregion
#region SQL语句
/// <summary>
/// 执行SQL语句返回影响的记录数
/// </summary>
/// <param name="SQLString">SQL语句</param>
/// <returns>影响的记录数</returns>
public static int ExecuteSql(string SQLString, params SQLiteParameter[] cmdParms)
{
using (SQLiteConnection connection = new SQLiteConnection(connectionString))
{
using (SQLiteCommand cmd = new SQLiteCommand())
{
try
{
PrepareCommand(cmd, connection, null, SQLString, cmdParms);
int rows = cmd.ExecuteNonQuery();
cmd.Parameters.Clear();
return rows;
}
catch (System.Data.SQLite.SQLiteException E)
{
throw new Exception(E.Message);
}
}
}
}
/// <summary>
/// 执行多条SQL语句实现数据库事务。
/// </summary>
/// <param name="SQLStringList">SQL语句的哈希表key为sql语句value是该语句的SQLiteParameter[]</param>
public static void ExecuteSqlTran(Hashtable SQLStringList)
{
using (SQLiteConnection conn = new SQLiteConnection(connectionString))
{
conn.Open();
using (SQLiteTransaction trans = conn.BeginTransaction())
{
SQLiteCommand cmd = new SQLiteCommand();
try
{
//循环
foreach (DictionaryEntry myDE in SQLStringList)
{
string cmdText = myDE.Key.ToString();
SQLiteParameter[] cmdParms = (SQLiteParameter[])myDE.Value;
PrepareCommand(cmd, conn, trans, cmdText, cmdParms);
int val = cmd.ExecuteNonQuery();
cmd.Parameters.Clear();
}
trans.Commit();
}
catch (System.Data.SQLite.SQLiteException e)
{
trans.Rollback();
throw new Exception(e.Message);
}
}
}
}
/// <summary>
/// 执行一条计算查询结果语句返回查询结果object
/// </summary>
/// <param name="SQLString">计算查询结果语句</param>
/// <returns>查询结果object</returns>
public static object GetSingle(string SQLString, params SQLiteParameter[] cmdParms)
{
using (SQLiteConnection connection = new SQLiteConnection(connectionString))
{
using (SQLiteCommand cmd = new SQLiteCommand())
{
try
{
PrepareCommand(cmd, connection, null, SQLString, cmdParms);
object obj = cmd.ExecuteScalar();
cmd.Parameters.Clear();
if ((Object.Equals(obj, null)) || (Object.Equals(obj, System.DBNull.Value)))
{
return null;
}
else
{
return obj;
}
}
catch (System.Data.SQLite.SQLiteException e)
{
throw new Exception(e.Message);
}
}
}
}
/// <summary>
/// 执行查询语句返回SQLiteDataReader (使用该方法切记要手工关闭SQLiteDataReader和连接)
/// </summary>
/// <param name="strSQL">查询语句</param>
/// <returns>SQLiteDataReader</returns>
public static SQLiteDataReader ExecuteReader(string SQLString, params SQLiteParameter[] cmdParms)
{
SQLiteConnection connection = new SQLiteConnection(connectionString);
SQLiteCommand cmd = new SQLiteCommand();
try
{
PrepareCommand(cmd, connection, null, SQLString, cmdParms);
SQLiteDataReader myReader = cmd.ExecuteReader();
cmd.Parameters.Clear();
return myReader;
}
catch (System.Data.SQLite.SQLiteException e)
{
throw new Exception(e.Message);
}
//finally //不能在此关闭,否则,返回的对象将无法使用
//{
// cmd.Dispose();
// connection.Close();
//}
}
/// <summary>
/// 执行查询语句返回DataSet
/// </summary>
/// <param name="SQLString">查询语句</param>
/// <returns>DataSet</returns>
public static DataSet Query(string SQLString, params SQLiteParameter[] cmdParms)
{
using (SQLiteConnection connection = new SQLiteConnection(connectionString))
{
SQLiteCommand cmd = new SQLiteCommand();
PrepareCommand(cmd, connection, null, SQLString, cmdParms);
using (SQLiteDataAdapter da = new SQLiteDataAdapter(cmd))
{
DataSet ds = new DataSet();
try
{
da.Fill(ds, "ds");
cmd.Parameters.Clear();
}
catch (System.Data.SQLite.SQLiteException ex)
{
throw new Exception(ex.Message);
}
return ds;
}
}
}
public static void PrepareCommand(SQLiteCommand cmd, SQLiteConnection conn,
SQLiteTransaction trans, string cmdText, SQLiteParameter[] cmdParms)
{
if (conn.State != ConnectionState.Open)
conn.Open();
cmd.Connection = conn;
cmd.CommandText = cmdText;
if (trans != null)
cmd.Transaction = trans;
cmd.CommandType = CommandType.Text;//cmdType;
if (cmdParms != null)
{
foreach (SQLiteParameter parameter in cmdParms)
{
if ((parameter.Direction == ParameterDirection.InputOutput
|| parameter.Direction == ParameterDirection.Input) &&
(parameter.Value == null))
{
parameter.Value = DBNull.Value;
}
cmd.Parameters.Add(parameter);
}
}
}
#endregion
#region
/// <summary>
/// 放回一个SQLiteParameter
/// </summary>
/// <param name="name">参数名字</param>
/// <param name="type">参数类型</param>
/// <param name="size">参数大小</param>
/// <param name="value">参数值</param>
/// <returns>SQLiteParameter的值</returns>
public static SQLiteParameter MakeSQLiteParameter(string name,
DbType type, int size, object value)
{
SQLiteParameter parm = new SQLiteParameter(name, type, size);
parm.Value = value;
return parm;
}
public static SQLiteParameter MakeSQLiteParameter(string name, DbType type, object value)
{
SQLiteParameter parm = new SQLiteParameter(name, type);
parm.Value = value;
return parm;
}
#endregion
}

View File

@ -0,0 +1,268 @@

using OpenCvSharp;
using OpenCvSharp.Extensions;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Runtime.ExceptionServices;
using System.Threading;
using System.Threading.Tasks;
using System.Runtime.InteropServices;
using Newtonsoft.Json;
public class SegResult
{
public List<Result> SegmentResult;
public class Result
{
public double fScore;
public int classId;
public string classname;
public double area;
public List<int> rect;
}
}
/// <summary>
/// 实例分割 maskrcnn
/// </summary>
public class SimboObjectDetection
{
IntPtr Model;
public bool Load(string ModelFile, string InferenceDevice, string InputNodeName, int InferenceWidth, int InferenceHeight)
{
bool res = false;
try
{
Model = MLEngine.InitModel(ModelFile,
InferenceDevice,
InputNodeName,
1, 3,
InferenceWidth,
InferenceHeight);
res = true;
#if USE_MULTI_THREAD
IsCreated = true;
if (IsCreated)
{
if (_runHandleBefore == null)
{
_runHandleBefore = new AutoResetEvent(false);
}
if (_runHandleAfter == null)
{
_runHandleAfter = new ManualResetEvent(false);
}
if (_runTask == null)
{
_runTask = Task.Factory.StartNew(() =>
{
while (IsCreated)
{
_runHandleBefore.WaitOne();
if (IsCreated)
{
_result = RunInferenceFixed(_req);
_runHandleAfter.Set();
}
}
}, TaskCreationOptions.LongRunning);
}
}
#endif
}
catch (Exception ex)
{
throw ex;
}
return res;
}
#if USE_MULTI_THREAD
MLRequest _req = null;
MLResult _result = null;
public bool IsCreated { get; set; } = false;
Task _runTask = null;
AutoResetEvent _runHandleBefore = new AutoResetEvent(false);
ManualResetEvent _runHandleAfter = new ManualResetEvent(false);
object _runLock = new object();
#endif
[HandleProcessCorruptedStateExceptions]
public MLResult RunInference(MLRequest req)
{
#if USE_MULTI_THREAD
MLResult mlResult = null;
lock (_runLock)
{
_result = new MLResult();
_req = req;
_runHandleAfter.Reset();
_runHandleBefore.Set();
_runHandleAfter.WaitOne();
mlResult = _result;
}
return mlResult;
#else
return RunInferenceFixed(req);
#endif
}
private void ConvertJsonResult(string json, ref MLResult result)
{
// json = "{\"FastDetResult\":[{\"cls_id\":0,\"cls\":\"liewen\",\"fScore\":0.654843,\"rect\":[175,99,110,594]},{\"cls_id\":0,\"cls\":\"liewen\",\"fScore\":0.654589,\"rect\":[2608,19,104,661]},{\"cls_id\":0,\"cls\":\"liewen\",\"fScore\":0.654285,\"rect\":[1275,19,104,662]},{\"cls_id\":0,\"cls\":\"liewen\",\"fScore\":0.620762,\"rect\":[1510,95,107,600]},{\"cls_id\":0,\"cls\":\"liewen\",\"fScore\":0.617812,\"rect\":[2844,93,106,602]}]}";
//
Console.WriteLine("检测结果JSON" + json);
SegResult detResult = JsonConvert.DeserializeObject<SegResult>(json);
if (detResult == null)
{
return;
}
int iNum = detResult.SegmentResult.Count;
int IokNum = 0;
for (int ix = 0; ix < iNum; ix++)
{
var det = detResult.SegmentResult[ix];
var rect = det.rect;
DetectionResultDetail detectionResultDetail = new DetectionResultDetail();
detectionResultDetail.LabelNo = det.classId;
//todo: 标签名相对应
detectionResultDetail.LabelDisplay = det.classname;
detectionResultDetail.Rect = new Rectangle(rect[0], rect[1], rect[2], rect[3]);
detectionResultDetail.Score = det.fScore;
detectionResultDetail.LabelName = det.classname;
detectionResultDetail.Area = det.area;
// detectionResultDetail.InferenceResult = ResultState.NG;
result.ResultDetails.Add(detectionResultDetail);
}
}
[HandleProcessCorruptedStateExceptions]
public MLResult RunInferenceFixed(MLRequest req)
{
MLResult mlResult = new MLResult();
Mat originMat = new Mat();
try
{
// resize
originMat = req.currentMat;//1ms
int iWidth = originMat.Cols;
int iHeight = originMat.Rows;
//输入数据转化为字节
var inputByte = new byte[originMat.Total() * 3];//这里必须乘以通道数不然数组越界也可以用w*h*c差不多
Marshal.Copy(originMat.Data, inputByte, 0, inputByte.Length);
byte[] labellist = new byte[20480]; //新建字节数组label1_str label2_str
byte[] outputByte = new byte[originMat.Total() * 3];
Stopwatch sw = new Stopwatch();
sw.Start();
unsafe
{
mlResult.IsSuccess = MLEngine.det_ModelPredict(Model,
inputByte,
iWidth, iHeight, 3,
req.out_node_name,
req.in_lable_path,
req.confThreshold, req.iouThreshold,
ref outputByte[0],
ref labellist[0]);
//mlResult.IsSuccess = true;
}
sw.Stop();
if (mlResult.IsSuccess)
{
mlResult.ResultMessage = $"深度学习推理成功,耗时:{sw.ElapsedMilliseconds} ms";
Mat maskWeighted = new Mat(iHeight, iWidth, MatType.CV_8UC3, outputByte);
mlResult.ResultMap = BitmapConverter.ToBitmap(maskWeighted);//4ms
//将字节数组转换为字符串
// mlResult.ResultMap = originMat.ToBitmap();//4ms
string strGet = System.Text.Encoding.Default.GetString(labellist, 0, labellist.Length);
Console.WriteLine("strGet:", strGet);
ConvertJsonResult(strGet, ref mlResult);
maskWeighted?.Dispose();
maskWeighted = null;
// 解析json字符串
return mlResult;
}
else
{
mlResult.ResultMessage = $"异常:深度学习执行推理失败!";
return mlResult;
}
}
catch (Exception ex)
{
//mlResult.ResultMessage = $"深度学习执行推理异常:{ex.GetExceptionMessage()}";
return mlResult;
}
finally
{
// originMat?.Dispose();
// originMat = null;
// GC.Collect();
}
}
}

View File

@ -0,0 +1,236 @@

using OpenCvSharp;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Runtime.InteropServices;
public class XKHisence
{
public int Number;
public string ?Type;
public string ?OcrBar;
public int MoveX;
public int MoveY;
public int MoveZ;
public string ?Detect;
public string ?OcrText;
public int MoveTwoX;
public int MoveTwoY;
public int MoveTwoZ;
public string ?OcrParm;
public string ?Language;
public XKHisence()
{
}
public XKHisence(String type,string ocrBar,int MoveX,int MoveY,int MoveZ,string Detect,string ocrText,int MoveTwoX,int MoveTwoY,int MoveTwoZ,string OcrParm,string Language)
{
this.Type = type;
this.OcrBar = ocrBar;
this.MoveX = MoveX;
this.MoveY = MoveY;
this.MoveZ= MoveZ;
this.Detect = Detect;
this.OcrText= ocrText;
this.MoveTwoX = MoveTwoX;
this.MoveTwoY = MoveTwoY;
this.MoveTwoZ = MoveTwoZ;
this.OcrParm = OcrParm;
this.Language = Language;
}
}
public class MLRequest
{
public int ImageChannels = 3;
public Mat currentMat;
public int ResizeWidth;
public int ResizeHeight;
public float confThreshold;
public float iouThreshold;
//public int ImageResizeCount;
public string in_node_name;
public string out_node_name;
public string in_lable_path;
public int ResizeImageSize;
public int segmentWidth;
public int ImageWidth;
public float Score;
}
public class DetectionResultDetail
{
public string LabelBGR { get; set; }//识别到对象的标签BGR
public int LabelNo { get; set; } // 识别到对象的标签索引
public string LabelName { get; set; }//识别到对象的标签名称
public double Score { get; set; }//识别目标结果的可能性、得分
public string LabelDisplay { get; set; }//识别到对象的 显示信息
public double Area { get; set; }//识别目标的区域面积
public Rectangle Rect { get; set; }//识别目标的外接矩形
public RotatedRect MinRect { get; set; }//识别目标的最小外接矩形(带角度)
//public ResultState InferenceResult { get; set; }//只是模型推理 label的结果
public double DistanceToImageCenter { get; set; } //计算矩形框到图像中心的距离
// public ResultState FinalResult { get; set; }//模型推理+其他视觉、逻辑判断后 label结果
}
public class MLResult
{
public bool IsSuccess = false;
public string ResultMessage;
public Bitmap ResultMap;
public List<DetectionResultDetail> ResultDetails = new List<DetectionResultDetail>();
}
public class MLResultModel
{
public bool IsSuccess = false;
public string ResultMessage;
public Bitmap ResultMap;
public List<DetectionResultDetail> ResultDetails = new List<DetectionResultDetail>();
public string WashMachineBar;
public string WashMachineBatch;
public string WashMachineSN;
public string WashMachineLanguage;
}
public static class MLEngine
{
//private const string sPath = @"D:\\C#\磁环项目\\OpenVinoYolo\\openvino_Yolov5_v7_v2.0\\openvino_Yolov5_v7\\Program\ConsoleProject\\x64\\Release\\QuickSegmentDynamic.dll";
[DllImport("QuickSegmentDynamic.dll", EntryPoint = "InitModel")]
public static extern IntPtr InitModel(string model_filename, string inferenceDevice, string input_node_name, int bacth, int inferenceChannels, int InferenceWidth, int InferenceHeight);
/// <summary>
/// 分割
/// </summary>
/// <param name="model"></param>
/// <param name="img"></param>
/// <param name="W"></param>
/// <param name="H"></param>
/// <param name="C"></param>
/// <param name="labelText"></param>
/// <param name="conf_threshold"></param>
/// <param name="IOU_THRESHOLD"></param>
/// <param name="fScoreThre"></param>
/// <param name="segmentWidth"></param>
/// <param name="Mask_output"></param>
/// <param name="label"></param>
/// <returns></returns>
[DllImport("QuickSegmentDynamic.dll", EntryPoint = "seg_ModelPredict")]
public static extern bool seg_ModelPredict(IntPtr model, byte[] img, int W, int H, int C,
string labelText, float conf_threshold, float IOU_THRESHOLD, float fScoreThre, int segmentWidth,
ref byte Mask_output, ref byte label);
/// <summary>
/// 目标检测
/// </summary>
/// <param name="model"></param>
/// <param name="img"></param>
/// <param name="W"></param>
/// <param name="H"></param>
/// <param name="C"></param>
/// <param name="nodes"></param>
/// <param name="labelText"></param>
/// <param name="conf_threshold"></param>
/// <param name="IOU_THRESHOLD"></param>
/// <param name="Mask_output"></param>
/// <param name="label"></param>
[DllImport("QuickSegmentDynamic.dll", EntryPoint = "det_ModelPredict")]
public static extern bool det_ModelPredict(IntPtr model, byte[] img, int W, int H, int C,
string nodes,// ++++++++++++++++++++++++++++++++++++
string labelText, float conf_threshold, float IOU_THRESHOLD,
ref byte Mask_output, ref byte label);
[DllImport("QuickSegmentDynamic.dll", EntryPoint = "FreePredictor")]
public static extern void FreePredictor(IntPtr model);
}
public static class OcrEngine
{
// private const string sPath = @"F:\OOOCR\PaddleOCRsourcecodeGPU\PROJECTS\OcrDetForm\bin\Release\net7.0-windows\ocrInference.dll";
[DllImport("ocrInference.dll", EntryPoint = "InitModel")]
public static extern IntPtr InitModel(string model_ParaPath, string device_id);
[DllImport("ocrInference.dll", EntryPoint = "Inference")]
public static extern bool Inference(IntPtr model, byte[] img, int W, int H, int C,
ref byte Mask_output, ref byte label);
[DllImport("ocrInference.dll", EntryPoint = "FreePredictor")]
public static extern void FreePredictor(IntPtr model);
}
public static class MLEngine1
{
/**********************************************************************/
/***************** 1.推理DLL导入实现 ****************/
/**********************************************************************/
//private const string sPath = @"D:\M018_NET7.0\src\Debug\model_infer.dll";
// 加载推理相关方法
[DllImport("model_infer.dll", EntryPoint = "InitModel")] // 模型统一初始化方法: 需要yml、pdmodel、pdiparams
//[DllImport(sPath, EntryPoint = "InitModel")] // 模型统一初始化方法: 需要yml、pdmodel、pdiparams
public static extern IntPtr InitModel(string model_type, string model_filename, string params_filename, string cfg_file, bool use_gpu, int gpu_id, ref byte paddlex_model_type);
[DllImport("model_infer.dll", EntryPoint = "Det_ModelPredict")] // PaddleDetection模型推理方法
public static extern bool Det_ModelPredict(IntPtr model, byte[] img, int W, int H, int C, IntPtr output, int[] BoxesNum, ref byte label);
[DllImport("model_infer.dll", EntryPoint = "Seg_ModelPredict")] // PaddleSeg模型推理方法
public static extern bool Seg_ModelPredict(IntPtr model, byte[] img, int W, int H, int C, ref byte output);
[DllImport("model_infer.dll", EntryPoint = "Cls_ModelPredict")] // PaddleClas模型推理方法
public static extern bool Cls_ModelPredict(IntPtr model, byte[] img, int W, int H, int C, ref float score, ref byte category, ref int category_id);
[DllImport("model_infer.dll", EntryPoint = "Mask_ModelPredict")] // Paddlex的MaskRCNN模型推理方法
public static extern bool Mask_ModelPredict(IntPtr model, byte[] img, int W, int H, int C, IntPtr output, ref byte Mask_output, int[] BoxesNum, ref byte label);
//public static extern bool Mask_ModelPredict(IntPtr model, IntPtr img, int W, int H, int C, IntPtr output, ref byte Mask_output, int[] BoxesNum, ref byte label);
[DllImport("model_infer.dll", EntryPoint = "DestructModel")] // 分割、检测、识别模型销毁方法
public static extern void DestructModel(IntPtr model);
}

View File

@ -0,0 +1,668 @@
using Microsoft.CSharp.RuntimeBinder;
//using Newtonsoft.Json;
using System.Collections.ObjectModel;
using System.Drawing.Imaging;
using System.Dynamic;
using System.Linq.Expressions;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.ExceptionServices;
using System.Runtime.InteropServices;
using System.Runtime.Serialization.Formatters.Binary;
public static class StaticHelper
{
/// <summary>
/// 数值转换为byte数组 高位在前,低位在后
/// </summary>
/// <param name="number"></param>
/// <param name="size"></param>
/// <returns></returns>
public static byte[] IntToBytes(this int number, int size = 2)
{
byte[] result = new byte[size];
int temp = size;
while (temp > 0)
{
result[size - temp] = (byte)(number >> ((temp - 1) * 8) & 0xff);
temp--;
}
return result;
}
/// <summary>
/// 字节数组转换为整数
/// </summary>
/// <param name="data">字节数组</param>
/// <param name="HtL">true:数组序号低的在高位 false数组序号低的在低位</param>
/// <returns></returns>
public static int BytesToInt(this byte[] data, bool HtL = true)
{
int res = 0;
for (int i = 0; i < data.Length; i++)
{
int index = i;
if (HtL)
{
index = data.Length - 1 - i;
}
res += data[index] << (8 * i);
}
return res;
}
/// <summary>
/// 获取一个类指定的属性值
/// </summary>
/// <param name="info">object对象</param>
/// <param name="field">属性名称</param>
/// <returns></returns>
public static object GetPropertyValue(object info, string field)
{
if (info == null) return null;
Type t = info.GetType();
IEnumerable<System.Reflection.PropertyInfo> property = from pi in t.GetProperties() where pi.Name.ToLower() == field.ToLower() select pi;
return property.First().GetValue(info, null);
}
/// <summary>
/// 将32位整形拆分为无符号16位整形
/// </summary>
/// <param name="num">需要拆分的32位整形</param>
/// <param name="bitNum">拆分为16位整形的位数 1或者2</param>
/// <param name="HtL">true高位在前低位在后false高位在后低位在前</param>
/// <returns></returns>
public static List<ushort> ParseIntToUnsignShortList(this int num, int bitNum = 2, bool HtL = false)
{
if (bitNum == 2)
{
ushort high = (ushort)(num >> 16);
ushort low = (ushort)num;
if (HtL)
{
return new List<ushort>() { high, low };
}
else
{
return new List<ushort>() { low, high };
}
}
else
{
if (num < 0)
{
num = ushort.MaxValue + 1 + num;
}
return new List<ushort>() { (ushort)num };
}
}
/// <summary>
/// 将32位整形数组拆分为无符号16位整形数组
/// </summary>
/// <param name="list">需要拆分的32位整形</param>
/// <param name="bitNum">拆分为16位整形的位数 1或者2</param>
/// <param name="HtL">true高位在前低位在后false高位在后低位在前</param>
/// <returns></returns>
public static List<ushort> ParseIntToUnsignShortList(this List<int> list, int bitNum = 2, bool HtL = false)
{
return list.SelectMany(u => u.ParseIntToUnsignShortList(bitNum, HtL)).ToList();
}
/// <summary>
/// 将ushort的集合转换为16位带符号整形
/// </summary>
/// <param name="numList"></param>
/// <param name="bitNum">合并的位数 1或者2</param>
/// <param name="HtL">true高位在前低位在后false高位在后低位在前</param>
/// <returns></returns>
public static List<int> ParseUnsignShortListToInt(this List<int> numList, int bitNum = 2, bool HtL = false)
{
if (bitNum == 1)
{
return numList.ConvertAll(n =>
{
int num = n;
if (num > short.MaxValue)
{
num = num - ushort.MaxValue - 1;
}
return num;
});
}
else
{
List<int> list = new List<int>();
for (int i = 0; i < numList.Count; i += 2)
{
int high = HtL ? numList[i] : numList[i + 1];
int low = HtL ? numList[i + 1] : numList[i];
list.Add((high << 16) | low);
}
return list;
}
}
//public static T DeepSerializeClone<T>(this T t)
//{
// return JsonConvert.DeserializeObject<T>(JsonConvert.SerializeObject(t));
//}
public static void DataFrom<T1, T2>(this T1 destT, T2 sourceT, List<string> exceptionProps = null) where T1 : class where T2 : class
{
if (sourceT == null)
{
destT = null;
return;
}
PropertyInfo[] propDest = destT.GetType().GetProperties();//.Where(p => !(p.GetMethod.IsVirtual && !p.GetMethod.IsFinal)).ToArray();
PropertyInfo[] propSource = sourceT.GetType().GetProperties();
Array.ForEach(propDest, prop =>
{
if (exceptionProps == null || !exceptionProps.Contains(prop.Name))
{
if (prop.CanWrite)
{
PropertyInfo propS = propSource.FirstOrDefault(p => p.Name == prop.Name);
if (propS != null && propS.CanRead)
{
prop.SetValue(destT, propS.GetValue(sourceT));
}
}
}
});
}
public static Bitmap BitmapSerializeCopy(this Bitmap map)
{
Bitmap image = null;
using (MemoryStream ms = new MemoryStream())
{
BinaryFormatter bf = new BinaryFormatter();
#if NET7_0_OR_GREATER
#pragma warning disable SYSLIB0011
#endif
bf.Serialize(ms, map);
ms.Seek(0, SeekOrigin.Begin);
image = (Bitmap)bf.Deserialize(ms);
#if NET7_0_OR_GREATER
#pragma warning restore SYSLIB0011
#endif
//ms.Close();
}
return image;
}
public static Bitmap DeepClone(this Bitmap bitmap)
{
Bitmap dstBitmap = null;
using (MemoryStream mStream = new MemoryStream())
{
BinaryFormatter bf = new BinaryFormatter();
#if NET7_0_OR_GREATER
#pragma warning disable SYSLIB0011
#endif
bf.Serialize(mStream, bitmap);
//#pragma warning restore SYSLIB0011
mStream.Seek(0, SeekOrigin.Begin);
dstBitmap = (Bitmap)bf.Deserialize(mStream);
mStream.Close();
#if NET7_0_OR_GREATER
#pragma warning restore SYSLIB0011
#endif
}
return dstBitmap;
}
//RtlMoveMemory
[DllImport("kernel32.dll", EntryPoint = "RtlMoveMemory", SetLastError = false)]
public static extern void CopyMemory(IntPtr dest, IntPtr src, uint count);
[HandleProcessCorruptedStateExceptions]
public static Bitmap CopyBitmap(this Bitmap source)
{
Bitmap clone = new Bitmap(source.Width, source.Height, source.PixelFormat);
try
{
int PixelSize = Bitmap.GetPixelFormatSize(source.PixelFormat) / 8;
if (PixelSize == 1)
{
ColorPalette cp = clone.Palette;
for (int i = 0; i < 256; i++)
{
cp.Entries[i] = Color.FromArgb(255, i, i, i);
}
clone.Palette = cp;
}
Rectangle rect = new Rectangle(0, 0, source.Width, source.Height);
BitmapData sourceData = source.LockBits(rect, ImageLockMode.ReadWrite, source.PixelFormat);
BitmapData cloneData = clone.LockBits(rect, ImageLockMode.ReadWrite, source.PixelFormat);
if (source.Width % 4 == 0)
{
unsafe
{
CopyMemory(cloneData.Scan0, sourceData.Scan0, (uint)(sourceData.Stride * sourceData.Height));
}
}
else
{
Parallel.For(0, source.Height, h =>
{
unsafe
{
CopyMemory(cloneData.Scan0 + h * sourceData.Stride, sourceData.Scan0 + h * sourceData.Stride, (uint)sourceData.Width);
}
});
}
clone.UnlockBits(cloneData);
source.UnlockBits(sourceData);
}
catch (Exception ex)
{
return clone;
}
return clone;
}
public static Bitmap BitmapDeepClone(Bitmap source)
{
Bitmap clone = new Bitmap(source.Width, source.Height, source.PixelFormat);
try
{
int PixelSize = Bitmap.GetPixelFormatSize(source.PixelFormat) / 8;
if (PixelSize == 1)
{
ColorPalette cp = clone.Palette;
for (int i = 0; i < 256; i++)
{
cp.Entries[i] = Color.FromArgb(255, i, i, i);
}
clone.Palette = cp;
}
Rectangle rect = new Rectangle(0, 0, source.Width, source.Height);
BitmapData source_bitmap = source.LockBits(rect, ImageLockMode.ReadWrite, source.PixelFormat);
BitmapData destination_bitmap = clone.LockBits(rect, ImageLockMode.ReadWrite, clone.PixelFormat);
int depth_width = source_bitmap.Width * PixelSize;
unsafe
{
byte* source_ptr = (byte*)source_bitmap.Scan0;
byte* destination_ptr = (byte*)destination_bitmap.Scan0;
int offset = source_bitmap.Stride - depth_width;
for (int i = 0; i < source_bitmap.Height; i++)
{
for (int j = 0; j < depth_width; j++, source_ptr++, destination_ptr++)
{
*destination_ptr = *source_ptr;
}
source_ptr += offset;
destination_ptr += offset;
}
}
source.UnlockBits(source_bitmap);
clone.UnlockBits(destination_bitmap);
}
catch (Exception ex)
{
}
return clone;
}
public static Bitmap HConnectBitmap(this Bitmap map1, Bitmap map2)
{
Bitmap connectImage = null;
if (map1 == null || map2 == null)
return null;
//横向拼接
int width = map1.Width + map2.Width;
//高度不变
int height = Math.Max(map1.Height, map2.Height);
connectImage = new Bitmap(width, height);
using (Graphics graph = Graphics.FromImage(connectImage))
{
graph.DrawImage(connectImage, width, height);
graph.Clear(System.Drawing.Color.White);
graph.DrawImage(map1, 0, 0);
graph.DrawImage(map2, map1.Width, 0);
}
return connectImage;
}
public static IntPtr FloatToIntptr(float[] bytes)
{
GCHandle hObject = GCHandle.Alloc(bytes, GCHandleType.Pinned);
return hObject.AddrOfPinnedObject();
}
// 将Btimap类转换为byte[]类函数
public static byte[] GetBGRValues(Bitmap bmp, out int stride)
{
var rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
var bmpData = bmp.LockBits(rect, ImageLockMode.ReadOnly, bmp.PixelFormat);
stride = bmpData.Stride;
var rowBytes = bmpData.Width * Image.GetPixelFormatSize(bmp.PixelFormat) / 8;
var imgBytes = bmp.Height * rowBytes;
byte[] rgbValues = new byte[imgBytes];
IntPtr ptr = bmpData.Scan0;
for (var i = 0; i < bmp.Height; i++)
{
Marshal.Copy(ptr, rgbValues, i * rowBytes, rowBytes);
ptr += bmpData.Stride;
}
bmp.UnlockBits(bmpData);
return rgbValues;
}
/// <summary>
/// 缺陷灰度图转彩色图像函数
/// </summary>
/// <param name="src">灰度图</param>
/// <returns>返回构造的伪彩色图像</returns>
public static Bitmap GrayMapToColorMap(this Bitmap src, Dictionary<int, Color> indexColorDict = null)
{
try
{
//Stopwatch sw = new Stopwatch();
//sw.Start();
Bitmap dest = new Bitmap(src.Width, src.Height, PixelFormat.Format32bppArgb);
int destHeight = dest.Height;
int destWidth = dest.Width;
Rectangle rect = new Rectangle(0, 0, destWidth, destHeight);
BitmapData bmpDataDest = dest.LockBits(rect, ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
BitmapData bmpDataSrc = src.LockBits(rect, ImageLockMode.ReadWrite, PixelFormat.Format8bppIndexed);
int strideDest = bmpDataDest.Stride;
int strideSrc = bmpDataSrc.Stride;
unsafe
{
byte* pDest = (byte*)bmpDataDest.Scan0.ToPointer();
byte* pSrc = (byte*)bmpDataSrc.Scan0.ToPointer();
Parallel.For(0, destHeight, y =>
{
Parallel.For(0, destWidth, x =>
{
int pixel = pSrc[y * strideSrc + x];
int startIndex = y * strideDest + x * 4;
if (pixel >= 0 && pixel <= 63)
{
Color color = Color.Red;
if (indexColorDict != null && indexColorDict.ContainsKey(pixel))
{
color = indexColorDict[pixel];
}
byte R = color.R;
byte G = color.G;
byte B = color.B;
pDest[startIndex] = B;
pDest[startIndex + 1] = G;
pDest[startIndex + 2] = R;
pDest[startIndex + 3] = 100;
}
else
{
pDest[startIndex] = 255;
pDest[startIndex + 1] = 255;
pDest[startIndex + 2] = 255;
pDest[startIndex + 3] = 0;
}
});
});
}
dest.UnlockBits(bmpDataDest);
src.UnlockBits(bmpDataSrc);
//sw.Stop();
//Console.WriteLine($"转换耗时:{sw.ElapsedMilliseconds}");
return dest;
}
catch (Exception ex)
{
return null;
}
}
public static void Sort<T>(this ObservableCollection<T> collection) where T : IComparable<T>
{
List<T> sortedList = collection.OrderByDescending(x => x).ToList();//这里用降序
for (int i = 0; i < sortedList.Count(); i++)
{
collection.Move(collection.IndexOf(sortedList[i]), i);
}
}
/// <summary>
/// 获得字符串中开始和结束字符串中间的值
/// </summary>
/// <param name="sourse"></param>
/// <param name="startstr"></param>
/// <param name="endstr"></param>
/// <returns></returns>
public static string GetMidString(string sourse, string startstr, string endstr)
{
string result = string.Empty;
int startindex, endindex;
try
{
startindex = sourse.IndexOf(startstr);
if (startindex == -1)
return result;
string tmpstr = sourse.Substring(startindex + startstr.Length);
endindex = tmpstr.IndexOf(endstr);
if (endindex == -1)
return result;
result = tmpstr.Remove(endindex);
}
catch (Exception ex)
{
return "";
}
return result;
}
/// <summary>
/// 获得字符串中开始和结束字符串中间的值
/// </summary>
/// <param name="t">字符串</param>
/// <param name="k">开始</param>
/// <param name="j">结束</param>
/// <returns></returns>
private static string GetMidString2(string sourse, string startstr, string endstr) //截取指定文本,和易语言的取文本中间差不多
{
try //异常捕捉
{
var kn = sourse.IndexOf(startstr, StringComparison.Ordinal) + startstr.Length;
var jn = sourse.IndexOf(endstr, kn, StringComparison.Ordinal);
return sourse.Substring(kn, jn - kn);
}
catch //如果发现未知的错误,比如上面的代码出错了,就执行下面这句代码
{
return ""; //返回空
}
}
// 布尔类型转换为整型
public static int ToInt(this object obj)
{
if (Convert.ToBoolean(obj) == true)
return 1;
else
return 0;
}
// 整型转换为布尔类型
public static bool ToBool(this object obj)
{
if (Convert.ToInt32(obj) == 1)
return true;
else
return false;
}
public static object GetProperty(this object o, string member)
{
if (o == null) throw new ArgumentNullException("o");
if (member == null) throw new ArgumentNullException("member");
Type scope = o.GetType();
IDynamicMetaObjectProvider provider = o as IDynamicMetaObjectProvider;
if (provider != null)
{
ParameterExpression param = Expression.Parameter(typeof(object));
DynamicMetaObject mobj = provider.GetMetaObject(param);
GetMemberBinder binder = (GetMemberBinder)Microsoft.CSharp.RuntimeBinder.Binder.GetMember(0, member, scope, new CSharpArgumentInfo[] { CSharpArgumentInfo.Create(0, null) });
DynamicMetaObject ret = mobj.BindGetMember(binder);
BlockExpression final = Expression.Block(
Expression.Label(CallSiteBinder.UpdateLabel),
ret.Expression
);
LambdaExpression lambda = Expression.Lambda(final, param);
Delegate del = lambda.Compile();
return del.DynamicInvoke(o);
}
else
{
return o.GetType().GetProperty(member, BindingFlags.Public | BindingFlags.Instance).GetValue(o, null);
}
}
#region
[DllImport("kernel32.dll")]
private static extern IntPtr _lopen(string lpPathName, int iReadWrite);
[DllImport("kernel32.dll")]
private static extern bool CloseHandle(IntPtr hObject);
private const int OF_READWRITE = 2;
private const int OF_SHARE_DENY_NONE = 0x40;
private static readonly IntPtr HFILE_ERROR = new IntPtr(-1);
/// <summary>
/// 检测文件是否只读或被使用
/// </summary>
/// <param name="FileNames">要检测的文件</param>
/// <returns>true可用false在用或只读</returns>
public static bool CheckFilesCanUse(string fileName)
{
if (!File.Exists(fileName))
return true;//文件不存在
if ((File.GetAttributes(fileName) & FileAttributes.ReadOnly) == FileAttributes.ReadOnly)
return false; //文件只读
IntPtr vHandle = _lopen(fileName, OF_READWRITE | OF_SHARE_DENY_NONE);
if (vHandle == HFILE_ERROR)
{
CloseHandle(vHandle);
return false; //文件被占用
}
CloseHandle(vHandle); //文件没被占用
return true;
}
#endregion
/// <summary>
/// 获取指定文件夹下所有的文件名称
/// </summary>
/// <param name="folderName">指定文件夹名称,绝对路径</param>
/// <param name="fileFilter">文件类型过滤,根据文件后缀名,如:*,*.txt,*.xls</param>
/// <param name="isContainSubFolder">是否包含子文件夹</param>
/// <returns>ArrayList数组,为所有需要的文件路径名称</returns>
public static List<FileInfo> GetAllFilesByFolder(string folderName, string fileFilter, bool isContainSubFolder = false)
{
List<FileInfo> resList = new List<FileInfo>();
try
{
DirectoryInfo currDir = new DirectoryInfo(folderName);//当前目录
FileInfo[] currFiles = currDir.GetFiles(fileFilter);//当前目录文件
foreach (FileInfo file in currFiles)
{
if (fileFilter.ToLower().IndexOf(file.Extension.ToLower()) >= 0)
{
resList.Add(file);
}
}
if (isContainSubFolder)
{
string[] subFolders = Directory.GetDirectories(folderName);
foreach (string subFolder in subFolders)
{
resList.AddRange(GetAllFilesByFolder(subFolder, fileFilter));//递归
}
}
}
catch (Exception ex)
{
throw ex;
}
return resList;
}
/// <summary>
/// 获取指定文件夹下所有的文件名称,不过滤文件类型
/// </summary>
/// <param name="folderName">指定文件夹名称,绝对路径</param>
/// <param name="isContainSubFolder">是否包含子文件夹</param>
/// <returns>ArrayList数组,为所有需要的文件路径名称</returns>
public static List<FileInfo> GetAllFilesByFolder(string folderName, bool isContainSubFolder)
{
return GetAllFilesByFolder(folderName, "*", isContainSubFolder);
}
}
public class Compare<T, C> : IEqualityComparer<T>
{
private Func<T, C> _getField;
public Compare(Func<T, C> getfield)
{
_getField = getfield;
}
public bool Equals(T x, T y)
{
return EqualityComparer<C>.Default.Equals(_getField(x), _getField(y));
}
public int GetHashCode(T obj)
{
return EqualityComparer<C>.Default.GetHashCode(_getField(obj));
}
}
public static class ObjectExtensions
{
public static IEnumerable<T> DistinctBy<T, C>(this IEnumerable<T> source, Func<T, C> getfield)
{
return source.Distinct(new Compare<T, C>(getfield));
}
public static IQueryable<T> DistinctBy<T, C>(this IQueryable<T> source, Func<T, C> getfield)
{
return source.Distinct(new Compare<T, C>(getfield));
}
}

View File

@ -0,0 +1,62 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
using OpenCvSharp;
using STTech.BytesIO.Core;
using STTech.BytesIO.Tcp;
using TcpClient = STTech.BytesIO.Tcp.TcpClient;
namespace HisenceYoloDetection
{
public class TCPClienDriver
{
private TcpClient client;
public event Action<byte[]> OnClientDataReceived;
public void Strart()
{
client = new TcpClient();
client.Host = "192.168.3.100";
client.Port= 9004;
//client.Host = "127.0.0.1";
//client.Port = 9000;
client.Connect();
client.OnDataReceived += Client_OnDataReceived;
client.OnConnectedSuccessfully += Client_OnConnectedSuccessfully;
client.OnDisconnected += Client_OnDisconnected;
}
private void Client_OnDisconnected(object? sender, DisconnectedEventArgs e)
{
Console.WriteLine("已经断开");
}
private void Client_OnConnectedSuccessfully(object? sender, ConnectedSuccessfullyEventArgs e)
{
Console.WriteLine("已经连上");
}
private void Client_OnDataReceived(object? sender, DataReceivedEventArgs e)
{
OnClientDataReceived?.Invoke(e.Data);
}
private void Stop()
{
client.Disconnect();
}
public void btnSendMsg(string msg)
{
//client.Send(msg.GetBytes("GBK"));
client.Send(System.Text.Encoding.UTF8.GetBytes(msg));
}
}
}

View File

@ -0,0 +1,212 @@

using HslCommunication;
using HslCommunication.Profinet.Melsec;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using System.Xml.Linq;
using static HisenceYoloDetection.MainForm;
using static OpenCvSharp.FileStorage;
public class MelsecPLCTCPDriver1
{
// private MelsecMcNet melsecMc = new MelsecMcNet();
// private HslCommunication.ModBus.ModbusTcpNet melsecMc = new HslCommunication.ModBus.ModbusTcpNet();
HslCommunication.Profinet.Melsec.MelsecMcServer melsecMc = new HslCommunication.Profinet.Melsec.MelsecMcServer();
#region PLCBase
public int ReadInt(string address)
{
try
{
// 读取Int变量
var result = melsecMc.ReadInt16("D"+address);
if (result.IsSuccess)
{
return result.Content;
}
else
{
// LogAsync(DateTime.Now, LogLevel.Error, $"{Name}未读取到数据:" + "地址:" + address + ";提示:" + result.Message);
return -1;
}
}
catch (Exception ex)
{
// LogAsync(DateTime.Now, LogLevel.Exception, $"{Name}读取异常:" + ex.GetExceptionMessage());
return -1;
}
}
/// <summary>
/// 写单独地址
/// </summary>
/// <param name="address">地址</param>
/// <param name="writeValue"></param>
/// <param name="waitForReply"></param>
public void WriteInt(string address, int writeValue, bool waitForReply = true)
{
if (string.IsNullOrEmpty(address))
{
// LogAsync(DateTime.Now, LogLevel.Error, $"{Name} 数据写入参数不能为空!");
return;
}
int repeatTime = 3;
Stopwatch sw = new Stopwatch();
do
{
try
{
var result = melsecMc.Write("D"+address, writeValue);
if (result.IsSuccess)
{
repeatTime = 0;
}
}
catch (Exception ex)
{
if (repeatTime < 0)
{
// LogAsync(DateTime.Now, LogLevel.Exception, $"{Name}数据写入异常:{ex.GetExceptionMessage()}");
}
}
} while (repeatTime > 0);
sw.Stop();
// LogAsync(DateTime.Now, LogLevel.Assist, $"{Name} {address},写入 {writeValue} 完成,耗时:{sw.ElapsedMilliseconds} ms");
}
#endregion
#region DeviceBase
public void Start()
{
// IConfig.ip
// 如果网络不太理想,配置了两个端口,一个有问题,立即切换另一个的话,可以配置如下的代码
// melsecMc.GetPipeSocket().SetMultiPorts(new int[] { 6000, 6001 });
//melsecMc = new HslCommunication.ModBus.ModbusTcpNet();
//melsecMc.IpAddress = "192.168.3.39";
//melsecMc.Port = 502;
//melsecMc.ConnectTimeOut = 10000; // 连接超时,单位毫秒
//melsecMc.ReceiveTimeOut = 5000; // 接收超时,单位毫秒
//melsecMc.Station = 1;
//melsecMc.AddressStartWithZero = true;
//melsecMc.IsStringReverse = false;
//melsecMc.DataFormat = HslCommunication.Core.DataFormat.CDAB;
//se("01:00:00");
// melsecMc.EnableIPv6 = false;
melsecMc.ServerStart(6000);
// melsecMc.ServerStart(6000);
// 连接对象
//OperateResult connect = melsecMc.ConnectServer();
CurrentState = true;
Task.Run(() =>
{
HeartbeatMonitor();
});
//else
//{
// // LogAsync(DateTime.Now, LogLevel.Exception, $"{Name}已开启异常:{connect.Message}");
//}
}
protected void Stop()
{
try
{
// 断开连接
// melsecMc.RemoteStop();
// OmronUDPNet.Stop();
}
catch (Exception ex)
{
// LogAsync(DateTime.Now, LogLevel.Exception, $"{Name}关闭异常:{ex.GetExceptionMessage()}");
}
}
#endregion
#region IMonitor
readonly byte[] scanBuffer = new byte[2048];
public List<int> GetMonitorValues(int startAddress, int length)
{
List<int> res = new List<int>();
// var result = melsecMc.ReadUInt16(startAddress.ToString(), (ushort)length);
// var result = melsecMc.ReadInt32("D" + startAddress, (ushort)length);
var result = melsecMc.ReadInt32("D" + startAddress, (ushort)length);
if (result.IsSuccess)
{
res = new List<int>(result.Content);
}
else
{
//LogAsync(DateTime.Now, LogLevel.Error, $"{Name}未读取到数据:" + "地址W" + startAddress + ";长度:" + length + ";提示:" + result.Message);
}
return res;
}
#endregion
int HeartbeatCycle = 2;
string HeartbeatAddress = "D800";
bool CurrentState = false;
public event Action<int> Heartbeat;
public async void HeartbeatMonitor()
{
if (HeartbeatCycle <= 0)
{
return;
}
await Task.Run(async () =>
{
if (!string.IsNullOrEmpty(HeartbeatAddress)
&& HeartbeatCycle > 0)
{
while (CurrentState != false)
{
if (HeartbeatCycle <= 0)
{
return;
}
try
{
await Task.Delay(HeartbeatCycle * 1000);
var result = melsecMc.Write(HeartbeatAddress, 1);
if (!result.IsSuccess)
{
Heartbeat?.Invoke(1);
//LogAsync(DateTime.Now, LogLevel.Error, $"{this.Name} 心跳监听失败");
}
}
catch (Exception ex)
{
}
}
}
});
}
}

Binary file not shown.

Binary file not shown.

BIN
libs/HslCommunication.dll Normal file

Binary file not shown.

Binary file not shown.