添加项目文件。
This commit is contained in:
commit
16d64aefba
63
.gitattributes
vendored
Normal file
63
.gitattributes
vendored
Normal file
@ -0,0 +1,63 @@
|
||||
###############################################################################
|
||||
# Set default behavior to automatically normalize line endings.
|
||||
###############################################################################
|
||||
* text=auto
|
||||
|
||||
###############################################################################
|
||||
# Set default behavior for command prompt diff.
|
||||
#
|
||||
# This is need for earlier builds of msysgit that does not have it on by
|
||||
# default for csharp files.
|
||||
# Note: This is only used by command line
|
||||
###############################################################################
|
||||
#*.cs diff=csharp
|
||||
|
||||
###############################################################################
|
||||
# Set the merge driver for project and solution files
|
||||
#
|
||||
# Merging from the command prompt will add diff markers to the files if there
|
||||
# are conflicts (Merging from VS is not affected by the settings below, in VS
|
||||
# the diff markers are never inserted). Diff markers may cause the following
|
||||
# file extensions to fail to load in VS. An alternative would be to treat
|
||||
# these files as binary and thus will always conflict and require user
|
||||
# intervention with every merge. To do so, just uncomment the entries below
|
||||
###############################################################################
|
||||
#*.sln merge=binary
|
||||
#*.csproj merge=binary
|
||||
#*.vbproj merge=binary
|
||||
#*.vcxproj merge=binary
|
||||
#*.vcproj merge=binary
|
||||
#*.dbproj merge=binary
|
||||
#*.fsproj merge=binary
|
||||
#*.lsproj merge=binary
|
||||
#*.wixproj merge=binary
|
||||
#*.modelproj merge=binary
|
||||
#*.sqlproj merge=binary
|
||||
#*.wwaproj merge=binary
|
||||
|
||||
###############################################################################
|
||||
# behavior for image files
|
||||
#
|
||||
# image files are treated as binary by default.
|
||||
###############################################################################
|
||||
#*.jpg binary
|
||||
#*.png binary
|
||||
#*.gif binary
|
||||
|
||||
###############################################################################
|
||||
# diff behavior for common document formats
|
||||
#
|
||||
# Convert binary document formats to text before diffing them. This feature
|
||||
# is only available from the command line. Turn it on by uncommenting the
|
||||
# entries below.
|
||||
###############################################################################
|
||||
#*.doc diff=astextplain
|
||||
#*.DOC diff=astextplain
|
||||
#*.docx diff=astextplain
|
||||
#*.DOCX diff=astextplain
|
||||
#*.dot diff=astextplain
|
||||
#*.DOT diff=astextplain
|
||||
#*.pdf diff=astextplain
|
||||
#*.PDF diff=astextplain
|
||||
#*.rtf diff=astextplain
|
||||
#*.RTF diff=astextplain
|
363
.gitignore
vendored
Normal file
363
.gitignore
vendored
Normal file
@ -0,0 +1,363 @@
|
||||
## Ignore Visual Studio temporary files, build results, and
|
||||
## files generated by popular Visual Studio add-ons.
|
||||
##
|
||||
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
|
||||
|
||||
# User-specific files
|
||||
*.rsuser
|
||||
*.suo
|
||||
*.user
|
||||
*.userosscache
|
||||
*.sln.docstates
|
||||
|
||||
# User-specific files (MonoDevelop/Xamarin Studio)
|
||||
*.userprefs
|
||||
|
||||
# Mono auto generated files
|
||||
mono_crash.*
|
||||
|
||||
# Build results
|
||||
[Dd]ebug/
|
||||
[Dd]ebugPublic/
|
||||
[Rr]elease/
|
||||
[Rr]eleases/
|
||||
x64/
|
||||
x86/
|
||||
[Ww][Ii][Nn]32/
|
||||
[Aa][Rr][Mm]/
|
||||
[Aa][Rr][Mm]64/
|
||||
bld/
|
||||
[Bb]in/
|
||||
[Oo]bj/
|
||||
[Oo]ut/
|
||||
[Ll]og/
|
||||
[Ll]ogs/
|
||||
|
||||
# Visual Studio 2015/2017 cache/options directory
|
||||
.vs/
|
||||
# Uncomment if you have tasks that create the project's static files in wwwroot
|
||||
#wwwroot/
|
||||
|
||||
# Visual Studio 2017 auto generated files
|
||||
Generated\ Files/
|
||||
|
||||
# MSTest test Results
|
||||
[Tt]est[Rr]esult*/
|
||||
[Bb]uild[Ll]og.*
|
||||
|
||||
# NUnit
|
||||
*.VisualState.xml
|
||||
TestResult.xml
|
||||
nunit-*.xml
|
||||
|
||||
# Build Results of an ATL Project
|
||||
[Dd]ebugPS/
|
||||
[Rr]eleasePS/
|
||||
dlldata.c
|
||||
|
||||
# Benchmark Results
|
||||
BenchmarkDotNet.Artifacts/
|
||||
|
||||
# .NET Core
|
||||
project.lock.json
|
||||
project.fragment.lock.json
|
||||
artifacts/
|
||||
|
||||
# ASP.NET Scaffolding
|
||||
ScaffoldingReadMe.txt
|
||||
|
||||
# StyleCop
|
||||
StyleCopReport.xml
|
||||
|
||||
# Files built by Visual Studio
|
||||
*_i.c
|
||||
*_p.c
|
||||
*_h.h
|
||||
*.ilk
|
||||
*.meta
|
||||
*.obj
|
||||
*.iobj
|
||||
*.pch
|
||||
*.pdb
|
||||
*.ipdb
|
||||
*.pgc
|
||||
*.pgd
|
||||
*.rsp
|
||||
*.sbr
|
||||
*.tlb
|
||||
*.tli
|
||||
*.tlh
|
||||
*.tmp
|
||||
*.tmp_proj
|
||||
*_wpftmp.csproj
|
||||
*.log
|
||||
*.vspscc
|
||||
*.vssscc
|
||||
.builds
|
||||
*.pidb
|
||||
*.svclog
|
||||
*.scc
|
||||
|
||||
# Chutzpah Test files
|
||||
_Chutzpah*
|
||||
|
||||
# Visual C++ cache files
|
||||
ipch/
|
||||
*.aps
|
||||
*.ncb
|
||||
*.opendb
|
||||
*.opensdf
|
||||
*.sdf
|
||||
*.cachefile
|
||||
*.VC.db
|
||||
*.VC.VC.opendb
|
||||
|
||||
# Visual Studio profiler
|
||||
*.psess
|
||||
*.vsp
|
||||
*.vspx
|
||||
*.sap
|
||||
|
||||
# Visual Studio Trace Files
|
||||
*.e2e
|
||||
|
||||
# TFS 2012 Local Workspace
|
||||
$tf/
|
||||
|
||||
# Guidance Automation Toolkit
|
||||
*.gpState
|
||||
|
||||
# ReSharper is a .NET coding add-in
|
||||
_ReSharper*/
|
||||
*.[Rr]e[Ss]harper
|
||||
*.DotSettings.user
|
||||
|
||||
# TeamCity is a build add-in
|
||||
_TeamCity*
|
||||
|
||||
# DotCover is a Code Coverage Tool
|
||||
*.dotCover
|
||||
|
||||
# AxoCover is a Code Coverage Tool
|
||||
.axoCover/*
|
||||
!.axoCover/settings.json
|
||||
|
||||
# Coverlet is a free, cross platform Code Coverage Tool
|
||||
coverage*.json
|
||||
coverage*.xml
|
||||
coverage*.info
|
||||
|
||||
# Visual Studio code coverage results
|
||||
*.coverage
|
||||
*.coveragexml
|
||||
|
||||
# NCrunch
|
||||
_NCrunch_*
|
||||
.*crunch*.local.xml
|
||||
nCrunchTemp_*
|
||||
|
||||
# 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
|
||||
# Note: Comment the next line if you want to checkin your web deploy settings,
|
||||
# but database connection strings (with potential passwords) will be unencrypted
|
||||
*.pubxml
|
||||
*.publishproj
|
||||
|
||||
# Microsoft Azure Web App publish settings. Comment the next line if you want to
|
||||
# checkin your Azure Web App publish settings, but sensitive information contained
|
||||
# in these scripts will be unencrypted
|
||||
PublishScripts/
|
||||
|
||||
# NuGet Packages
|
||||
*.nupkg
|
||||
# NuGet Symbol Packages
|
||||
*.snupkg
|
||||
# The packages folder can be ignored because of Package Restore
|
||||
**/[Pp]ackages/*
|
||||
# except build/, which is used as an MSBuild target.
|
||||
!**/[Pp]ackages/build/
|
||||
# Uncomment if necessary however generally it will be regenerated when needed
|
||||
#!**/[Pp]ackages/repositories.config
|
||||
# NuGet v3's project.json files produces more ignorable files
|
||||
*.nuget.props
|
||||
*.nuget.targets
|
||||
|
||||
# Microsoft Azure Build Output
|
||||
csx/
|
||||
*.build.csdef
|
||||
|
||||
# Microsoft Azure Emulator
|
||||
ecf/
|
||||
rcf/
|
||||
|
||||
# Windows Store app package directories and files
|
||||
AppPackages/
|
||||
BundleArtifacts/
|
||||
Package.StoreAssociation.xml
|
||||
_pkginfo.txt
|
||||
*.appx
|
||||
*.appxbundle
|
||||
*.appxupload
|
||||
|
||||
# Visual Studio cache files
|
||||
# files ending in .cache can be ignored
|
||||
*.[Cc]ache
|
||||
# but keep track of directories ending in .cache
|
||||
!?*.[Cc]ache/
|
||||
|
||||
# Others
|
||||
ClientBin/
|
||||
~$*
|
||||
*~
|
||||
*.dbmdl
|
||||
*.dbproj.schemaview
|
||||
*.jfm
|
||||
*.pfx
|
||||
*.publishsettings
|
||||
orleans.codegen.cs
|
||||
|
||||
# Including strong name files can present a security risk
|
||||
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
|
||||
#*.snk
|
||||
|
||||
# Since there are multiple workflows, uncomment next line to ignore bower_components
|
||||
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
|
||||
#bower_components/
|
||||
|
||||
# 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
|
||||
ServiceFabricBackup/
|
||||
*.rptproj.bak
|
||||
|
||||
# SQL Server files
|
||||
*.mdf
|
||||
*.ldf
|
||||
*.ndf
|
||||
|
||||
# Business Intelligence projects
|
||||
*.rdl.data
|
||||
*.bim.layout
|
||||
*.bim_*.settings
|
||||
*.rptproj.rsuser
|
||||
*- [Bb]ackup.rdl
|
||||
*- [Bb]ackup ([0-9]).rdl
|
||||
*- [Bb]ackup ([0-9][0-9]).rdl
|
||||
|
||||
# Microsoft Fakes
|
||||
FakesAssemblies/
|
||||
|
||||
# GhostDoc plugin setting file
|
||||
*.GhostDoc.xml
|
||||
|
||||
# Node.js Tools for Visual Studio
|
||||
.ntvs_analysis.dat
|
||||
node_modules/
|
||||
|
||||
# Visual Studio 6 build log
|
||||
*.plg
|
||||
|
||||
# Visual Studio 6 workspace options file
|
||||
*.opt
|
||||
|
||||
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
|
||||
*.vbw
|
||||
|
||||
# Visual Studio LightSwitch build output
|
||||
**/*.HTMLClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/ModelManifest.xml
|
||||
**/*.Server/GeneratedArtifacts
|
||||
**/*.Server/ModelManifest.xml
|
||||
_Pvt_Extensions
|
||||
|
||||
# Paket dependency manager
|
||||
.paket/paket.exe
|
||||
paket-files/
|
||||
|
||||
# FAKE - F# Make
|
||||
.fake/
|
||||
|
||||
# CodeRush personal settings
|
||||
.cr/personal
|
||||
|
||||
# Python Tools for Visual Studio (PTVS)
|
||||
__pycache__/
|
||||
*.pyc
|
||||
|
||||
# Cake - Uncomment if you are using it
|
||||
# tools/**
|
||||
# !tools/packages.config
|
||||
|
||||
# Tabs Studio
|
||||
*.tss
|
||||
|
||||
# Telerik's JustMock configuration file
|
||||
*.jmconfig
|
||||
|
||||
# BizTalk build output
|
||||
*.btp.cs
|
||||
*.btm.cs
|
||||
*.odx.cs
|
||||
*.xsd.cs
|
||||
|
||||
# OpenCover UI analysis results
|
||||
OpenCover/
|
||||
|
||||
# Azure Stream Analytics local run output
|
||||
ASALocalRun/
|
||||
|
||||
# MSBuild Binary and Structured Log
|
||||
*.binlog
|
||||
|
||||
# NVidia Nsight GPU debugger configuration file
|
||||
*.nvuser
|
||||
|
||||
# MFractors (Xamarin productivity tool) working folder
|
||||
.mfractor/
|
||||
|
||||
# Local History for Visual Studio
|
||||
.localhistory/
|
||||
|
||||
# BeatPulse healthcheck temp database
|
||||
healthchecksdb
|
||||
|
||||
# Backup folder for Package Reference Convert tool in Visual Studio 2017
|
||||
MigrationBackup/
|
||||
|
||||
# Ionide (cross platform F# VS Code tools) working folder
|
||||
.ionide/
|
||||
|
||||
# Fody - auto-generated XML schema
|
||||
FodyWeavers.xsd
|
81
App.config
Normal file
81
App.config
Normal file
@ -0,0 +1,81 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<configSections>
|
||||
<!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
|
||||
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
|
||||
</configSections>
|
||||
<startup>
|
||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
|
||||
</startup>
|
||||
<runtime>
|
||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Drawing.Common" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-8.0.0.0" newVersion="8.0.0.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Memory" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.0.1.2" newVersion="4.0.1.2" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Text.Json" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-8.0.0.4" newVersion="8.0.0.4" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.IO.Pipelines" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-8.0.0.0" newVersion="8.0.0.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-13.0.0.0" newVersion="13.0.0.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="SQLitePCLRaw.core" publicKeyToken="1488e028ca7ab535" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-2.1.9.2410" newVersion="2.1.9.2410" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="K4os.Hash.xxHash" publicKeyToken="32cd54395057cec3" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-1.0.7.0" newVersion="1.0.7.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="K4os.Compression.LZ4.Streams" publicKeyToken="2186fa9121ef231d" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-1.2.16.0" newVersion="1.2.16.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="Microsoft.Bcl.AsyncInterfaces" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-8.0.0.0" newVersion="8.0.0.0" />
|
||||
</dependentAssembly>
|
||||
<!-- 添加对 System.Runtime 的绑定重定向 -->
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Runtime" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Collections.Immutable" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-8.0.0.0" newVersion="8.0.0.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Text.Encodings.Web" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-8.0.0.0" newVersion="8.0.0.0" />
|
||||
</dependentAssembly>
|
||||
</assemblyBinding>
|
||||
</runtime>
|
||||
<entityFramework>
|
||||
<providers>
|
||||
<provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
|
||||
<provider invariantName="System.Data.SQLite.EF6" type="System.Data.SQLite.EF6.SQLiteProviderServices, System.Data.SQLite.EF6" />
|
||||
</providers>
|
||||
</entityFramework>
|
||||
<system.data>
|
||||
<DbProviderFactories>
|
||||
<remove invariant="System.Data.SQLite.EF6" />
|
||||
<add name="SQLite Data Provider (Entity Framework 6)" invariant="System.Data.SQLite.EF6" description=".NET Framework Data Provider for SQLite (Entity Framework 6)" type="System.Data.SQLite.EF6.SQLiteProviderFactory, System.Data.SQLite.EF6" />
|
||||
<remove invariant="System.Data.SQLite" />
|
||||
<add name="SQLite Data Provider" invariant="System.Data.SQLite" description=".NET Framework Data Provider for SQLite" type="System.Data.SQLite.SQLiteFactory, System.Data.SQLite" />
|
||||
</DbProviderFactories>
|
||||
</system.data>
|
||||
</configuration>
|
224
CamManager.cs
Normal file
224
CamManager.cs
Normal file
@ -0,0 +1,224 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
using GuideGraspSys;
|
||||
using picEx;
|
||||
using OpenCvSharp;
|
||||
using WindowsFormsApp1;
|
||||
|
||||
|
||||
public class CameraManager
|
||||
{
|
||||
private MGSCameraDriver cam1;
|
||||
private MGSCameraDriver cam2;
|
||||
private MGSCameraDriver cam3;
|
||||
private MGSCameraDriver cam4;
|
||||
|
||||
private readonly Dictionary<HikCamDriver, string> cameraPaths = new Dictionary<HikCamDriver, string>();
|
||||
|
||||
public CameraManager()
|
||||
{
|
||||
|
||||
cam1 = new MGSCameraDriver();
|
||||
cam2 = new MGSCameraDriver();
|
||||
cam3 = new MGSCameraDriver();
|
||||
cam4 = new MGSCameraDriver();
|
||||
|
||||
}
|
||||
|
||||
public void StartAllCameras()
|
||||
{
|
||||
// Create and start threads for each camera
|
||||
StartCamera(cam1, "Cam1");
|
||||
StartCamera(cam2, "Cam2");
|
||||
StartCamera(cam3, "Cam3");
|
||||
StartCamera(cam4, "Cam4");
|
||||
}
|
||||
|
||||
private void StartCamera(MGSCameraDriver camera, string cameraName)
|
||||
{
|
||||
|
||||
|
||||
if (cameraName == "Cam1")
|
||||
{
|
||||
|
||||
|
||||
camera.Start("Cam1");
|
||||
if (cam1.IfSuccess)
|
||||
{
|
||||
|
||||
}
|
||||
else { }
|
||||
|
||||
|
||||
camera.OnHImageOutput -= OnCameraMatOutPut1;
|
||||
camera.OnHImageOutput += OnCameraMatOutPut1;
|
||||
|
||||
|
||||
}
|
||||
else if(cameraName == "Cam2")
|
||||
{
|
||||
camera.Start("Cam2");
|
||||
if (cam1.IfSuccess)
|
||||
{
|
||||
|
||||
}
|
||||
else { }
|
||||
camera.OnHImageOutput -= OnCameraMatOutPut2;
|
||||
camera.OnHImageOutput += OnCameraMatOutPut2;
|
||||
|
||||
}
|
||||
else if (cameraName == "Cam3")
|
||||
{
|
||||
camera.Start("Cam3");
|
||||
if (cam1.IfSuccess)
|
||||
{
|
||||
|
||||
}
|
||||
else { }
|
||||
camera.OnHImageOutput -= OnCameraMatOutPut3;
|
||||
camera.OnHImageOutput += OnCameraMatOutPut3;
|
||||
}
|
||||
else if (cameraName == "Cam4")
|
||||
{
|
||||
camera.Start("Cam4");
|
||||
if (cam1.IfSuccess)
|
||||
{
|
||||
|
||||
}
|
||||
else { }
|
||||
camera.OnHImageOutput -= OnCameraMatOutPut4;
|
||||
camera.OnHImageOutput += OnCameraMatOutPut4;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
private void OnCameraMatOutPut1(DateTime dt, Mat cameraMat)
|
||||
{
|
||||
// Save the image or process it
|
||||
string path = "D:\\Lujiayi\\Cam1";
|
||||
int num = CountPhotos(path)+1;
|
||||
|
||||
if (path == null)
|
||||
{
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Ensure the directory exists
|
||||
if (!Directory.Exists(path))
|
||||
{
|
||||
Directory.CreateDirectory(path);
|
||||
}
|
||||
|
||||
// Save the image with a unique filename
|
||||
string nameCam = $"{path}\\{num}.jpg";
|
||||
cameraMat.ImWrite(nameCam);
|
||||
|
||||
}
|
||||
private void OnCameraMatOutPut2(DateTime dt, Mat cameraMat)
|
||||
{
|
||||
// Save the image or process it
|
||||
|
||||
string path = "D:\\Lujiayi\\Cam2";
|
||||
int num = CountPhotos(path) + 1;
|
||||
if (path == null)
|
||||
{
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Ensure the directory exists
|
||||
if (!Directory.Exists(path))
|
||||
{
|
||||
Directory.CreateDirectory(path);
|
||||
}
|
||||
|
||||
// Save the image with a unique filename
|
||||
string nameCam = $"{path}\\{num}.jpg";
|
||||
cameraMat.ImWrite(nameCam);
|
||||
|
||||
}
|
||||
private void OnCameraMatOutPut3(DateTime dt, Mat cameraMat)
|
||||
{
|
||||
// Save the image or process it
|
||||
|
||||
string path = "D:\\Lujiayi\\Cam3";
|
||||
int num = CountPhotos(path);
|
||||
if (path == null)
|
||||
{
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Ensure the directory exists
|
||||
if (!Directory.Exists(path))
|
||||
{
|
||||
Directory.CreateDirectory(path);
|
||||
}
|
||||
|
||||
// Save the image with a unique filename
|
||||
string nameCam = $"{path}\\{num}.jpg";
|
||||
cameraMat.ImWrite(nameCam);
|
||||
|
||||
}
|
||||
private void OnCameraMatOutPut4(DateTime dt, Mat cameraMat)
|
||||
{
|
||||
// Save the image or process it
|
||||
|
||||
string path = "D:\\Lujiayi\\Cam4";
|
||||
int num = CountPhotos(path);
|
||||
if (path == null)
|
||||
{
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Ensure the directory exists
|
||||
if (!Directory.Exists(path))
|
||||
{
|
||||
Directory.CreateDirectory(path);
|
||||
}
|
||||
|
||||
// Save the image with a unique filename
|
||||
string nameCam = $"{path}\\{num}.jpg";
|
||||
cameraMat.ImWrite(nameCam);
|
||||
|
||||
}
|
||||
public void takepic1()
|
||||
{
|
||||
cam1.Snapshot();
|
||||
}
|
||||
public void takepic2()
|
||||
{
|
||||
cam2.Snapshot();
|
||||
}
|
||||
public void takepic3()
|
||||
{
|
||||
cam3.Snapshot();
|
||||
}
|
||||
public void takepic4()
|
||||
{
|
||||
cam4.Snapshot();
|
||||
}
|
||||
public static int CountPhotos(string folderPath)
|
||||
{
|
||||
// 图片文件扩展名列表
|
||||
string[] imageExtensions = { ".jpg", ".jpeg", ".png", ".bmp", ".gif" };
|
||||
|
||||
// 获取所有图片文件
|
||||
var photoFiles = Directory.GetFiles(folderPath)
|
||||
.Where(file => imageExtensions.Contains(Path.GetExtension(file).ToLower()))
|
||||
.ToArray();
|
||||
|
||||
return photoFiles.Length;
|
||||
}
|
||||
}
|
||||
|
||||
|
73
CameraBase.cs
Normal file
73
CameraBase.cs
Normal file
@ -0,0 +1,73 @@
|
||||
using OpenCvSharp;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace GuideGraspSys
|
||||
{
|
||||
public abstract class CameraBase
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public Mat MyImage { get; set; }
|
||||
/// <summary>
|
||||
/// 相机名
|
||||
/// </summary>
|
||||
public string CameraName { get; set; }
|
||||
/// <summary>
|
||||
/// 查找相机
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
|
||||
/// <summary>
|
||||
/// 根据相机序列号开启相机
|
||||
/// </summary>
|
||||
/// <param name="CameraName"></param>
|
||||
/// <returns></returns>
|
||||
public abstract bool OpenCamera(string serialNum,IntPtr hWnd);//根据相机序列号开启相机
|
||||
/// <summary>
|
||||
/// 关闭相机
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public abstract bool CloserCamera();//关闭相机
|
||||
/// <summary>
|
||||
///软触发一次
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 启动为硬触发
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public abstract bool EncoderGrap();
|
||||
/// <summary>
|
||||
/// 重连相机
|
||||
/// </summary>
|
||||
/// <param name="CameraName"></param>
|
||||
/// <returns></returns>
|
||||
public abstract bool ReconnectCamera(string CameraName);
|
||||
/// <summary>
|
||||
/// 设置曝光
|
||||
/// </summary>
|
||||
/// <param name="ExposureTime"></param>
|
||||
/// <returns></returns>
|
||||
public abstract bool SetExpoureTime(int ExposureTime);
|
||||
/// <summary>
|
||||
/// 图像委托事件 用于传出参数
|
||||
/// </summary>
|
||||
/// <param name="Image"></param>
|
||||
public delegate void delegateProcessHImage(Mat Image);
|
||||
|
||||
public event delegateProcessHImage EventProcessImage;
|
||||
|
||||
public void GetImage(Mat getimage)
|
||||
{
|
||||
MyImage = new Mat(getimage);
|
||||
EventProcessImage(MyImage);
|
||||
}
|
||||
}
|
||||
}
|
166
Define.cs
Normal file
166
Define.cs
Normal file
@ -0,0 +1,166 @@
|
||||
using OpenCvSharp;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Drawing;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
|
||||
public class LuJiaYi
|
||||
{
|
||||
// 使用属性而不是字段
|
||||
public string Product { get; set; }
|
||||
public int Num { get; set; }
|
||||
public double Distance { get; set; }
|
||||
public int Hole { get; set; }
|
||||
public string Load { get; set; }
|
||||
|
||||
// 默认构造函数
|
||||
public LuJiaYi()
|
||||
{
|
||||
}
|
||||
|
||||
// 带参数的构造函数
|
||||
public LuJiaYi(string product, int num, double distance, int hole, string load)
|
||||
{
|
||||
Product = product;
|
||||
Num = num;
|
||||
Distance = distance;
|
||||
Hole = hole;
|
||||
Load = load;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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 MLRequest()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
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 string JsonString { get; set; }
|
||||
}
|
||||
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 enum ResultState
|
||||
{
|
||||
[Description("检测NG")]
|
||||
DetectNG = 0,
|
||||
[Description("OK")]
|
||||
OK = 1,
|
||||
}
|
1303
HikCamDriver.cs
Normal file
1303
HikCamDriver.cs
Normal file
File diff suppressed because it is too large
Load Diff
486
HikCameraDriver.cs
Normal file
486
HikCameraDriver.cs
Normal file
@ -0,0 +1,486 @@
|
||||
|
||||
using MvCamCtrl.NET;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Drawing.Imaging;
|
||||
using System.Drawing;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading;
|
||||
using System.Net;
|
||||
using OpenCvSharp;
|
||||
using System.Reflection.Metadata;
|
||||
|
||||
|
||||
|
||||
|
||||
//[Device("HikCamera", "海康相机", EnumHelper.DeviceAttributeType.Device)]
|
||||
public class HikCameraDriver
|
||||
{
|
||||
|
||||
#region CameraBase
|
||||
|
||||
public bool IfSuccess = false;
|
||||
|
||||
float _lastExposure = 0;
|
||||
float _lastGain = 0;
|
||||
/// <summary>
|
||||
/// 相机拍照计数
|
||||
/// </summary>
|
||||
public volatile int SnapshotCount = 0;
|
||||
|
||||
public Action<DateTime, Mat, int> OnHImageOutput { get; set; }
|
||||
|
||||
public void Init()
|
||||
{
|
||||
|
||||
//_bufferImgSetQueue = new ConcurrentQueue<ImageSet>();
|
||||
//_bufferImgSet = new ImageSet();
|
||||
//pCallBackFunc = new MyCamera.cbExceptiondelegate(cbExceptiondelegate);
|
||||
#if false
|
||||
#region 根据IP连接相机
|
||||
|
||||
stDevInfo.nTLayerType = MyCamera.MV_GIGE_DEVICE;
|
||||
MyCamera.MV_GIGE_DEVICE_INFO stGigEDev = new MyCamera.MV_GIGE_DEVICE_INFO();
|
||||
//string strCurrentIp = IIConfig.CameraIP;// ch:需要连接的相机ip(根据实际填充)
|
||||
|
||||
//string strNetExport = IIConfig.ComputerIP; // ch:相机对应的网卡ip(根据实际填充)
|
||||
|
||||
string strCurrentIp = "192.168.1.21";// ch:需要连接的相机ip(根据实际填充)
|
||||
|
||||
string strNetExport = "192.168.1.20"; // ch:相机对应的网卡ip(根据实际填充)
|
||||
|
||||
var parts = strCurrentIp.Split('.');
|
||||
int nIp1 = Convert.ToInt32(parts[0]);
|
||||
int nIp2 = Convert.ToInt32(parts[1]);
|
||||
int nIp3 = Convert.ToInt32(parts[2]);
|
||||
int nIp4 = Convert.ToInt32(parts[3]);
|
||||
stGigEDev.nCurrentIp = (uint)((nIp1 << 24) | (nIp2 << 16) | (nIp3 << 8) | nIp4);
|
||||
|
||||
parts = strNetExport.Split('.');
|
||||
nIp1 = Convert.ToInt32(parts[0]);
|
||||
nIp2 = Convert.ToInt32(parts[1]);
|
||||
nIp3 = Convert.ToInt32(parts[2]);
|
||||
nIp4 = Convert.ToInt32(parts[3]);
|
||||
stGigEDev.nNetExport = (uint)((nIp1 << 24) | (nIp2 << 16) | (nIp3 << 8) | nIp4);
|
||||
|
||||
IntPtr stGigeInfoPtr = Marshal.AllocHGlobal(216);
|
||||
Marshal.StructureToPtr(stGigEDev, stGigeInfoPtr, false);
|
||||
stDevInfo.SpecialInfo.stGigEInfo = new Byte[540];
|
||||
Marshal.Copy(stGigeInfoPtr, stDevInfo.SpecialInfo.stGigEInfo, 0, 540);
|
||||
//释放内存空间
|
||||
Marshal.FreeHGlobal(stGigeInfoPtr);
|
||||
|
||||
#endregion
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
protected void Pause()
|
||||
{
|
||||
}
|
||||
|
||||
protected void Resume()
|
||||
{
|
||||
}
|
||||
|
||||
public void Start(string v)
|
||||
{
|
||||
#region 枚举相机后根据IP地址匹配连接相机
|
||||
//将IP地址转换为字节数组
|
||||
uint intAddress = 0;
|
||||
if (/*(IIConfig.HikCameraType == EnumHelper.HikCameraType.Gige) &&*/ (!string.IsNullOrWhiteSpace("192.168.1.21")))
|
||||
{
|
||||
byte[] IPArr = IPAddress.Parse("192.168.1.21").GetAddressBytes();
|
||||
for (int i = 0; i < IPArr.Length; i++)
|
||||
{
|
||||
intAddress += (uint)(IPArr[i] << (IPArr.Length - 1 - i) * 8);
|
||||
}
|
||||
}
|
||||
|
||||
MyCamera.MV_CC_DEVICE_INFO_LIST m_pDeviceList = new MyCamera.MV_CC_DEVICE_INFO_LIST();
|
||||
|
||||
int nRet = MyCamera.MV_CC_EnumDevices_NET(MyCamera.MV_GIGE_DEVICE | MyCamera.MV_USB_DEVICE, ref m_pDeviceList);
|
||||
if (0 != nRet)
|
||||
{
|
||||
throw new Exception($"Enumerate devices fail!");
|
||||
}
|
||||
else
|
||||
{
|
||||
//LogAsync(DateTime.Now, $"搜索获取{m_pDeviceList.nDeviceNum.ToInt()}台相机在线", "");
|
||||
}
|
||||
|
||||
bool isCameraFound = false;
|
||||
for (int i = 0; i < m_pDeviceList.nDeviceNum; i++)
|
||||
{
|
||||
MyCamera.MV_CC_DEVICE_INFO device = (MyCamera.MV_CC_DEVICE_INFO)Marshal.PtrToStructure(m_pDeviceList.pDeviceInfo[i], typeof(MyCamera.MV_CC_DEVICE_INFO));
|
||||
IntPtr buffer = IntPtr.Zero;
|
||||
|
||||
if (device.nTLayerType == MyCamera.MV_GIGE_DEVICE)
|
||||
{
|
||||
buffer = Marshal.UnsafeAddrOfPinnedArrayElement(device.SpecialInfo.stGigEInfo, 0);
|
||||
MyCamera.MV_GIGE_DEVICE_INFO stGigEDev = (MyCamera.MV_GIGE_DEVICE_INFO)Marshal.PtrToStructure(buffer, typeof(MyCamera.MV_GIGE_DEVICE_INFO));
|
||||
|
||||
if (stGigEDev.nCurrentIp == intAddress)
|
||||
{
|
||||
stDevInfo = device;
|
||||
isCameraFound = true;
|
||||
}
|
||||
}
|
||||
else if (device.nTLayerType == MyCamera.MV_USB_DEVICE)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
//释放内存空间
|
||||
//Marshal.FreeHGlobal(buffer);
|
||||
|
||||
if (isCameraFound)
|
||||
break;
|
||||
}
|
||||
|
||||
if (!isCameraFound)
|
||||
{
|
||||
throw new Exception($"相机未能找到");
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
// ch:创建设备 | en: Create device
|
||||
nRet = device.MV_CC_CreateDevice_NET(ref stDevInfo);
|
||||
if (MyCamera.MV_OK != nRet)
|
||||
{
|
||||
throw new Exception($"Create device failed:{nRet:x8}");
|
||||
}
|
||||
|
||||
// ch:打开设备 | en:Open device
|
||||
nRet = device.MV_CC_OpenDevice_NET();
|
||||
if (MyCamera.MV_OK != nRet)
|
||||
{
|
||||
throw new Exception($"Open device failed:{nRet:x8}");
|
||||
}
|
||||
|
||||
|
||||
// ch:探测网络最佳包大小(只对GigE相机有效) | en:Detection network optimal package size(It only works for the GigE camera)
|
||||
if (stDevInfo.nTLayerType == MyCamera.MV_GIGE_DEVICE)
|
||||
{
|
||||
int nPacketSize = device.MV_CC_GetOptimalPacketSize_NET();
|
||||
if (nPacketSize > 0)
|
||||
{
|
||||
nRet = device.MV_CC_SetIntValue_NET("GevSCPSPacketSize", (uint)nPacketSize);
|
||||
if (nRet != MyCamera.MV_OK)
|
||||
{
|
||||
Console.WriteLine("Warning: Set Packet Size failed {0:x8}", nRet);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("Warning: Get Packet Size failed {0:x8}", nPacketSize);
|
||||
}
|
||||
}
|
||||
|
||||
// ch:注册异常回调函数 | en:Register Exception Callback
|
||||
nRet = device.MV_CC_RegisterExceptionCallBack_NET(pCallBackFunc, IntPtr.Zero);
|
||||
if (MyCamera.MV_OK != nRet)
|
||||
{
|
||||
throw new Exception($"Register expection callback failed:{nRet}");
|
||||
}
|
||||
GC.KeepAlive(pCallBackFunc);
|
||||
|
||||
// ch:设置采集连续模式 | en:Set Continues Aquisition Mode
|
||||
device.MV_CC_SetEnumValue_NET("AcquisitionMode", 2);// ch:工作在连续模式 | en:Acquisition On Continuous Mode
|
||||
if (false)
|
||||
{
|
||||
device.MV_CC_SetEnumValue_NET("TriggerMode", 0); // ch:连续模式 | en:Continuous
|
||||
|
||||
// ch:注册回调函数 | en:Register image callback
|
||||
ImageCallback = new MyCamera.cbOutputExdelegate(ImageCallbackFunc);
|
||||
nRet = device.MV_CC_RegisterImageCallBackEx_NET(ImageCallback, IntPtr.Zero);
|
||||
if (MyCamera.MV_OK != nRet)
|
||||
{
|
||||
throw new Exception("Register image callback failed!");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// ch:设置触发模式为off || en:set trigger mode as off
|
||||
nRet = device.MV_CC_SetEnumValue_NET("TriggerMode", 1);
|
||||
if (MyCamera.MV_OK != nRet)
|
||||
{
|
||||
throw new Exception("Set TriggerMode failed!");
|
||||
}
|
||||
|
||||
if (false)
|
||||
{
|
||||
// ch:触发源选择:0 - Line0; | en:Trigger source select:0 - Line0;
|
||||
// 1 - Line1;
|
||||
// 2 - Line2;
|
||||
// 3 - Line3;
|
||||
// 4 - Counter;
|
||||
// 7 - Software;
|
||||
nRet = device.MV_CC_SetEnumValue_NET("TriggerSource", 0);
|
||||
if (MyCamera.MV_OK != nRet)
|
||||
{
|
||||
throw new Exception("Set Line0 Trigger failed!");
|
||||
}
|
||||
|
||||
// ch:注册回调函数 | en:Register image callback
|
||||
ImageCallback = new MyCamera.cbOutputExdelegate(ImageCallbackFunc);
|
||||
nRet = device.MV_CC_RegisterImageCallBackEx_NET(ImageCallback, IntPtr.Zero);
|
||||
if (MyCamera.MV_OK != nRet)
|
||||
{
|
||||
throw new Exception("Register image callback failed!");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
nRet = device.MV_CC_SetEnumValue_NET("TriggerSource", 7);
|
||||
if (MyCamera.MV_OK != nRet)
|
||||
{
|
||||
throw new Exception("Set Software Trigger failed!");
|
||||
}
|
||||
}
|
||||
}
|
||||
// ch:开启抓图 || en: start grab image
|
||||
nRet = device.MV_CC_StartGrabbing_NET();
|
||||
if (MyCamera.MV_OK != nRet)
|
||||
{
|
||||
throw new Exception($"Start grabbing failed:{nRet:x8}");
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
IfSuccess = true;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
private void IIConfig_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
|
||||
{
|
||||
if (e.PropertyName == "IsHardwareTrigger" && !false)
|
||||
{
|
||||
// ch:停止抓图 | en:Stop grab image
|
||||
nRet = device.MV_CC_StopGrabbing_NET();
|
||||
if (MyCamera.MV_OK != nRet)
|
||||
{
|
||||
throw new Exception($"Stop grabbing failed{nRet:x8}");
|
||||
}
|
||||
|
||||
if (false)
|
||||
{
|
||||
// ch:触发源选择:0 - Line0; | en:Trigger source select:0 - Line0;
|
||||
// 1 - Line1;
|
||||
// 2 - Line2;
|
||||
// 3 - Line3;
|
||||
// 4 - Counter;
|
||||
// 7 - Software;
|
||||
nRet = device.MV_CC_SetEnumValue_NET("TriggerSource", 0);
|
||||
if (MyCamera.MV_OK != nRet)
|
||||
{
|
||||
throw new Exception("Set Line0 Trigger failed!");
|
||||
}
|
||||
|
||||
// ch:注册回调函数 | en:Register image callback
|
||||
ImageCallback = new MyCamera.cbOutputExdelegate(ImageCallbackFunc);
|
||||
nRet = device.MV_CC_RegisterImageCallBackEx_NET(ImageCallback, IntPtr.Zero);
|
||||
if (MyCamera.MV_OK != nRet)
|
||||
{
|
||||
throw new Exception("Register image callback failed!");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
nRet = device.MV_CC_SetEnumValue_NET("TriggerSource", 7);
|
||||
if (MyCamera.MV_OK != nRet)
|
||||
{
|
||||
throw new Exception("Set Software Trigger failed!");
|
||||
}
|
||||
}
|
||||
|
||||
// ch:开启抓图 || en: start grab image
|
||||
nRet = device.MV_CC_StartGrabbing_NET();
|
||||
if (MyCamera.MV_OK != nRet)
|
||||
{
|
||||
throw new Exception($"Start grabbing failed:{nRet:x8}");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public void Stop()
|
||||
{
|
||||
// IIConfig.PropertyChanged -= IIConfig_PropertyChanged;
|
||||
|
||||
|
||||
// ch:停止抓图 | en:Stop grab image
|
||||
nRet = device.MV_CC_StopGrabbing_NET();
|
||||
if (MyCamera.MV_OK != nRet)
|
||||
{
|
||||
throw new Exception($"Stop grabbing failed{nRet:x8}");
|
||||
}
|
||||
|
||||
// ch:关闭设备 | en:Close device
|
||||
nRet = device.MV_CC_CloseDevice_NET();
|
||||
if (MyCamera.MV_OK != nRet)
|
||||
{
|
||||
throw new Exception($"Close device failed{nRet:x8}");
|
||||
}
|
||||
|
||||
// ch:销毁设备 | en:Destroy device
|
||||
nRet = device.MV_CC_DestroyDevice_NET();
|
||||
if (MyCamera.MV_OK != nRet)
|
||||
{
|
||||
throw new Exception($"Destroy device failed:{nRet:x8}");
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region HikCamera
|
||||
public MyCamera.cbOutputExdelegate ImageCallback;
|
||||
MyCamera.MV_FRAME_OUT _frame = new MyCamera.MV_FRAME_OUT();
|
||||
readonly ManualResetEvent _snapHandle = new ManualResetEvent(false);
|
||||
bool _snapFlag = false;
|
||||
|
||||
//ImageSet _bufferImgSet = null;
|
||||
ManualResetEvent _bufferHandle = new ManualResetEvent(false);
|
||||
//ConcurrentQueue<ImageSet> _bufferImgSetQueue = new ConcurrentQueue<ImageSet>();
|
||||
//volatile ImageSet _bufferImgSet = new ImageSet();
|
||||
|
||||
|
||||
void ImageCallbackFunc(IntPtr pData, ref MyCamera.MV_FRAME_OUT_INFO_EX pFrameInfo, IntPtr pUser)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
if (_snapFlag)
|
||||
{
|
||||
_snapFlag = false;
|
||||
_frame = new MyCamera.MV_FRAME_OUT
|
||||
{
|
||||
stFrameInfo = pFrameInfo,
|
||||
pBufAddr = pData
|
||||
};
|
||||
_snapHandle.Set();
|
||||
}
|
||||
// }
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
//LogAsync(DateTime.Now, LogLevel.Exception, $"{Name}相机取像异常,{ex.GetExceptionMessage()}");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
private bool IsMonoData(MyCamera.MvGvspPixelType enGvspPixelType)
|
||||
{
|
||||
switch (enGvspPixelType)
|
||||
{
|
||||
case MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono8:
|
||||
case MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono10:
|
||||
case MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono10_Packed:
|
||||
case MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono12:
|
||||
case MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono12_Packed:
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public void RefreshImageBufferHandle()
|
||||
{
|
||||
//_bufferImgSet?.Dispose();
|
||||
//_bufferImgSet = null;
|
||||
|
||||
_bufferHandle.Reset();
|
||||
}
|
||||
|
||||
object _bufferLock = new object();
|
||||
|
||||
|
||||
|
||||
public void Snapshot(int pageBum, string napshotFileName)
|
||||
{
|
||||
//SnapshotCount = pageBum;
|
||||
//SnapshotFileNames = napshotFileName;
|
||||
|
||||
Snapshot();
|
||||
}
|
||||
public void Snapshot()
|
||||
{
|
||||
Stopwatch sw = new Stopwatch();
|
||||
sw.Start();
|
||||
|
||||
MyCamera.MV_FRAME_OUT frameInfo = new MyCamera.MV_FRAME_OUT();
|
||||
nRet = MyCamera.MV_OK;
|
||||
if (true)
|
||||
{
|
||||
// ch: 触发命令 || en: Trigger command
|
||||
nRet = device.MV_CC_SetCommandValue_NET("TriggerSoftware");
|
||||
if (MyCamera.MV_OK != nRet)
|
||||
{
|
||||
throw new Exception($"相机拍照触发失败:{nRet}");
|
||||
}
|
||||
|
||||
nRet = device.MV_CC_GetImageBuffer_NET(ref frameInfo, 1000);
|
||||
nRet = device.MV_CC_FreeImageBuffer_NET(ref frameInfo);
|
||||
}
|
||||
else
|
||||
{
|
||||
_snapHandle.Reset();
|
||||
_snapFlag = true;
|
||||
_snapHandle.WaitOne();
|
||||
//lock (_imgCallBackLock)
|
||||
{
|
||||
frameInfo.stFrameInfo = _frame.stFrameInfo;
|
||||
frameInfo.pBufAddr = _frame.pBufAddr;
|
||||
}
|
||||
}
|
||||
|
||||
// ch:获取一帧图像 | en:Get one image
|
||||
if (MyCamera.MV_OK == nRet)
|
||||
{
|
||||
if (frameInfo.pBufAddr != IntPtr.Zero)
|
||||
{
|
||||
if (nRet == MyCamera.MV_OK)
|
||||
{
|
||||
var pFrameInfo = frameInfo.stFrameInfo;
|
||||
|
||||
Mat _mat = new Mat(pFrameInfo.nWidth, pFrameInfo.nHeight, MatType.CV_8UC3, frameInfo.pBufAddr);
|
||||
OnHImageOutput?.Invoke(DateTime.Now, _mat, SnapshotCount);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception($"Grap Image Failed:{nRet:x8}");
|
||||
}
|
||||
|
||||
sw.Stop();
|
||||
//LogAsync(DateTime.Now, LogLevel.Information, $"取像耗时:{sw.ElapsedMilliseconds} ms");
|
||||
}
|
||||
|
||||
|
||||
|
||||
readonly MyCamera device = new MyCamera();
|
||||
MyCamera.MV_CC_DEVICE_INFO stDevInfo = new MyCamera.MV_CC_DEVICE_INFO();
|
||||
int nRet = MyCamera.MV_OK;
|
||||
MyCamera.cbExceptiondelegate pCallBackFunc;
|
||||
|
||||
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
0
JianZhenQi1.db
Normal file
0
JianZhenQi1.db
Normal file
293
LuJiaYi.csproj
Normal file
293
LuJiaYi.csproj
Normal file
@ -0,0 +1,293 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="packages\Microsoft.ML.OnnxRuntime.1.15.1\build\netstandard2.0\Microsoft.ML.OnnxRuntime.props" Condition="Exists('packages\Microsoft.ML.OnnxRuntime.1.15.1\build\netstandard2.0\Microsoft.ML.OnnxRuntime.props')" />
|
||||
<Import Project="packages\OpenVINO.runtime.win.2024.3.0.1\build\net\OpenVINO.runtime.win.props" Condition="Exists('packages\OpenVINO.runtime.win.2024.3.0.1\build\net\OpenVINO.runtime.win.props')" />
|
||||
<Import Project="packages\EntityFramework.6.4.4\build\EntityFramework.props" Condition="Exists('packages\EntityFramework.6.4.4\build\EntityFramework.props')" />
|
||||
<Import Project="packages\OpenCvSharp4.runtime.win.4.5.5.20211231\build\netstandard\OpenCvSharp4.runtime.win.props" Condition="Exists('packages\OpenCvSharp4.runtime.win.4.5.5.20211231\build\netstandard\OpenCvSharp4.runtime.win.props')" />
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{B79451BB-0B27-4B9E-9DFE-2ED254D26903}</ProjectGuid>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<RootNamespace>WindowsFormsApp1</RootNamespace>
|
||||
<AssemblyName>WindowsFormsApp1</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
||||
<Deterministic>true</Deterministic>
|
||||
<NuGetPackageImportStamp>
|
||||
</NuGetPackageImportStamp>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<Prefer32Bit>false</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>bin\x64\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<LangVersion>7.3</LangVersion>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<Prefer32Bit>false</Prefer32Bit>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<WarningLevel>0</WarningLevel>
|
||||
<Optimize>false</Optimize>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
|
||||
<OutputPath>bin\x64\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<LangVersion>7.3</LangVersion>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="BouncyCastle.Crypto, Version=1.9.0.0, Culture=neutral, PublicKeyToken=0e99375e54769942, processorArchitecture=MSIL">
|
||||
<HintPath>packages\Portable.BouncyCastle.1.9.0\lib\net40\BouncyCastle.Crypto.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="BouncyCastle.Cryptography, Version=2.0.0.0, Culture=neutral, PublicKeyToken=072edcf4a5328938, processorArchitecture=MSIL">
|
||||
<HintPath>packages\BouncyCastle.Cryptography.2.4.0\lib\net461\BouncyCastle.Cryptography.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="DVPCameraCS64, Version=2.0.0.1, Culture=neutral, processorArchitecture=AMD64">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>bin\x64\Debug\DVPCameraCS64.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Emgu.CV, Version=4.7.0.5276, Culture=neutral, PublicKeyToken=7281126722ab4438, processorArchitecture=MSIL">
|
||||
<HintPath>packages\Emgu.CV.4.7.0.5276\lib\netstandard2.0\Emgu.CV.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
|
||||
<HintPath>packages\EntityFramework.6.4.4\lib\net45\EntityFramework.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="EntityFramework.SqlServer, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
|
||||
<HintPath>packages\EntityFramework.6.4.4\lib\net45\EntityFramework.SqlServer.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Google.Protobuf, Version=3.21.9.0, Culture=neutral, PublicKeyToken=a7d26565bac4d604, processorArchitecture=MSIL">
|
||||
<HintPath>packages\Google.Protobuf.3.21.9\lib\net45\Google.Protobuf.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="halcondotnet, Version=19.11.0.0, Culture=neutral, PublicKeyToken=4973bed59ddbf2b8, processorArchitecture=MSIL">
|
||||
<HintPath>packages\HalconDotNet.19.11.0\lib\net35\halcondotnet.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="HslCommunication, Version=12.0.3.0, Culture=neutral, PublicKeyToken=3d72ad3b6b5ec0e3, processorArchitecture=MSIL">
|
||||
<HintPath>packages\HslCommunication.12.0.3\lib\net451\HslCommunication.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="K4os.Compression.LZ4, Version=1.2.16.0, Culture=neutral, PublicKeyToken=2186fa9121ef231d, processorArchitecture=MSIL">
|
||||
<HintPath>packages\K4os.Compression.LZ4.1.2.16\lib\net46\K4os.Compression.LZ4.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="K4os.Compression.LZ4.Streams, Version=1.2.16.0, Culture=neutral, PublicKeyToken=2186fa9121ef231d, processorArchitecture=MSIL">
|
||||
<HintPath>packages\K4os.Compression.LZ4.Streams.1.2.16\lib\net46\K4os.Compression.LZ4.Streams.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="K4os.Hash.xxHash, Version=1.0.7.0, Culture=neutral, PublicKeyToken=32cd54395057cec3, processorArchitecture=MSIL">
|
||||
<HintPath>packages\K4os.Hash.xxHash.1.0.7\lib\net46\K4os.Hash.xxHash.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.Bcl.AsyncInterfaces, Version=8.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
|
||||
<HintPath>packages\Microsoft.Bcl.AsyncInterfaces.8.0.0\lib\net462\Microsoft.Bcl.AsyncInterfaces.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.ML.OnnxRuntime, Version=0.0.0.0, Culture=neutral, PublicKeyToken=f27f157f0a5b7bb6, processorArchitecture=MSIL">
|
||||
<HintPath>packages\Microsoft.ML.OnnxRuntime.Managed.1.15.1\lib\netstandard2.0\Microsoft.ML.OnnxRuntime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="MvCameraControl.Net, Version=3.4.0.1, Culture=neutral, PublicKeyToken=52fddfb3f94be800, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>bin\x64\Debug\MvCameraControl.Net.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="MySql.Data, Version=8.0.32.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d, processorArchitecture=MSIL">
|
||||
<HintPath>packages\MySql.Data.8.0.32.1\lib\net452\MySql.Data.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Newtonsoft.Json, Version=13.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
||||
<HintPath>packages\Newtonsoft.Json.13.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="OpenCvSharp, Version=1.0.0.0, Culture=neutral, PublicKeyToken=6adad1e807fea099, processorArchitecture=MSIL">
|
||||
<HintPath>packages\OpenCvSharp4.4.5.3.20211207\lib\net461\OpenCvSharp.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="OpenCvSharp.Extensions, Version=1.0.0.0, Culture=neutral, PublicKeyToken=6adad1e807fea099, processorArchitecture=MSIL">
|
||||
<HintPath>packages\OpenCvSharp4.4.5.3.20211207\lib\net461\OpenCvSharp.Extensions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="picEx, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>bin\x64\Debug\picEx.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="SQLitePCLRaw.core, Version=2.1.9.2410, Culture=neutral, PublicKeyToken=1488e028ca7ab535, processorArchitecture=MSIL">
|
||||
<HintPath>packages\SQLitePCLRaw.core.2.1.9\lib\netstandard2.0\SQLitePCLRaw.core.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Buffers, Version=4.0.3.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
|
||||
<HintPath>packages\System.Buffers.4.5.1\lib\net461\System.Buffers.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Collections.Immutable, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>packages\System.Collections.Immutable.8.0.0\lib\net462\System.Collections.Immutable.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.ComponentModel.Composition" />
|
||||
<Reference Include="System.ComponentModel.DataAnnotations" />
|
||||
<Reference Include="System.Configuration" />
|
||||
<Reference Include="System.Configuration.ConfigurationManager, Version=4.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
|
||||
<HintPath>packages\System.Configuration.ConfigurationManager.4.4.1\lib\net461\System.Configuration.ConfigurationManager.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Configuration.Install" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Data.SQLite, Version=1.0.118.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139, processorArchitecture=MSIL">
|
||||
<HintPath>packages\Stub.System.Data.SQLite.Core.NetFramework.1.0.118.0\lib\net46\System.Data.SQLite.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Data.SQLite.EF6, Version=1.0.118.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139, processorArchitecture=MSIL">
|
||||
<HintPath>packages\System.Data.SQLite.EF6.1.0.118.0\lib\net46\System.Data.SQLite.EF6.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Data.SQLite.Linq, Version=1.0.118.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139, processorArchitecture=MSIL">
|
||||
<HintPath>packages\System.Data.SQLite.Linq.1.0.118.0\lib\net46\System.Data.SQLite.Linq.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Diagnostics.DiagnosticSource, Version=8.0.0.1, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
|
||||
<HintPath>packages\System.Diagnostics.DiagnosticSource.8.0.1\lib\net462\System.Diagnostics.DiagnosticSource.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Drawing.Common, Version=8.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
|
||||
<HintPath>packages\System.Drawing.Common.8.0.7\lib\net462\System.Drawing.Common.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Drawing.Primitives, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>packages\System.Drawing.Primitives.4.3.0\lib\net45\System.Drawing.Primitives.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="System.IO.Pipelines, Version=6.0.0.3, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
|
||||
<HintPath>packages\System.IO.Pipelines.6.0.3\lib\net461\System.IO.Pipelines.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Management" />
|
||||
<Reference Include="System.Memory, Version=4.0.1.2, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
|
||||
<HintPath>packages\System.Memory.4.5.5\lib\net461\System.Memory.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Numerics" />
|
||||
<Reference Include="System.Numerics.Vectors, Version=4.1.4.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Reflection.Metadata, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>packages\System.Reflection.Metadata.5.0.0\lib\net461\System.Reflection.Metadata.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime" />
|
||||
<Reference Include="System.Runtime.CompilerServices.Unsafe, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>packages\System.Runtime.CompilerServices.Unsafe.6.0.0\lib\net461\System.Runtime.CompilerServices.Unsafe.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime.Extensions, Version=4.1.1.1, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>packages\System.Runtime.Extensions.4.3.1\lib\net462\System.Runtime.Extensions.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime.InteropServices.RuntimeInformation, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>packages\System.Runtime.InteropServices.RuntimeInformation.4.3.0\lib\net45\System.Runtime.InteropServices.RuntimeInformation.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="System.Text.Encodings.Web, Version=8.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
|
||||
<HintPath>packages\System.Text.Encodings.Web.8.0.0\lib\net462\System.Text.Encodings.Web.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Text.Json, Version=6.0.0.9, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
|
||||
<HintPath>packages\System.Text.Json.6.0.9\lib\net461\System.Text.Json.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Threading.Tasks.Extensions, Version=4.2.0.1, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
|
||||
<HintPath>packages\System.Threading.Tasks.Extensions.4.5.4\lib\net461\System.Threading.Tasks.Extensions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Transactions" />
|
||||
<Reference Include="System.ValueTuple, Version=4.0.3.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
|
||||
<HintPath>packages\System.ValueTuple.4.5.0\lib\net47\System.ValueTuple.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Deployment" />
|
||||
<Reference Include="System.Drawing" />
|
||||
<Reference Include="System.Net.Http" />
|
||||
<Reference Include="System.Windows.Forms" />
|
||||
<Reference Include="System.Xml" />
|
||||
<Reference Include="ZstdSharp, Version=0.6.5.0, Culture=neutral, PublicKeyToken=8d151af33a4ad5cf, processorArchitecture=MSIL">
|
||||
<HintPath>packages\ZstdSharp.Port.0.6.5\lib\net461\ZstdSharp.dll</HintPath>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="CameraBase.cs" />
|
||||
<Compile Include="CamManager.cs" />
|
||||
<Compile Include="MGSCameraDriver.cs" />
|
||||
<Compile Include="PlcContorl.cs" />
|
||||
<Compile Include="PLCItem.cs" />
|
||||
<Compile Include="StaticHelper.cs" />
|
||||
<Compile Include="Thread.cs" />
|
||||
<Compile Include="MLResultDisplay.cs" />
|
||||
<Compile Include="Define.cs" />
|
||||
<Compile Include="HikCameraDriver.cs" />
|
||||
<Compile Include="Process_Img.cs" />
|
||||
<Compile Include="SimboObjectDetection.cs" />
|
||||
<Compile Include="SQLConnect.cs" />
|
||||
<Compile Include="WriteLog.cs" />
|
||||
<Compile Include="HikCamDriver.cs" />
|
||||
<Compile Include="MainForm.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="MainForm.Designer.cs">
|
||||
<DependentUpon>MainForm.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Program.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<EmbeddedResource Include="MainForm.resx">
|
||||
<DependentUpon>MainForm.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Properties\Resources.resx">
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
|
||||
<SubType>Designer</SubType>
|
||||
</EmbeddedResource>
|
||||
<Compile Include="Properties\Resources.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>Resources.resx</DependentUpon>
|
||||
</Compile>
|
||||
<None Include="packages.config" />
|
||||
<None Include="Properties\Settings.settings">
|
||||
<Generator>SettingsSingleFileGenerator</Generator>
|
||||
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
|
||||
</None>
|
||||
<Compile Include="Properties\Settings.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>Settings.settings</DependentUpon>
|
||||
<DesignTimeSharedInput>True</DesignTimeSharedInput>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="App.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<WCFMetadata Include="Connected Services\" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
<ErrorText>这台计算机上缺少此项目引用的 NuGet 程序包。使用“NuGet 程序包还原”可下载这些程序包。有关更多信息,请参见 http://go.microsoft.com/fwlink/?LinkID=322105。缺少的文件是 {0}。</ErrorText>
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('packages\OpenCvSharp4.runtime.win.4.5.5.20211231\build\netstandard\OpenCvSharp4.runtime.win.props')" Text="$([System.String]::Format('$(ErrorText)', 'packages\OpenCvSharp4.runtime.win.4.5.5.20211231\build\netstandard\OpenCvSharp4.runtime.win.props'))" />
|
||||
<Error Condition="!Exists('packages\EntityFramework.6.4.4\build\EntityFramework.props')" Text="$([System.String]::Format('$(ErrorText)', 'packages\EntityFramework.6.4.4\build\EntityFramework.props'))" />
|
||||
<Error Condition="!Exists('packages\EntityFramework.6.4.4\build\EntityFramework.targets')" Text="$([System.String]::Format('$(ErrorText)', 'packages\EntityFramework.6.4.4\build\EntityFramework.targets'))" />
|
||||
<Error Condition="!Exists('packages\Stub.System.Data.SQLite.Core.NetFramework.1.0.118.0\build\net46\Stub.System.Data.SQLite.Core.NetFramework.targets')" Text="$([System.String]::Format('$(ErrorText)', 'packages\Stub.System.Data.SQLite.Core.NetFramework.1.0.118.0\build\net46\Stub.System.Data.SQLite.Core.NetFramework.targets'))" />
|
||||
<Error Condition="!Exists('packages\OpenVINO.runtime.win.2024.3.0.1\build\net\OpenVINO.runtime.win.props')" Text="$([System.String]::Format('$(ErrorText)', 'packages\OpenVINO.runtime.win.2024.3.0.1\build\net\OpenVINO.runtime.win.props'))" />
|
||||
<Error Condition="!Exists('packages\Microsoft.ML.OnnxRuntime.Managed.1.15.1\build\netstandard2.0\Microsoft.ML.OnnxRuntime.Managed.targets')" Text="$([System.String]::Format('$(ErrorText)', 'packages\Microsoft.ML.OnnxRuntime.Managed.1.15.1\build\netstandard2.0\Microsoft.ML.OnnxRuntime.Managed.targets'))" />
|
||||
<Error Condition="!Exists('packages\Microsoft.ML.OnnxRuntime.1.15.1\build\netstandard2.0\Microsoft.ML.OnnxRuntime.props')" Text="$([System.String]::Format('$(ErrorText)', 'packages\Microsoft.ML.OnnxRuntime.1.15.1\build\netstandard2.0\Microsoft.ML.OnnxRuntime.props'))" />
|
||||
<Error Condition="!Exists('packages\Microsoft.ML.OnnxRuntime.1.15.1\build\netstandard2.0\Microsoft.ML.OnnxRuntime.targets')" Text="$([System.String]::Format('$(ErrorText)', 'packages\Microsoft.ML.OnnxRuntime.1.15.1\build\netstandard2.0\Microsoft.ML.OnnxRuntime.targets'))" />
|
||||
</Target>
|
||||
<Import Project="packages\EntityFramework.6.4.4\build\EntityFramework.targets" Condition="Exists('packages\EntityFramework.6.4.4\build\EntityFramework.targets')" />
|
||||
<Import Project="packages\Stub.System.Data.SQLite.Core.NetFramework.1.0.118.0\build\net46\Stub.System.Data.SQLite.Core.NetFramework.targets" Condition="Exists('packages\Stub.System.Data.SQLite.Core.NetFramework.1.0.118.0\build\net46\Stub.System.Data.SQLite.Core.NetFramework.targets')" />
|
||||
<Import Project="packages\Microsoft.ML.OnnxRuntime.Managed.1.15.1\build\netstandard2.0\Microsoft.ML.OnnxRuntime.Managed.targets" Condition="Exists('packages\Microsoft.ML.OnnxRuntime.Managed.1.15.1\build\netstandard2.0\Microsoft.ML.OnnxRuntime.Managed.targets')" />
|
||||
<Import Project="packages\Microsoft.ML.OnnxRuntime.1.15.1\build\netstandard2.0\Microsoft.ML.OnnxRuntime.targets" Condition="Exists('packages\Microsoft.ML.OnnxRuntime.1.15.1\build\netstandard2.0\Microsoft.ML.OnnxRuntime.targets')" />
|
||||
</Project>
|
31
LuJiaYi.sln
Normal file
31
LuJiaYi.sln
Normal file
@ -0,0 +1,31 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.10.35013.160
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LuJiaYi", "LuJiaYi.csproj", "{B79451BB-0B27-4B9E-9DFE-2ED254D26903}"
|
||||
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
|
||||
{B79451BB-0B27-4B9E-9DFE-2ED254D26903}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{B79451BB-0B27-4B9E-9DFE-2ED254D26903}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{B79451BB-0B27-4B9E-9DFE-2ED254D26903}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{B79451BB-0B27-4B9E-9DFE-2ED254D26903}.Debug|x64.Build.0 = Debug|x64
|
||||
{B79451BB-0B27-4B9E-9DFE-2ED254D26903}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{B79451BB-0B27-4B9E-9DFE-2ED254D26903}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{B79451BB-0B27-4B9E-9DFE-2ED254D26903}.Release|x64.ActiveCfg = Release|x64
|
||||
{B79451BB-0B27-4B9E-9DFE-2ED254D26903}.Release|x64.Build.0 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {638D3E31-F0F3-4E6A-869E-B55B17EF1BD2}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
714
MGSCameraDriver.cs
Normal file
714
MGSCameraDriver.cs
Normal file
@ -0,0 +1,714 @@
|
||||
|
||||
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> 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);
|
||||
// }
|
||||
//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);
|
||||
//_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
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
216
MLResultDisplay.cs
Normal file
216
MLResultDisplay.cs
Normal file
@ -0,0 +1,216 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
|
||||
|
||||
namespace WindowsFormsApp1
|
||||
{
|
||||
public class DetectResultDisplay
|
||||
{
|
||||
//深度学习 显示结果
|
||||
private List<DetectionResultDetail> mlResultList = null;
|
||||
public List<DetectionResultDetail> MLResultList
|
||||
{
|
||||
get => mlResultList;
|
||||
set
|
||||
{
|
||||
if (mlResultList != value)
|
||||
{
|
||||
mlResultList = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
string DisplayTxt = "";
|
||||
Bitmap ResultImage = null;
|
||||
PointF StartPoint = new PointF();
|
||||
Brush FontBrush = new SolidBrush(Color.Green);
|
||||
Pen DetectResultRectPen = new Pen(new SolidBrush(Color.Green));
|
||||
|
||||
public Font Font { get; private set; }
|
||||
ResultState ResultState = ResultState.DetectNG;
|
||||
|
||||
Font DetectResultFont = new Font(new FontFamily("Tahoma"), 15, GraphicsUnit.World);
|
||||
|
||||
public int ImageWidth { get; set; }
|
||||
public int ImageHeight { get; set; }
|
||||
public DetectResultDisplay() { }
|
||||
|
||||
//public DetectResultDisplay(NetResult result, List<IndexedSpec> specs, ResultState resultState, int imageWidth)
|
||||
//{
|
||||
// ImageWidth = imageWidth;
|
||||
|
||||
// ResultState = resultState;
|
||||
|
||||
// displayTxt = resultState.ToString() + "\r\n";
|
||||
// if (resultState != ResultState.OK)
|
||||
// {
|
||||
// fontBrush = new SolidBrush(Color.Red);
|
||||
// }
|
||||
|
||||
// NetResult = result;
|
||||
// SpecList = specs;
|
||||
|
||||
// Font = new Font(new FontFamily("Tahoma"), 35 * ImageWidth / 1400, GraphicsUnit.World);
|
||||
// startPoint = new PointF(150 * ImageWidth / 1400, 150 * ImageWidth / 1400);
|
||||
//}
|
||||
|
||||
public DetectResultDisplay(List<DetectionResultDetail> ResultDetails, Bitmap resultImage, string displayTxt)
|
||||
{
|
||||
ImageWidth = resultImage.Width;
|
||||
ImageHeight = resultImage.Height;
|
||||
var longSide = ImageWidth > ImageHeight ? ImageWidth : ImageHeight;
|
||||
|
||||
MLResultList = ResultDetails;
|
||||
|
||||
ResultImage = resultImage;
|
||||
DisplayTxt = displayTxt;
|
||||
if (ResultState != ResultState.OK)
|
||||
{
|
||||
FontBrush = new SolidBrush(Color.Red);
|
||||
DetectResultRectPen = new Pen(new SolidBrush(Color.Red));
|
||||
}
|
||||
Font = new Font(new FontFamily("Tahoma"), 35 * longSide / 1400, GraphicsUnit.World);
|
||||
DetectResultFont = new Font(new FontFamily("Tahoma"), 25 * longSide / 1400, GraphicsUnit.World);
|
||||
StartPoint = new PointF(100 * ImageWidth / 1400, 100 * ImageHeight / 1400);
|
||||
}
|
||||
|
||||
public object Clone()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public void Draw(Graphics g)
|
||||
{
|
||||
//画检测结果图
|
||||
if (ResultImage != null && ResultState != ResultState.OK)
|
||||
{
|
||||
g.DrawImage(ResultImage, new Point(0, 0));
|
||||
}
|
||||
//画文字
|
||||
if (!string.IsNullOrWhiteSpace(DisplayTxt))
|
||||
{
|
||||
g.DrawString(DisplayTxt, Font, FontBrush, StartPoint);
|
||||
}
|
||||
//画外接矩形+label 深度学习
|
||||
if (MLResultList != null && MLResultList.Count > 0)
|
||||
{
|
||||
MLResultList.ForEach(d =>
|
||||
{
|
||||
g.DrawRectangle(DetectResultRectPen, d.Rect);
|
||||
|
||||
string locationTxt = $"{d.LabelDisplay}";
|
||||
var locationX = d.Rect.X;
|
||||
var locationY = d.Rect.Y <= 20 ? d.Rect.Y + 20 : d.Rect.Y - 20;
|
||||
g.DrawString(locationTxt, DetectResultFont, FontBrush, locationX, locationY);
|
||||
});
|
||||
}
|
||||
//画spec信息
|
||||
|
||||
//if (DetectResult != null && DetectResult.NetResult?.DetectDetails?.Count > 0)
|
||||
//{
|
||||
// DetectResult.NetResult?.DetectDetails.ForEach(d =>
|
||||
// {
|
||||
// g.DrawRectangle(defectRectPen, d.Rect);
|
||||
|
||||
// string locationTxt = $"{d.Rect.X},{d.Rect.Y}";
|
||||
// g.DrawString(locationTxt, defectFont, fontBrush, d.Rect.X, d.Rect.Y - 5);
|
||||
// });
|
||||
//}
|
||||
|
||||
//float fontHeight = g.MeasureString(displayTxt, Font).Height;
|
||||
//startPoint.Y += fontHeight * 1.2f;
|
||||
|
||||
//var defects = DetectResult.NetResult?.DetectDetails;
|
||||
//if (defects != null && defects.Count > 0)
|
||||
//{
|
||||
// defects.ForEach(d =>
|
||||
// {
|
||||
// g.DrawString($"{d.ClassName} X:{d.Rect.X.ToString("f2")} Y:{d.Rect.Y.ToString("f2")} S:{d.Area}", Font, d.FinalResult == EnumHelper.ResultState.OK ? fontBrushOK : fontBrushNG, startPoint);
|
||||
|
||||
// startPoint.Y += fontHeight;
|
||||
// });
|
||||
//}
|
||||
|
||||
//DetectResult.Specs.ForEach(s =>
|
||||
//{
|
||||
// g.DrawString($"{s.Code}:{(s.ActualValue ?? 0).ToString("f2")}", Font, s.MeasureResult ?? false == true ? fontBrushOK : fontBrushNG, startPoint);
|
||||
|
||||
// startPoint.Y += fontHeight;
|
||||
//});
|
||||
}
|
||||
|
||||
public string GetDisplayText()
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public class RectResultDisplay
|
||||
{
|
||||
ResultState ResultState = ResultState.DetectNG;
|
||||
public string DisplayTxt = "";
|
||||
Color FillColor = Color.Lime;
|
||||
int FontSize = 15;
|
||||
RectangleF Rect = new RectangleF();
|
||||
bool IsFilled = false;
|
||||
|
||||
public RectResultDisplay() { }
|
||||
|
||||
public RectResultDisplay(ResultState _resultState, RectangleF _rect, string _displayTxt, Color _fillColor, bool _isFilled, int _fontSize)
|
||||
{
|
||||
ResultState = _resultState;
|
||||
Rect = _rect;
|
||||
DisplayTxt = _displayTxt;
|
||||
FillColor = _fillColor;
|
||||
IsFilled = _isFilled;
|
||||
FontSize = _fontSize;
|
||||
}
|
||||
|
||||
public object Clone()
|
||||
{
|
||||
RectResultDisplay rect = new RectResultDisplay();
|
||||
|
||||
rect.ResultState = ResultState;
|
||||
rect.Rect = Rect;
|
||||
rect.DisplayTxt = DisplayTxt;
|
||||
rect.FillColor = FillColor;
|
||||
rect.FontSize = FontSize;
|
||||
rect.IsFilled = IsFilled;
|
||||
|
||||
return rect;
|
||||
}
|
||||
|
||||
public void Draw(Graphics g)
|
||||
{
|
||||
g.DrawRectangle(new Pen(FillColor, 1), Rect.X, Rect.Y, Rect.Width, Rect.Height);
|
||||
|
||||
if (IsFilled)
|
||||
{
|
||||
g.FillRectangle(new SolidBrush(Color.FromArgb(20, FillColor)), Rect);
|
||||
}
|
||||
|
||||
Font font = new Font("Tahoma", FontSize);
|
||||
var txtSize = g.MeasureString(DisplayTxt, font);
|
||||
|
||||
g.DrawString(DisplayTxt, font, new SolidBrush(FillColor), (float)(Rect.X + Rect.Width / 2.0 - txtSize.Width / 2.0), Rect.Y + Rect.Height + 5);
|
||||
}
|
||||
|
||||
public string GetDisplayText()
|
||||
{
|
||||
return $"{ResultState} {DisplayTxt} ({Rect.X},{Rect.Y},{Rect.Width},{Rect.Height})";
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
1547
MainForm.Designer.cs
generated
Normal file
1547
MainForm.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
779
MainForm.cs
Normal file
779
MainForm.cs
Normal file
@ -0,0 +1,779 @@
|
||||
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.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
using GuideGraspSys;
|
||||
using System.IO;
|
||||
using static System.Windows.Forms.VisualStyles.VisualStyleElement;
|
||||
using OpenCvSharp.Extensions;
|
||||
using static System.Windows.Forms.VisualStyles.VisualStyleElement.ProgressBar;
|
||||
using Point = System.Drawing.Point;
|
||||
using System.Data.SQLite;
|
||||
using Google.Protobuf;
|
||||
using System.Drawing.Imaging;
|
||||
//using Microsoft.Data.Sqlite;
|
||||
using HalconDotNet;
|
||||
using System.Diagnostics;
|
||||
using System.Data.SqlClient;
|
||||
using Org.BouncyCastle.Ocsp;
|
||||
using Google.Protobuf.WellKnownTypes;
|
||||
//using System.Diagnostics.Metrics;
|
||||
|
||||
|
||||
namespace WindowsFormsApp1
|
||||
{
|
||||
|
||||
public partial class MainForm : Form
|
||||
{
|
||||
private MGSCameraDriver cam1;//
|
||||
private WriteLog writeLog1;//主界面日志
|
||||
private WriteLog writeLog2;//插入日志
|
||||
string preproduct = "";
|
||||
private int count = 0;//每种型号插入模板计数
|
||||
string Resultpath = "D:\\Lujiayi\\Result";
|
||||
string OKpath= "D:\\Lujiayi\\OKNG\\OK.png";
|
||||
string NGpath = "D:\\Lujiayi\\OKNG\\NG.png";
|
||||
|
||||
|
||||
string LablePath = "";
|
||||
string cam1path = "D:\\Lujiayi\\cam1";
|
||||
string cam2path = "D:\\Lujiayi\\cam2";
|
||||
string cam3path = "D:\\Lujiayi\\cam3";
|
||||
string cam4path = "D:\\Lujiayi\\cam4";
|
||||
private bool isDrawing = false;
|
||||
private Point startPoint;
|
||||
private Rectangle rectangle;
|
||||
SimboObjectDetection simboObjectDetection = new SimboObjectDetection();
|
||||
private readonly List<CameraThread> _cameraThreads;
|
||||
private readonly List<PictureBox> _imageDisplays;
|
||||
Mat originalImage = new Mat();
|
||||
public volatile int AllDsums = 0;
|
||||
public volatile int NGDsums = 0;
|
||||
public volatile int OKDsums = 0;
|
||||
|
||||
private CameraManager cameraManager;
|
||||
public MainForm()
|
||||
{
|
||||
InitializeComponent();
|
||||
writeLog1 = new WriteLog(richTextBox1);
|
||||
writeLog2 = new WriteLog(richTextBox2);
|
||||
cam1 = new MGSCameraDriver();
|
||||
cameraManager = new CameraManager();
|
||||
Control.CheckForIllegalCrossThreadCalls = false;
|
||||
ShowData();
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
private void checkedListBox1_SelectedIndexChanged(object sender, EventArgs e)
|
||||
{
|
||||
|
||||
}
|
||||
// <summary>
|
||||
/// 主窗口
|
||||
/// </summary>
|
||||
private void Form1_Load(object sender, EventArgs e)
|
||||
{
|
||||
x = this.Width;
|
||||
y = this.Height;
|
||||
SetTag(this);
|
||||
string LablePathstr = "D:\\Lujiayi\\Yolov5\\class.txt";
|
||||
string ModelPath = "D:\\Lujiayi\\Yolov5\\best.onnx";
|
||||
if (File.Exists(LablePathstr) && File.Exists(ModelPath))
|
||||
{
|
||||
LablePath = LablePathstr;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageBox.Show("检测" + ModelPath + " " + LablePathstr + "模型有无");
|
||||
return;
|
||||
}
|
||||
//初始化驱动
|
||||
simboObjectDetection.Load(ModelPath, "CPU", "images", 640, 640);
|
||||
|
||||
|
||||
|
||||
}
|
||||
private float x;//定义当前窗体的宽度
|
||||
private float y;//定义当前窗体的高度
|
||||
private void SetTag(Control control)
|
||||
{
|
||||
foreach (Control con in control.Controls)
|
||||
{
|
||||
con.Tag = con.Width + ";" + con.Height + ";" + con.Left + ";" + con.Top + ";" + con.Font.Size;
|
||||
if (con.Controls.Count > 0)
|
||||
{
|
||||
SetTag(con);
|
||||
}
|
||||
}
|
||||
}
|
||||
private void SetControls(float newx, float newy, Control cons)
|
||||
{
|
||||
//遍历窗体中的控件,重新设置控件的值
|
||||
foreach (Control con in cons.Controls)
|
||||
{
|
||||
//获取控件的Tag属性值,并分割后存储字符串数组
|
||||
if (con.Tag != null)
|
||||
{
|
||||
string[] mytag = con.Tag.ToString().Split(new char[] { ';' });
|
||||
//根据窗体缩放的比例确定控件的值
|
||||
con.Width = Convert.ToInt32(System.Convert.ToSingle(mytag[0]) * newx);//宽度
|
||||
con.Height = Convert.ToInt32(System.Convert.ToSingle(mytag[1]) * newy);//高度
|
||||
con.Left = Convert.ToInt32(System.Convert.ToSingle(mytag[2]) * newx);//左边距
|
||||
con.Top = Convert.ToInt32(System.Convert.ToSingle(mytag[3]) * newy);//顶边距
|
||||
Single currentSize = System.Convert.ToSingle(mytag[4]) * newy;//字体大小
|
||||
con.Font = new Font(con.Font.Name, currentSize, con.Font.Style, con.Font.Unit);
|
||||
if (con.Controls.Count > 0)
|
||||
{
|
||||
SetControls(newx, newy, con);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//private void Form1_Resize(object sender, EventArgs e)
|
||||
//{
|
||||
// float newx = (this.Width) / x;
|
||||
// float newy = (this.Height) / y;
|
||||
// SetControls(newx, newy, this);
|
||||
//}
|
||||
// <summary>
|
||||
/// NG图片路径按钮
|
||||
/// </summary>
|
||||
|
||||
|
||||
private void checkBox1_CheckedChanged(object sender, EventArgs e)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private void MainForm_Resize(object sender, EventArgs e)
|
||||
{
|
||||
float newx = (this.Width) / x;
|
||||
float newy = (this.Height) / y;
|
||||
SetControls(newx, newy, this);
|
||||
}
|
||||
|
||||
|
||||
// <summary>
|
||||
/// 拍摄照片按钮
|
||||
/// </summary>
|
||||
private void button5_Click(object sender, EventArgs e)
|
||||
{
|
||||
|
||||
cam1.Snapshot();
|
||||
|
||||
writeLog2.LogAppendMsg("采集图像成功!");
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void OnCameraMatOutPut(DateTime dt, Mat cameraMat)
|
||||
{
|
||||
originalImage = cameraMat;
|
||||
string fitImageFolder = "D:\\Lujiayi\\Module";
|
||||
if (!Directory.Exists(fitImageFolder))
|
||||
{
|
||||
Directory.CreateDirectory(fitImageFolder);
|
||||
}
|
||||
// string nameCam = fitImageFolder + dt.Year.ToString() + dt.Month.ToString() + dt.Day.ToString() + dt.Hour.ToString() + dt.Minute.ToString() + dt.Millisecond.ToString() + "1.jpg";
|
||||
|
||||
//string nameCam = fitImageFolder + "111.jpg";
|
||||
//cameraMat.ImWrite(nameCam);
|
||||
userControl11._mat = cameraMat;
|
||||
}
|
||||
|
||||
// <summary>
|
||||
/// 启动相机(插入)
|
||||
/// </summary>
|
||||
private void button6_Click(object sender, EventArgs e)
|
||||
{
|
||||
cam1.Start("Cam2");
|
||||
if (cam1.IfSuccess)
|
||||
{
|
||||
writeLog2.LogAppendMsg("相机1启动成功!");
|
||||
}
|
||||
else { writeLog2.LogAppendMsg("相机1启动失败!"); }
|
||||
|
||||
cam1.OnHImageOutput -= OnCameraMatOutPut;
|
||||
cam1.OnHImageOutput += OnCameraMatOutPut;
|
||||
|
||||
}
|
||||
|
||||
// <summary>
|
||||
/// 窗体关闭事件
|
||||
/// </summary>
|
||||
private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
|
||||
{
|
||||
DialogResult result = MessageBox.Show("你确定要关闭吗!", "提示信息", MessageBoxButtons.OKCancel, MessageBoxIcon.Information);
|
||||
if (result == DialogResult.OK)
|
||||
{
|
||||
cam1.Stop();
|
||||
e.Cancel = false; //点击OK
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
e.Cancel = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void label11_Click(object sender, EventArgs e)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
// <summary>
|
||||
/// 保存模板
|
||||
/// </summary>
|
||||
private void button4_Click(object sender, EventArgs e)
|
||||
{
|
||||
string folderName = textBox7.Text;
|
||||
|
||||
// 构建完整的路径
|
||||
string basePath = @"D:\Lujiayi\Module";
|
||||
string fullPath = Path.Combine(basePath, folderName);
|
||||
try
|
||||
{
|
||||
LuJiaYi xkword = new LuJiaYi
|
||||
{
|
||||
Product = textBox7.Text,
|
||||
Num = int.TryParse(textBox9.Text, out int num) ? num : 0, // 转换文本框中的文本为整数
|
||||
Distance = double.TryParse(textBox8.Text, out double distance) ? distance : 0.0, // 转换文本框中的文本为浮点数
|
||||
Load = fullPath
|
||||
};
|
||||
// 设置 Hole 属性
|
||||
if (checkBox1.CheckState == CheckState.Checked)
|
||||
{
|
||||
xkword.Hole = 0;
|
||||
}
|
||||
else if (checkBox1.CheckState == CheckState.Unchecked)
|
||||
{
|
||||
xkword.Hole = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
xkword.Hole = 1;
|
||||
}
|
||||
|
||||
// 检查文件夹是否存在
|
||||
if (!Directory.Exists(fullPath))
|
||||
{
|
||||
try
|
||||
{
|
||||
// 如果文件夹不存在,则创建它
|
||||
Directory.CreateDirectory(fullPath);
|
||||
writeLog2.LogAppendMsg($"文件夹 {fullPath} 已创建。");
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// 捕获并显示异常
|
||||
writeLog2.LogAppendMsg("创建文件夹错误!");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
string Product = xkword.Product; // 从 xkword 获取 Product
|
||||
|
||||
|
||||
if (!string.IsNullOrEmpty(Product) && num != 0 && distance != 0.0)
|
||||
{
|
||||
|
||||
if (Product == preproduct)
|
||||
{
|
||||
count++;
|
||||
}
|
||||
else
|
||||
{
|
||||
count = 1;
|
||||
preproduct = Product;
|
||||
InsertData(xkword);
|
||||
}
|
||||
int count2 = CountPhotos(fullPath);
|
||||
SaveCroppedImage(fullPath, count2); // 在绘制完成后保存裁剪区域
|
||||
textBox10.Text=count.ToString();
|
||||
writeLog2.LogAppendMsg("模板已保存至数据库!");
|
||||
ShowData();
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageBox.Show("插入的数据不能为NULL");
|
||||
}
|
||||
|
||||
}
|
||||
catch (Exception es)
|
||||
{
|
||||
MessageBox.Show(es.Message);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void userControl11_MouseDown(object sender, MouseEventArgs e)
|
||||
{
|
||||
if (e.Button == MouseButtons.Left)
|
||||
{
|
||||
if (isDrawing)
|
||||
{
|
||||
// 完成绘制矩形框
|
||||
isDrawing = false;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
// 开始绘制矩形框
|
||||
isDrawing = true;
|
||||
startPoint = e.Location;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void userControl11_MouseMove(object sender, MouseEventArgs e)
|
||||
{
|
||||
if (isDrawing)
|
||||
{
|
||||
// 更新矩形框的大小
|
||||
int width = e.X - startPoint.X;
|
||||
int height = e.Y - startPoint.Y;
|
||||
rectangle = new Rectangle(startPoint.X, startPoint.Y, width, height);
|
||||
userControl11.Invalidate(); // 刷新控件以显示矩形框
|
||||
}
|
||||
}
|
||||
|
||||
private void userControl11_Paint(object sender, PaintEventArgs e)
|
||||
{
|
||||
if (rectangle != null && rectangle.Width > 0 && rectangle.Height > 0)
|
||||
{
|
||||
// 绘制矩形框
|
||||
using (Pen pen = new Pen(Color.Red, 2))
|
||||
{
|
||||
e.Graphics.DrawRectangle(pen, rectangle);
|
||||
}
|
||||
}
|
||||
}
|
||||
private Bitmap MatToBitmap(Mat mat)
|
||||
{
|
||||
// 将 Mat 转换为 Bitmap
|
||||
using (var stream = new MemoryStream(mat.ToBytes()))
|
||||
{
|
||||
return new Bitmap(stream);
|
||||
}
|
||||
}
|
||||
private void SaveCroppedImage(string savePath, int count)
|
||||
{
|
||||
if (originalImage.Empty() || rectangle.Width <= 0 || rectangle.Height <= 0)
|
||||
{
|
||||
MessageBox.Show("原始图像为空或矩形框无效");
|
||||
return;
|
||||
}
|
||||
|
||||
// 将原始 Mat 图像转换为 Bitmap
|
||||
Bitmap bitmap = MatToBitmap(originalImage);
|
||||
|
||||
// 确保矩形框在原始图像的范围内
|
||||
Rectangle cropRect = new Rectangle(
|
||||
(int)(rectangle.X * originalImage.Width / userControl11.Width),
|
||||
(int)(rectangle.Y * originalImage.Height / userControl11.Height),
|
||||
(int)(rectangle.Width * originalImage.Width / userControl11.Width),
|
||||
(int)(rectangle.Height * originalImage.Height / userControl11.Height)
|
||||
);
|
||||
|
||||
// 确保裁剪矩形在原始图像范围内
|
||||
cropRect.Intersect(new Rectangle(0, 0, bitmap.Width, bitmap.Height));
|
||||
|
||||
if (cropRect.Width > 0 && cropRect.Height > 0)
|
||||
{
|
||||
using (Bitmap croppedImage = new Bitmap(cropRect.Width, cropRect.Height))
|
||||
{
|
||||
using (Graphics g = Graphics.FromImage(croppedImage))
|
||||
{
|
||||
g.DrawImage(bitmap, new Rectangle(0, 0, croppedImage.Width, croppedImage.Height),
|
||||
cropRect, GraphicsUnit.Pixel);
|
||||
}
|
||||
|
||||
// 确保保存路径存在
|
||||
if (!Directory.Exists(savePath))
|
||||
{
|
||||
try
|
||||
{
|
||||
Directory.CreateDirectory(savePath);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBox.Show($"创建文件夹时发生错误: {ex.Message}");
|
||||
return;
|
||||
}
|
||||
}
|
||||
int num = count + 1;
|
||||
// 构建文件名和保存路径
|
||||
string fileName = $"{num}.png";
|
||||
string filePath = Path.Combine(savePath, fileName);
|
||||
|
||||
try
|
||||
{
|
||||
croppedImage.Save(filePath, ImageFormat.Png);
|
||||
writeLog2.LogAppendMsg($"裁剪区域已保存到 {filePath}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBox.Show($"保存图像时发生错误: {ex.Message}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void groupBox7_Enter(object sender, EventArgs e)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
|
||||
{
|
||||
|
||||
}
|
||||
public static int CountPhotos(string folderPath)
|
||||
{
|
||||
// 图片文件扩展名列表
|
||||
string[] imageExtensions = { ".jpg", ".jpeg", ".png", ".bmp", ".gif" };
|
||||
|
||||
// 获取所有图片文件
|
||||
var photoFiles = Directory.GetFiles(folderPath)
|
||||
.Where(file => imageExtensions.Contains(Path.GetExtension(file).ToLower()))
|
||||
.ToArray();
|
||||
|
||||
return photoFiles.Length;
|
||||
}
|
||||
private bool IsProductExists(string product)//用于型号是否已经插入到数据库中,避免数据重复插入导致信息更改
|
||||
{
|
||||
string query = "SELECT COUNT(*) FROM LuJiaYi WHERE Product = @Product";
|
||||
string connectionString = "Data Source = D:\\Lujiayi\\DataBase\\JianZhenQi1.db;BinaryGUID=False;";
|
||||
using (var connection = new SQLiteConnection(connectionString))
|
||||
{
|
||||
connection.Open();
|
||||
using (var command = new SQLiteCommand(query, connection))
|
||||
{
|
||||
command.Parameters.AddWithValue("@Product", product);
|
||||
|
||||
int count = Convert.ToInt32(command.ExecuteScalar());
|
||||
return count > 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
public void InsertData(LuJiaYi xkWord)//插入模板数据到数据库中
|
||||
{
|
||||
if (IsProductExists(xkWord.Product))
|
||||
{
|
||||
writeLog2.LogAppendMsg("产品型号已在数据库中,请勿重复插入!");
|
||||
return;
|
||||
}
|
||||
|
||||
StringBuilder strSql = new StringBuilder();
|
||||
strSql.Append("insert into LuJiaYi(");
|
||||
strSql.Append("Product,Num,Distance,Hole,Load)");
|
||||
strSql.Append(" values (");
|
||||
strSql.Append("@Product,@Num,@Distance,@Hole,@Load)");
|
||||
SQLiteParameter[] parameters = {
|
||||
new SQLiteParameter("@Product", DbType.String),
|
||||
new SQLiteParameter("@Num", DbType.String),
|
||||
new SQLiteParameter("@Distance", DbType.String),
|
||||
new SQLiteParameter("@Hole", DbType.String),
|
||||
new SQLiteParameter("@Load",DbType.String) };
|
||||
|
||||
|
||||
parameters[0].Value = xkWord.Product;
|
||||
parameters[1].Value = xkWord.Num;
|
||||
parameters[2].Value = xkWord.Distance;
|
||||
parameters[3].Value = xkWord.Hole;
|
||||
parameters[4].Value = xkWord.Load;
|
||||
|
||||
int iv = SQLiteHelper.ExecuteSql(strSql.ToString(), parameters);
|
||||
if (iv == 1)
|
||||
{
|
||||
writeLog2.LogAppendMsg($"型号:{xkWord.Product}的相关信息已插入!");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void ShowData()//展示数据库结果
|
||||
{
|
||||
string query = "SELECT * FROM LuJiaYi";
|
||||
DataSet ds = SQLiteHelper.Query(query);
|
||||
|
||||
if (ds.Tables.Count == 0)
|
||||
{
|
||||
writeLog2.LogAppendMsg("没有找到相关数据!");
|
||||
return;
|
||||
}
|
||||
|
||||
// 获取DataTable
|
||||
DataTable dt = ds.Tables[0];
|
||||
|
||||
// 创建列名映射表(示例映射)
|
||||
Dictionary<string, string> columnMappings = new Dictionary<string, string>
|
||||
{
|
||||
{ "Product", "产品号" },
|
||||
{ "Num", "金属圈数量" },
|
||||
{ "Distance", "距离" },
|
||||
{ "Hole", "孔" },
|
||||
{ "Load", "路径" }
|
||||
};
|
||||
|
||||
// 遍历DataTable的列并修改列名
|
||||
foreach (DataColumn column in dt.Columns)
|
||||
{
|
||||
if (columnMappings.TryGetValue(column.ColumnName, out string newName))
|
||||
{
|
||||
column.ColumnName = newName;
|
||||
}
|
||||
}
|
||||
|
||||
// 绑定DataTable到DataGridView
|
||||
dataGridView1.DataSource = dt;
|
||||
dataGridView1.DefaultCellStyle.WrapMode = DataGridViewTriState.False;
|
||||
dataGridView1.ColumnHeadersDefaultCellStyle.WrapMode = DataGridViewTriState.False;//列名不换行
|
||||
dataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells;
|
||||
dataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;//自适应填充
|
||||
foreach (DataGridViewColumn column in dataGridView1.Columns)
|
||||
{
|
||||
column.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;//列内容居中
|
||||
}
|
||||
dataGridView1.ColumnHeadersDefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;//列名居中
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
private void tabPage2_Click(object sender, EventArgs e)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private void label6_Click(object sender, EventArgs e)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private void groupBox5_Enter(object sender, EventArgs e)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private void button1_Click_1(object sender, EventArgs e)
|
||||
{
|
||||
cameraManager.StartAllCameras();
|
||||
SQLiteHelper.DataToComboBox(comboBox1, "LuJiaYi","Product");//数据库型号信息传入选框中
|
||||
SQLiteHelper.DataToComboBox(comboBox2, "LuJiaYi", "Product");
|
||||
|
||||
}
|
||||
|
||||
private void button2_Click_1(object sender, EventArgs e)
|
||||
{
|
||||
|
||||
textBox4.Text = comboBox1.SelectedItem.ToString();//产线1型号
|
||||
textBox15.Text = comboBox1.SelectedItem.ToString();//产线2型号
|
||||
textBox19.Text = comboBox2.SelectedItem.ToString();//产线3型号
|
||||
textBox23.Text = comboBox2.SelectedItem.ToString();//产线4型号
|
||||
|
||||
cameraManager.takepic1();
|
||||
cameraManager.takepic2();
|
||||
cameraManager.takepic3();
|
||||
cameraManager.takepic4();
|
||||
|
||||
}
|
||||
|
||||
public void TriggerCam()//触发相机拍照
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public void AddRect(string ImgPath, string templatePath,PictureBox pictureBox1, PictureBox pictureBox2,System.Windows.Forms.TextBox textBox, System.Windows.Forms.TextBox Num, System.Windows.Forms.TextBox Hole, System.Windows.Forms.TextBox Distance)
|
||||
{
|
||||
string Type = textBox.Text;
|
||||
MLRequest req = new MLRequest();
|
||||
req.ResizeWidth = 640;
|
||||
req.ResizeHeight = 640;
|
||||
req.Score = 0.3f;
|
||||
req.in_lable_path = LablePath;//标签路径
|
||||
req.confThreshold = 0.3f;//模型置信度
|
||||
req.iouThreshold = 0.4f;//检测IOU
|
||||
req.out_node_name = "output0";
|
||||
int countPhotos = CountPhotos(templatePath);
|
||||
string SavePath = $"{templatePath}\\Result";
|
||||
SaveCroppedImage(SavePath, countPhotos);
|
||||
|
||||
string ResPath = $"{SavePath}\\{countPhotos}.jpg";
|
||||
req.currentMat = Cv2.ImRead(ImgPath);
|
||||
MLResult mL = simboObjectDetection.RunInferenceFixed(req);
|
||||
Rect rect = ProcessImg.ProcessImagesInFolder(templatePath, ImgPath, SavePath, ResPath);
|
||||
|
||||
string JsonStr = mL.JsonString;
|
||||
|
||||
Bitmap ResPic = new Bitmap(ResPath);
|
||||
Bitmap OKPic = new Bitmap(OKpath);
|
||||
Bitmap NGPic = new Bitmap(NGpath);
|
||||
if (mL.ResultMap != null)
|
||||
{
|
||||
mL.ResultMap.Save(ResPath);
|
||||
pictureBox1.Image = ResPic;
|
||||
writeLog1.LogAppendMsg("模型运行成功!");
|
||||
bool IsNot= ResultOut(rect, JsonStr,Type,Num,Hole,Distance);//结果
|
||||
if (IsNot == true)
|
||||
{
|
||||
pictureBox2.Image = OKPic;
|
||||
}
|
||||
else
|
||||
{
|
||||
pictureBox2.Image = NGPic;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
writeLog1.LogAppendMsg("模板或相机照片不存在!");
|
||||
}
|
||||
}
|
||||
public bool ResultOut(Rect rect, string JsonStr,string Type, System.Windows.Forms.TextBox Num,System.Windows.Forms.TextBox Hole,System.Windows.Forms.TextBox Distance)
|
||||
{
|
||||
|
||||
int MetalCount = SimboObjectDetection.LableCount(JsonStr, "Metal");//金属圈个数
|
||||
int SQLMetal = SQLiteHelper.GetNum("LuJiaYi", "Product", Type, "Num");//数据库金属圈个数
|
||||
Num.Text = MetalCount.ToString();
|
||||
|
||||
int ScrewholeCount = SimboObjectDetection.LableCount(JsonStr, "Screwhole");//螺丝孔个数
|
||||
int SQLScrewhole = SQLiteHelper.GetNum("LuJiaYi", "Product", Type, "Hole");//数据库螺丝孔个数
|
||||
Hole.Text = ScrewholeCount.ToString();
|
||||
|
||||
|
||||
|
||||
|
||||
double DistanceCount = 0;
|
||||
Distance.Text = DistanceCount.ToString();
|
||||
double SQLDistance= SQLiteHelper.GetNum("LuJiaYi", "Product", Type, "Distance");//数据库距离
|
||||
|
||||
Rect DenseRect = SimboObjectDetection.RectMes(JsonStr, "Dense");
|
||||
int Dense_Top = DenseRect.Y;
|
||||
int Dense_Bottom=DenseRect.Y+DenseRect.Height;
|
||||
int Template_Top=rect.Y;
|
||||
int Template_Bottom=rect.Y+rect.Height;
|
||||
|
||||
// if dense_point_top_y < template_point_top_y:
|
||||
// if template_point_top_y - dense_point_bottom_y > 100:
|
||||
// cv2.putText(result_img, 'Shock absorbers:NG', (10, 100), font, 1, (0, 0, 255), 5, cv2.LINE_AA)
|
||||
// else:
|
||||
// cv2.putText(result_img, 'Shock absorbers:OK', (10, 100), font, 1, (0, 255, 0), 5, cv2.LINE_AA)
|
||||
//elif dense_point_top_y > template_point_top_y:
|
||||
// if dense_point_top_y - template_point_bottom_y > 100:
|
||||
// cv2.putText(result_img, 'Shock absorbers:NG', (10, 100), font, 1, (0, 0, 255), 5, cv2.LINE_AA)
|
||||
// else:
|
||||
// cv2.putText(result_img, 'Shock absorbers:OK', (10, 100), font, 1, (0, 255, 0), 5, cv2.LINE_AA)
|
||||
|
||||
if (MetalCount== SQLMetal&& ScrewholeCount== SQLScrewhole&& DistanceCount==SQLDistance)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
public void AddRectTest( )//YOLO标框测试
|
||||
{
|
||||
string imagePath = "D:\\Lujiayi\\Yolov5\\test.jpg";
|
||||
|
||||
// 图像文件夹路径
|
||||
string templatePath = "D:\\Lujiayi\\Yolov5\\test";
|
||||
|
||||
// 结果图像输出文件夹路径
|
||||
string outputFolderPath = @"D:\Lujiayi\Yolov5";
|
||||
string respic = "D:\\Lujiayi\\Cam1\\1.jpg";//框后结果
|
||||
|
||||
MLRequest req =new MLRequest();
|
||||
req.ResizeWidth = 640;
|
||||
req.ResizeHeight = 640;
|
||||
req.Score = 0.3f;
|
||||
req.in_lable_path = LablePath;//标签路径
|
||||
req.confThreshold = 0.3f;//模型置信度
|
||||
req.iouThreshold = 0.4f;//检测IOU
|
||||
req.out_node_name = "output0";
|
||||
|
||||
req.currentMat = Cv2.ImRead(imagePath);
|
||||
DateTime dt = DateTime.Now;
|
||||
Stopwatch sw = new Stopwatch();
|
||||
sw.Start();
|
||||
MLResult mL = simboObjectDetection.RunInferenceFixed(req);//将模型训练后的框标出
|
||||
|
||||
//Rect rect = ProcessImg.ProcessImagesInFolder(templatePath, imagePath, outputFolderPath, respic);
|
||||
|
||||
sw.Stop();
|
||||
|
||||
//if (mL.ResultMap != null)
|
||||
//{
|
||||
|
||||
// mL.ResultMap.Save(respic);
|
||||
// pictureBox1.Image = mL.ResultMap;
|
||||
// int MetalCount = SimboObjectDetection.LableCount(mL.JsonString, "Metal");//金属圈个数
|
||||
// string Type1=textBox4.Text;
|
||||
// int SQLMetal = SQLiteHelper.GetNum("LuJiaYi","Product", Type1, "Num");
|
||||
// textBox5.Text = MetalCount.ToString();
|
||||
// int ScrewholeCount = SimboObjectDetection.LableCount(mL.JsonString, "Screwhole");//螺丝孔个数
|
||||
// textBox11.Text = ScrewholeCount.ToString();
|
||||
// string numberAsString = SQLMetal.ToString();
|
||||
// writeLog1.LogMessage(numberAsString);
|
||||
// writeLog1.LogAppendMsg("模板匹配标识成功!" + sw.ElapsedMilliseconds);
|
||||
|
||||
//}
|
||||
//else if (mL.ResultMap == null)//如果标框失败,结果返回原图
|
||||
//{
|
||||
// Mat res_yolo = Cv2.ImRead(NGpath);
|
||||
|
||||
// pictureBox1.Image = res_yolo.ToBitmap();
|
||||
// writeLog1.LogAppendMsg("无法定位矩形框,图像为原图!");
|
||||
|
||||
//}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
private void groupBox4_Enter(object sender, EventArgs e)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private void button3_Click(object sender, EventArgs e)
|
||||
{
|
||||
textBox4.Text = comboBox1.SelectedItem.ToString();//产线1型号
|
||||
textBox15.Text = comboBox1.SelectedItem.ToString();//产线2型号
|
||||
textBox19.Text = comboBox2.SelectedItem.ToString();//产线3型号
|
||||
textBox23.Text = comboBox2.SelectedItem.ToString();//产线4型号
|
||||
}
|
||||
}
|
||||
}
|
120
MainForm.resx
Normal file
120
MainForm.resx
Normal 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>
|
54
PLCItem.cs
Normal file
54
PLCItem.cs
Normal file
@ -0,0 +1,54 @@
|
||||
|
||||
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;
|
||||
|
||||
|
||||
}
|
||||
|
358
PlcContorl.cs
Normal file
358
PlcContorl.cs
Normal 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)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
133
Process_Img.cs
Normal file
133
Process_Img.cs
Normal file
@ -0,0 +1,133 @@
|
||||
using OpenCvSharp;
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Drawing.Imaging;
|
||||
using OpenCvSharp.Extensions;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Threading.Tasks;
|
||||
using WindowsFormsApp1;
|
||||
using System.Diagnostics;
|
||||
using System.Threading;
|
||||
|
||||
public class ProcessImg
|
||||
{
|
||||
// 对单个图像进行模板匹配
|
||||
|
||||
public static (double score, Rect? coords) MatchTemplate(string imgPath, string templatePath)
|
||||
{
|
||||
// 确保图像和模板文件存在
|
||||
|
||||
|
||||
// 读取图像和模板
|
||||
var img = Cv2.ImRead(imgPath, ImreadModes.Color);
|
||||
var template = Cv2.ImRead(templatePath, ImreadModes.Color);
|
||||
|
||||
// 创建一个模板匹配的结果矩阵
|
||||
var result = new Mat();
|
||||
Cv2.MatchTemplate(img, template, result, TemplateMatchModes.CCoeffNormed);
|
||||
|
||||
// 查找最大匹配值
|
||||
Cv2.MinMaxLoc(result, out _, out var maxVal, out _, out var maxLoc);
|
||||
|
||||
// 如果找到的最大匹配值大于阈值
|
||||
double threshold = 0.4; // 可以根据需要调整阈值
|
||||
if (maxVal >= threshold)
|
||||
{
|
||||
// 计算匹配的坐标
|
||||
var topLeft = maxLoc;
|
||||
var rect = new Rect(topLeft.X, topLeft.Y, template.Width, template.Height);
|
||||
|
||||
return (maxVal, rect);
|
||||
}
|
||||
|
||||
return (0, null);
|
||||
}
|
||||
|
||||
// 遍历文件夹中的所有图像文件进行模板匹配,并找到最佳得分图像
|
||||
public static Rect ProcessImagesInFolder(string folderPath, string actPath, string outputFolderPath, string resImgPath)
|
||||
{
|
||||
// 获取所有图像文件
|
||||
var imageFiles = Directory.GetFiles(folderPath, "*.*", SearchOption.TopDirectoryOnly)
|
||||
.Where(file => file.EndsWith(".jpg", StringComparison.OrdinalIgnoreCase) ||
|
||||
file.EndsWith(".png", StringComparison.OrdinalIgnoreCase) ||
|
||||
file.EndsWith(".jpeg", StringComparison.OrdinalIgnoreCase))
|
||||
.ToList();
|
||||
|
||||
|
||||
|
||||
// 确保输出文件夹存在
|
||||
Directory.CreateDirectory(outputFolderPath);
|
||||
|
||||
// 计算线程数量(文件数量的一半)
|
||||
int numThreads = Math.Max(1, imageFiles.Count);
|
||||
|
||||
// 用于存储每个图像的得分和坐标
|
||||
var bestMatch = new ConcurrentBag<(string imagePath, double score, Rect? coords)>();
|
||||
DateTime startTime = DateTime.Now;
|
||||
Stopwatch sw = new Stopwatch();
|
||||
sw.Start();
|
||||
|
||||
Parallel.ForEach(imageFiles, new ParallelOptions { MaxDegreeOfParallelism = numThreads }, picPath =>
|
||||
{
|
||||
DateTime threadStartTime = DateTime.Now;
|
||||
|
||||
var (score, coords) = MatchTemplate(actPath, picPath);
|
||||
|
||||
if (score > 0.4)
|
||||
{
|
||||
bestMatch.Add((picPath, score, coords));
|
||||
}
|
||||
|
||||
DateTime threadEndTime = DateTime.Now;
|
||||
TimeSpan threadElapsed = threadEndTime - threadStartTime;
|
||||
Console.WriteLine($"线程处理 {picPath} 耗时: {threadElapsed.TotalMilliseconds}ms");
|
||||
});
|
||||
|
||||
sw.Stop();
|
||||
TimeSpan totalElapsed = sw.Elapsed;
|
||||
Console.WriteLine($"处理完成,耗时: {totalElapsed.TotalSeconds}秒");
|
||||
// 查找最佳得分
|
||||
var best = bestMatch.OrderByDescending(m => m.score).FirstOrDefault();
|
||||
Rect rect = best.coords.Value;
|
||||
if (best.imagePath != null && best.coords.HasValue)
|
||||
{
|
||||
|
||||
// 结果图像的路径
|
||||
string fileName = Path.GetFileNameWithoutExtension(best.imagePath) + "_result.jpg";
|
||||
string outputPath = Path.Combine(outputFolderPath, fileName);
|
||||
|
||||
// 在最佳图像上绘制矩形并保存结果
|
||||
DrawRectangleOnImage(resImgPath, rect, outputPath);
|
||||
|
||||
}
|
||||
return rect;
|
||||
|
||||
}
|
||||
|
||||
// 在图像上绘制矩形并保存结果
|
||||
public static void DrawRectangleOnImage(string imagePath, Rect rect, string outputPath)
|
||||
{
|
||||
using (var mat = Cv2.ImRead(imagePath, ImreadModes.Color))
|
||||
{
|
||||
// 将 Mat 转换为 Bitmap
|
||||
using (var bitmap = BitmapConverter.ToBitmap(mat))
|
||||
{
|
||||
// 创建一个 Bitmap 的副本,以便在其上绘制
|
||||
using (var bitmapCopy = new Bitmap(bitmap))
|
||||
using (var graphics = Graphics.FromImage(bitmapCopy))
|
||||
{
|
||||
// 创建一个红色边框,宽度为 2 像素
|
||||
var pen = new Pen(Color.Red, 2);
|
||||
|
||||
// 绘制矩形
|
||||
graphics.DrawRectangle(pen, rect.X, rect.Y, rect.Width, rect.Height);
|
||||
|
||||
// 保存结果图像
|
||||
bitmapCopy.Save(outputPath, ImageFormat.Jpeg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
22
Program.cs
Normal file
22
Program.cs
Normal file
@ -0,0 +1,22 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace WindowsFormsApp1
|
||||
{
|
||||
internal static class Program
|
||||
{
|
||||
/// <summary>
|
||||
/// 应用程序的主入口点。
|
||||
/// </summary>
|
||||
[STAThread]
|
||||
static void Main()
|
||||
{
|
||||
Application.EnableVisualStyles();
|
||||
Application.SetCompatibleTextRenderingDefault(false);
|
||||
Application.Run(new MainForm());
|
||||
}
|
||||
}
|
||||
}
|
36
Properties/AssemblyInfo.cs
Normal file
36
Properties/AssemblyInfo.cs
Normal file
@ -0,0 +1,36 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// 有关程序集的一般信息由以下
|
||||
// 控制。更改这些特性值可修改
|
||||
// 与程序集关联的信息。
|
||||
[assembly: AssemblyTitle("WindowsFormsApp1")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("WindowsFormsApp1")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2024")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// 将 ComVisible 设置为 false 会使此程序集中的类型
|
||||
//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型
|
||||
//请将此类型的 ComVisible 特性设置为 true。
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
|
||||
[assembly: Guid("b79451bb-0b27-4b9e-9dfe-2ed254d26903")]
|
||||
|
||||
// 程序集的版本信息由下列四个值组成:
|
||||
//
|
||||
// 主版本
|
||||
// 次版本
|
||||
// 生成号
|
||||
// 修订号
|
||||
//
|
||||
//可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值
|
||||
//通过使用 "*",如下所示:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
71
Properties/Resources.Designer.cs
generated
Normal file
71
Properties/Resources.Designer.cs
generated
Normal file
@ -0,0 +1,71 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// 此代码由工具生成。
|
||||
// 运行时版本: 4.0.30319.42000
|
||||
//
|
||||
// 对此文件的更改可能导致不正确的行为,如果
|
||||
// 重新生成代码,则所做更改将丢失。
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace WindowsFormsApp1.Properties
|
||||
{
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 强类型资源类,用于查找本地化字符串等。
|
||||
/// </summary>
|
||||
// 此类是由 StronglyTypedResourceBuilder
|
||||
// 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。
|
||||
// 若要添加或移除成员,请编辑 .ResX 文件,然后重新运行 ResGen
|
||||
// (以 /str 作为命令选项),或重新生成 VS 项目。
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.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 ((resourceMan == null))
|
||||
{
|
||||
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("WindowsFormsApp1.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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
117
Properties/Resources.resx
Normal file
117
Properties/Resources.resx
Normal file
@ -0,0 +1,117 @@
|
||||
<?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.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: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" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
</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" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
</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=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
30
Properties/Settings.Designer.cs
generated
Normal file
30
Properties/Settings.Designer.cs
generated
Normal file
@ -0,0 +1,30 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:4.0.30319.42000
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace WindowsFormsApp1.Properties
|
||||
{
|
||||
|
||||
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")]
|
||||
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase
|
||||
{
|
||||
|
||||
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
|
||||
|
||||
public static Settings Default
|
||||
{
|
||||
get
|
||||
{
|
||||
return defaultInstance;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
7
Properties/Settings.settings
Normal file
7
Properties/Settings.settings
Normal file
@ -0,0 +1,7 @@
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)">
|
||||
<Profiles>
|
||||
<Profile Name="(Default)" />
|
||||
</Profiles>
|
||||
<Settings />
|
||||
</SettingsFile>
|
720
SQLConnect.cs
Normal file
720
SQLConnect.cs
Normal file
@ -0,0 +1,720 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Specialized;
|
||||
using System.Data;
|
||||
using System.Data.SQLite;
|
||||
using System.Configuration;
|
||||
using System.Data.SqlClient;
|
||||
using System.Data.SqlTypes;
|
||||
using System.Collections.Generic;
|
||||
using System.Windows.Forms;
|
||||
|
||||
|
||||
public class SQLiteHelper
|
||||
{
|
||||
//数据库连接字符串
|
||||
// public static string connectionString = ConfigurationManager.ConnectionStrings["ProcessDB"].ConnectionString;
|
||||
public static string connectionString = "Data Source = D:\\Lujiayi\\DataBase\\JianZhenQi1.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 List<T> ExecuteQuery<T>(string SQLString, Func<IDataRecord, T> selector, params SQLiteParameter[] parameters)
|
||||
{
|
||||
using (SQLiteConnection connection = new SQLiteConnection(connectionString))
|
||||
{
|
||||
using (SQLiteCommand cmd = new SQLiteCommand(SQLString, connection))
|
||||
{
|
||||
// 添加参数
|
||||
cmd.Parameters.AddRange(parameters);
|
||||
// 打开连接
|
||||
connection.Open();
|
||||
// 创建DataReader对象并读取数据,将每行数据映射到对象并添加到列表中
|
||||
using (SQLiteDataReader reader = cmd.ExecuteReader())
|
||||
{
|
||||
List<T> list = new List<T>();
|
||||
while (reader.Read())
|
||||
{
|
||||
list.Add(selector(reader));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
public static List<string> GetColumnData(string tableName, string columnName)
|
||||
{
|
||||
List<string> dataList = new List<string>();
|
||||
string query = $"SELECT DISTINCT {columnName} FROM {tableName}";
|
||||
|
||||
using (SQLiteConnection connection = new SQLiteConnection(connectionString))
|
||||
{
|
||||
using (SQLiteCommand command = new SQLiteCommand(query, connection))
|
||||
{
|
||||
try
|
||||
{
|
||||
connection.Open();
|
||||
using (SQLiteDataReader reader = command.ExecuteReader())
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
if (!reader.IsDBNull(0))
|
||||
{
|
||||
dataList.Add(reader.GetString(0));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBox.Show("Error: " + ex.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return dataList;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 绑定列数据到ComboBox
|
||||
/// </summary>
|
||||
/// <param name="comboBox">ComboBox控件</param>
|
||||
/// <param name="tableName">表名</param>
|
||||
/// <param name="columnName">列名</param>
|
||||
public static void DataToComboBox(ComboBox comboBox, string tableName, string columnName)
|
||||
{
|
||||
List<string> dataList = GetColumnData(tableName, columnName);
|
||||
comboBox.Items.Clear();
|
||||
comboBox.Items.AddRange(dataList.ToArray());
|
||||
}
|
||||
|
||||
|
||||
public static int GetNum(string tableName, string filterColumn, string filterValue, string resultColumn)
|
||||
{
|
||||
int resultValue = 0;
|
||||
|
||||
// 构造 SQL 查询
|
||||
string query = $"SELECT {resultColumn} FROM {tableName} WHERE {filterColumn} = @filterValue";
|
||||
|
||||
// 创建 SQL 连接
|
||||
using (SQLiteConnection connection = new SQLiteConnection(connectionString))
|
||||
{
|
||||
// 创建 SQL 命令
|
||||
using (SQLiteCommand command = new SQLiteCommand(query, connection))
|
||||
{
|
||||
// 添加参数
|
||||
command.Parameters.AddWithValue("@filterValue", filterValue);
|
||||
|
||||
// 打开连接
|
||||
connection.Open();
|
||||
|
||||
// 执行查询并获取单个值
|
||||
object result = command.ExecuteScalar();
|
||||
|
||||
// 确保结果不为 null 并转换为 int
|
||||
if (result != null && int.TryParse(result.ToString(), out int parsedValue))
|
||||
{
|
||||
resultValue = parsedValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return resultValue;
|
||||
}
|
||||
#endregion
|
||||
}
|
304
SimboObjectDetection.cs
Normal file
304
SimboObjectDetection.cs
Normal file
@ -0,0 +1,304 @@
|
||||
|
||||
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
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
public static int LableCount(string json, string targetLabel)//出现的标签数
|
||||
{
|
||||
// 解析 JSON 结果
|
||||
SegResult detResult = JsonConvert.DeserializeObject<SegResult>(json);
|
||||
if (detResult == null)
|
||||
{
|
||||
throw new ArgumentException("Invalid JSON format.");
|
||||
}
|
||||
|
||||
// 统计目标标签的数量
|
||||
int labelCount = detResult.SegmentResult
|
||||
.Count(det => det.classname.Equals(targetLabel, StringComparison.OrdinalIgnoreCase));
|
||||
|
||||
return labelCount;
|
||||
}
|
||||
|
||||
public static Rect RectMes(string json, string targetLabel)
|
||||
{
|
||||
SegResult detResult = JsonConvert.DeserializeObject<SegResult>(json);
|
||||
if (detResult == null)
|
||||
{
|
||||
throw new ArgumentException("Invalid JSON format.");
|
||||
}
|
||||
|
||||
// 获取第一个指定标签的框信息
|
||||
var result = detResult.SegmentResult
|
||||
.FirstOrDefault(det => det.classname.Equals(targetLabel, StringComparison.OrdinalIgnoreCase));
|
||||
|
||||
// 如果找到匹配的结果,返回其矩形框;否则返回 null
|
||||
|
||||
|
||||
return new Rect(result.rect[0], result.rect[1], result.rect[2], result.rect[3]);
|
||||
|
||||
}
|
||||
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);
|
||||
|
||||
}
|
||||
result.ResultDetails.Sort((s1, s2) => s1.Rect.X.CompareTo(s2.Rect.X));
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
[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
|
||||
mlResult.JsonString = System.Text.Encoding.Default.GetString(labellist, 0, labellist.Length);
|
||||
|
||||
|
||||
|
||||
|
||||
ConvertJsonResult(mlResult.JsonString, 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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
682
StaticHelper.cs
Normal file
682
StaticHelper.cs
Normal file
@ -0,0 +1,682 @@
|
||||
using Microsoft.CSharp.RuntimeBinder;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using System;
|
||||
|
||||
//using Newtonsoft.Json;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.ComponentModel;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using System.Dynamic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
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;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
public static class StaticHelper
|
||||
{
|
||||
|
||||
//判断是否为正整数
|
||||
public static bool IsInt(string inString)
|
||||
{
|
||||
Regex regex = new Regex("^[0-9]*[1-9][0-9]*$");
|
||||
return regex.IsMatch(inString.Trim());
|
||||
}
|
||||
/// <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)
|
||||
{
|
||||
|
||||
CopyMemory(cloneData.Scan0, sourceData.Scan0, (uint)(sourceData.Stride * sourceData.Height));
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
Parallel.For(0, source.Height, h =>
|
||||
{
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
51
Thread.cs
Normal file
51
Thread.cs
Normal file
@ -0,0 +1,51 @@
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Drawing; // 或者使用其他图像处理库
|
||||
|
||||
public class CameraThread
|
||||
{
|
||||
private readonly int _cameraId;
|
||||
private readonly Action<Bitmap> _onImageCaptured;
|
||||
private Thread _thread;
|
||||
private bool _running;
|
||||
|
||||
public CameraThread(int cameraId, Action<Bitmap> onImageCaptured)
|
||||
{
|
||||
_cameraId = cameraId;
|
||||
_onImageCaptured = onImageCaptured;
|
||||
_running = false;
|
||||
}
|
||||
|
||||
public void Start()
|
||||
{
|
||||
_running = true;
|
||||
_thread = new Thread(Run);
|
||||
_thread.Start();
|
||||
}
|
||||
|
||||
public void Stop()
|
||||
{
|
||||
_running = false;
|
||||
_thread?.Join();
|
||||
}
|
||||
|
||||
private void Run()
|
||||
{
|
||||
while (_running)
|
||||
{
|
||||
// 模拟图像捕获
|
||||
Bitmap image = CaptureImageFromCamera(_cameraId);
|
||||
_onImageCaptured?.Invoke(image);
|
||||
|
||||
// 休眠一段时间,模拟捕获间隔
|
||||
Thread.Sleep(1000);
|
||||
}
|
||||
}
|
||||
|
||||
private Bitmap CaptureImageFromCamera(int cameraId)
|
||||
{
|
||||
// 这里添加实际的图像捕获代码
|
||||
// 例如,从相机 SDK 捕获图像并返回
|
||||
return new Bitmap(640, 480); // 模拟图像
|
||||
}
|
||||
}
|
70
WriteLog.cs
Normal file
70
WriteLog.cs
Normal file
@ -0,0 +1,70 @@
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace WindowsFormsApp1
|
||||
{
|
||||
internal class WriteLog
|
||||
{
|
||||
public delegate void LogAppendDelegate(Color color, string text);
|
||||
private readonly RichTextBox richTextBox1;
|
||||
private readonly LogAppendDelegate logAppendDelegate;
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数传入RichTextBox控件的实例。
|
||||
/// </summary>
|
||||
/// <param name="richTextBox1"></param>
|
||||
public WriteLog(RichTextBox richTextBox1)
|
||||
{
|
||||
this.richTextBox1 = richTextBox1;
|
||||
this.logAppendDelegate = new LogAppendDelegate(LogAppend);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// LogAppendDelegate委托指向的方法
|
||||
/// </summary>
|
||||
/// <param name="color"></param>
|
||||
/// <param name="text"></param>
|
||||
private void LogAppend(Color color, string text)
|
||||
{
|
||||
richTextBox1.SelectionColor = color;
|
||||
richTextBox1.AppendText(text + Environment.NewLine);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 追加显示文本
|
||||
/// </summary>
|
||||
/// <param name="text"></param>
|
||||
public void LogAppendMsg(string text)
|
||||
{
|
||||
richTextBox1.Invoke(logAppendDelegate, Color.Black, DateTime.Now.ToString("yyyy.MM.dd HH:mm:ss") + " " + text);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 显示错误日志
|
||||
/// </summary>
|
||||
/// <param name="text"></param>
|
||||
public void LogError(string text)
|
||||
{
|
||||
richTextBox1.Invoke(logAppendDelegate, Color.Red, DateTime.Now.ToString("yyyy.MM.dd HH:mm:ss") + " " + text);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 显示警告信息
|
||||
/// </summary>
|
||||
/// <param name="text"></param>
|
||||
public void LogWarning(string text)
|
||||
{
|
||||
richTextBox1.Invoke(logAppendDelegate, Color.Violet, DateTime.Now.ToString("yyyy.MM.dd HH:mm:ss") + " " + text);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 显示信息
|
||||
/// </summary>
|
||||
/// <param name="text"></param>
|
||||
public void LogMessage(string text)
|
||||
{
|
||||
richTextBox1.Invoke(logAppendDelegate, Color.Black, DateTime.Now.ToString("yyyy.MM.dd HH:mm:ss") + " " + text);
|
||||
}
|
||||
}
|
||||
}
|
48
packages.config
Normal file
48
packages.config
Normal file
@ -0,0 +1,48 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="BouncyCastle.Cryptography" version="2.4.0" targetFramework="net472" />
|
||||
<package id="Emgu.CV" version="4.7.0.5276" targetFramework="net472" />
|
||||
<package id="EntityFramework" version="6.4.4" targetFramework="net472" />
|
||||
<package id="Google.Protobuf" version="3.21.9" targetFramework="net472" />
|
||||
<package id="HalconDotNet" version="19.11.0" targetFramework="net472" />
|
||||
<package id="HslCommunication" version="12.0.3" targetFramework="net472" />
|
||||
<package id="K4os.Compression.LZ4" version="1.2.16" targetFramework="net472" />
|
||||
<package id="K4os.Compression.LZ4.Streams" version="1.2.16" targetFramework="net472" />
|
||||
<package id="K4os.Hash.xxHash" version="1.0.7" targetFramework="net472" />
|
||||
<package id="Microsoft.Bcl.AsyncInterfaces" version="8.0.0" targetFramework="net472" />
|
||||
<package id="Microsoft.ML.OnnxRuntime" version="1.15.1" targetFramework="net472" />
|
||||
<package id="Microsoft.ML.OnnxRuntime.Managed" version="1.15.1" targetFramework="net472" />
|
||||
<package id="MySql.Data" version="8.0.32.1" targetFramework="net472" />
|
||||
<package id="Newtonsoft.Json" version="13.0.3" targetFramework="net472" />
|
||||
<package id="OpenCvSharp4" version="4.5.3.20211207" targetFramework="net472" />
|
||||
<package id="OpenCvSharp4.runtime.win" version="4.5.5.20211231" targetFramework="net472" />
|
||||
<package id="OpenVINO.runtime.win" version="2024.3.0.1" targetFramework="net472" />
|
||||
<package id="Portable.BouncyCastle" version="1.9.0" targetFramework="net472" />
|
||||
<package id="SQLitePCLRaw.core" version="2.1.9" targetFramework="net472" />
|
||||
<package id="Stub.System.Data.SQLite.Core.NetFramework" version="1.0.118.0" targetFramework="net472" />
|
||||
<package id="System.Buffers" version="4.5.1" targetFramework="net472" />
|
||||
<package id="System.Collections.Immutable" version="8.0.0" targetFramework="net472" />
|
||||
<package id="System.Configuration.ConfigurationManager" version="4.4.1" targetFramework="net472" />
|
||||
<package id="System.Data.SQLite" version="1.0.118.0" targetFramework="net472" />
|
||||
<package id="System.Data.SQLite.Core" version="1.0.118.0" targetFramework="net472" />
|
||||
<package id="System.Data.SQLite.EF6" version="1.0.118.0" targetFramework="net472" />
|
||||
<package id="System.Data.SQLite.Linq" version="1.0.118.0" targetFramework="net472" />
|
||||
<package id="System.Diagnostics.DiagnosticSource" version="8.0.1" targetFramework="net472" />
|
||||
<package id="System.Drawing.Common" version="8.0.7" targetFramework="net472" />
|
||||
<package id="System.Drawing.Primitives" version="4.3.0" targetFramework="net472" />
|
||||
<package id="System.IO.Pipelines" version="6.0.3" targetFramework="net472" />
|
||||
<package id="System.Memory" version="4.5.5" targetFramework="net472" />
|
||||
<package id="System.Numerics.Vectors" version="4.5.0" targetFramework="net472" />
|
||||
<package id="System.Reflection.Metadata" version="5.0.0" targetFramework="net472" />
|
||||
<package id="System.Runtime" version="4.3.1" targetFramework="net472" />
|
||||
<package id="System.Runtime.CompilerServices.Unsafe" version="6.0.0" targetFramework="net472" />
|
||||
<package id="System.Runtime.Extensions" version="4.3.1" targetFramework="net472" />
|
||||
<package id="System.Runtime.Handles" version="4.3.0" targetFramework="net472" />
|
||||
<package id="System.Runtime.InteropServices.RuntimeInformation" version="4.3.0" targetFramework="net472" />
|
||||
<package id="System.Runtime.Numerics" version="4.3.0" targetFramework="net472" />
|
||||
<package id="System.Text.Encodings.Web" version="8.0.0" targetFramework="net472" />
|
||||
<package id="System.Text.Json" version="6.0.9" targetFramework="net472" />
|
||||
<package id="System.Threading.Tasks.Extensions" version="4.5.4" targetFramework="net472" />
|
||||
<package id="System.ValueTuple" version="4.5.0" targetFramework="net472" />
|
||||
<package id="ZstdSharp.Port" version="0.6.5" targetFramework="net472" />
|
||||
</packages>
|
Loading…
Reference in New Issue
Block a user