From 16d64aefba39becdddf41ce4762bd95f43c2e28b Mon Sep 17 00:00:00 2001 From: 820689062 <820689062@qq.com> Date: Sat, 17 Aug 2024 18:00:59 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E9=A1=B9=E7=9B=AE=E6=96=87?= =?UTF-8?q?=E4=BB=B6=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitattributes | 63 ++ .gitignore | 363 +++++++ App.config | 81 ++ CamManager.cs | 224 +++++ CameraBase.cs | 73 ++ Define.cs | 166 ++++ HikCamDriver.cs | 1303 +++++++++++++++++++++++++ HikCameraDriver.cs | 486 ++++++++++ JianZhenQi1.db | 0 LuJiaYi.csproj | 293 ++++++ LuJiaYi.sln | 31 + MGSCameraDriver.cs | 714 ++++++++++++++ MLResultDisplay.cs | 216 +++++ MainForm.Designer.cs | 1547 ++++++++++++++++++++++++++++++ MainForm.cs | 779 +++++++++++++++ MainForm.resx | 120 +++ PLCItem.cs | 54 ++ PlcContorl.cs | 358 +++++++ Process_Img.cs | 133 +++ Program.cs | 22 + Properties/AssemblyInfo.cs | 36 + Properties/Resources.Designer.cs | 71 ++ Properties/Resources.resx | 117 +++ Properties/Settings.Designer.cs | 30 + Properties/Settings.settings | 7 + README.md | 1 + SQLConnect.cs | 720 ++++++++++++++ SimboObjectDetection.cs | 304 ++++++ StaticHelper.cs | 682 +++++++++++++ Thread.cs | 51 + WriteLog.cs | 70 ++ packages.config | 48 + 32 files changed, 9163 insertions(+) create mode 100644 .gitattributes create mode 100644 .gitignore create mode 100644 App.config create mode 100644 CamManager.cs create mode 100644 CameraBase.cs create mode 100644 Define.cs create mode 100644 HikCamDriver.cs create mode 100644 HikCameraDriver.cs create mode 100644 JianZhenQi1.db create mode 100644 LuJiaYi.csproj create mode 100644 LuJiaYi.sln create mode 100644 MGSCameraDriver.cs create mode 100644 MLResultDisplay.cs create mode 100644 MainForm.Designer.cs create mode 100644 MainForm.cs create mode 100644 MainForm.resx create mode 100644 PLCItem.cs create mode 100644 PlcContorl.cs create mode 100644 Process_Img.cs create mode 100644 Program.cs create mode 100644 Properties/AssemblyInfo.cs create mode 100644 Properties/Resources.Designer.cs create mode 100644 Properties/Resources.resx create mode 100644 Properties/Settings.Designer.cs create mode 100644 Properties/Settings.settings create mode 100644 README.md create mode 100644 SQLConnect.cs create mode 100644 SimboObjectDetection.cs create mode 100644 StaticHelper.cs create mode 100644 Thread.cs create mode 100644 WriteLog.cs create mode 100644 packages.config diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..1ff0c42 --- /dev/null +++ b/.gitattributes @@ -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 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9491a2f --- /dev/null +++ b/.gitignore @@ -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 \ No newline at end of file diff --git a/App.config b/App.config new file mode 100644 index 0000000..7a20f8f --- /dev/null +++ b/App.config @@ -0,0 +1,81 @@ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/CamManager.cs b/CamManager.cs new file mode 100644 index 0000000..6e725e9 --- /dev/null +++ b/CamManager.cs @@ -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 cameraPaths = new Dictionary(); + + 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; + } +} + + diff --git a/CameraBase.cs b/CameraBase.cs new file mode 100644 index 0000000..56c03ac --- /dev/null +++ b/CameraBase.cs @@ -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 + { + /// + /// + /// + public Mat MyImage { get; set; } + /// + /// 相机名 + /// + public string CameraName { get; set; } + /// + /// 查找相机 + /// + /// + + /// + /// 根据相机序列号开启相机 + /// + /// + /// + public abstract bool OpenCamera(string serialNum,IntPtr hWnd);//根据相机序列号开启相机 + /// + /// 关闭相机 + /// + /// + public abstract bool CloserCamera();//关闭相机 + /// + ///软触发一次 + /// + /// + + + /// + /// 启动为硬触发 + /// + /// + public abstract bool EncoderGrap(); + /// + /// 重连相机 + /// + /// + /// + public abstract bool ReconnectCamera(string CameraName); + /// + /// 设置曝光 + /// + /// + /// + public abstract bool SetExpoureTime(int ExposureTime); + /// + /// 图像委托事件 用于传出参数 + /// + /// + public delegate void delegateProcessHImage(Mat Image); + + public event delegateProcessHImage EventProcessImage; + + public void GetImage(Mat getimage) + { + MyImage = new Mat(getimage); + EventProcessImage(MyImage); + } + } +} diff --git a/Define.cs b/Define.cs new file mode 100644 index 0000000..a2560cb --- /dev/null +++ b/Define.cs @@ -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 ResultDetails = new List(); + 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); + + + /// + /// 分割 + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + [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); + + + + /// + /// 目标检测 + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + [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, +} \ No newline at end of file diff --git a/HikCamDriver.cs b/HikCamDriver.cs new file mode 100644 index 0000000..79a8640 --- /dev/null +++ b/HikCamDriver.cs @@ -0,0 +1,1303 @@ +using OpenCvSharp; +using System; +using System.Collections.Generic; +using System.Drawing.Imaging; +using System.Drawing; +using System.Linq; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using System.Windows.Forms; +using MvCamCtrl.NET; +using OpenCvSharp.Dnn; +using System.Diagnostics; +using HalconDotNet; +using System.Xml.Linq; + +namespace GuideGraspSys +{ + public class HikCamDriver: CameraBase + { + [DllImport("kernel32.dll", EntryPoint = "CopyMemory", SetLastError = false)] + public static extern void CopyMemory(IntPtr dest, IntPtr src, uint count); + /// + /// 创建相机集合,存放相机 + /// + MyCamera.MV_CC_DEVICE_INFO_LIST m_pDeviceList; + MyCamera.MV_CC_DEVICE_INFO device; + + MyCamera hkCamera = new MyCamera(); + /// + /// 抓图回调 + /// + MyCamera.cbOutputExdelegate ImageCallback; + + Thread m_hReceiveThread = null; + + /// + /// 异常回调 + /// + MyCamera.cbExceptiondelegate pCallBackFunc; + HObject hPylonImage = new HObject(); + List CameraName = new List(); + + MyCamera.MV_FRAME_OUT _frame = new MyCamera.MV_FRAME_OUT(); + readonly ManualResetEvent _snapHandle = new ManualResetEvent(false); + bool _snapFlag = false; + + // ch:Bitmap及其像素格式 | en:Bitmap and Pixel Format + Bitmap m_bitmap = null; + PixelFormat m_bitmapPixelFormat = PixelFormat.DontCare; + IntPtr m_ConvertDstBuf = IntPtr.Zero; + UInt32 m_nConvertDstBufLen = 0; + + int nRet = MyCamera.MV_OK; + /// + /// 曝光时间 + /// + public int ExposureTime { get; set; } + /// + /// 增益 + /// + public int Gain { get; set; } + /// + /// 帧率 + /// + public int FrameRate { get; set; } + + + public bool m_bGrabbing = false; + + private static Object BufForDriverLock = new Object(); + + IntPtr m_BufForDriver = IntPtr.Zero; + + UInt32 m_nBufSizeForDriver = 0; + MyCamera.MV_FRAME_OUT_INFO_EX m_stFrameInfo = new MyCamera.MV_FRAME_OUT_INFO_EX(); + + public delegate void MatImgTransferDelegate(Mat img); + public event MatImgTransferDelegate OnImgTransfer; + + public delegate void BitmapTransferDelegate(Bitmap img); + public event BitmapTransferDelegate OnBitmapTransfer; + + public Action OnHImageOutput { get; set; } + + public static Dictionary allCamera=new Dictionary(); + private CameraInfor currentCam; + + public override bool CloserCamera() + { + m_bGrabbing = false; + hkCamera.MV_CC_StopGrabbing_NET();//停止采集 + hkCamera.MV_CC_CloseDevice_NET();//关闭设备 + hkCamera.MV_CC_DestroyDevice_NET(); + return true; + } + /// + /// 开启硬触发 + /// + /// + public override bool EncoderGrap() + { + try + { + if (m_bGrabbing) + { + Console.WriteLine("Camera is now Continue Grabing Images!"); + return false; + } + else + { + // ch:标志位置位true | en:Set position bit true + m_bGrabbing = true; + + hkCamera.MV_CC_SetEnumValue_NET("TriggerMode", (uint)MyCamera.MV_CAM_TRIGGER_MODE.MV_TRIGGER_MODE_ON); + //设置使用硬触发模式 + int nRet = hkCamera.MV_CC_SetEnumValue_NET("TriggerSource", (uint)MyCamera.MV_CAM_TRIGGER_SOURCE.MV_TRIGGER_SOURCE_LINE0); + + + if (MyCamera.MV_OK != nRet) + { + m_bGrabbing = false; + return false; + } + return true; + } + } + catch (Exception) + { + return false; + } + } + + + //public override List FindCamera() + //{ + // int nRet; + + // System.GC.Collect(); + // CameraName.Clear(); + + // nRet = MyCamera.MV_CC_EnumDevices_NET(MyCamera.MV_GIGE_DEVICE | MyCamera.MV_USB_DEVICE, ref m_pDeviceList); + // if (0 != nRet) + // { + // Console.WriteLine("Not Find Camera!{0:x8}", nRet); + // return null; + // } + // 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)); + // //网口相机 + // if (device.nTLayerType == MyCamera.MV_GIGE_DEVICE) + // { + // IntPtr buffer = Marshal.UnsafeAddrOfPinnedArrayElement(device.SpecialInfo.stGigEInfo, 0); + // MyCamera.MV_GIGE_DEVICE_INFO gigeInfo = (MyCamera.MV_GIGE_DEVICE_INFO)Marshal.PtrToStructure(buffer, typeof(MyCamera.MV_GIGE_DEVICE_INFO)); + // if (gigeInfo.chUserDefinedName != "") + // { + // Console.WriteLine("GigE:" + gigeInfo.chUserDefinedName + " (" + gigeInfo.chSerialNumber + ")"); + // CameraName.Add("GigE:" + gigeInfo.chUserDefinedName + " (" + gigeInfo.chSerialNumber + ")"); + // } + // else + // { + // Console.WriteLine("GigE: " + gigeInfo.chManufacturerName + " " + gigeInfo.chModelName + " (" + gigeInfo.chSerialNumber + ")"); + // CameraName.Add("GigE: " + gigeInfo.chManufacturerName + " " + gigeInfo.chModelName + " (" + gigeInfo.chSerialNumber + ")"); + // } + // } + // else if (device.nTLayerType == MyCamera.MV_USB_DEVICE) + // { + // IntPtr buffer = Marshal.UnsafeAddrOfPinnedArrayElement(device.SpecialInfo.stUsb3VInfo, 0); + // MyCamera.MV_USB3_DEVICE_INFO usbInfo = (MyCamera.MV_USB3_DEVICE_INFO)Marshal.PtrToStructure(buffer, typeof(MyCamera.MV_USB3_DEVICE_INFO)); + // if (usbInfo.chUserDefinedName != "") + // { + // Console.WriteLine("USB: " + usbInfo.chUserDefinedName + " (" + usbInfo.chSerialNumber + ")"); + // CameraName.Add("USB: " + usbInfo.chUserDefinedName + " (" + usbInfo.chSerialNumber + ")"); + // } + // else + // { + // Console.WriteLine("USB: " + usbInfo.chManufacturerName + " " + usbInfo.chModelName + " (" + usbInfo.chSerialNumber + ")"); + // CameraName.Add("USB: " + usbInfo.chManufacturerName + " " + usbInfo.chModelName + " (" + usbInfo.chSerialNumber + ")"); + // } + // } + // } + // if (m_pDeviceList.nDeviceNum == 0) + // { + // Console.WriteLine("未能找到USB或者网线接口的相机", 0); + // return null; + // } + + // return CameraName; + //} + public Dictionary EnumDevice() + { + System.GC.Collect();//强制对所有代进行及时垃圾回收 + m_pDeviceList.nDeviceNum = 0; //初始化信息列表 + int nRet = MyCamera.MV_CC_EnumDevices_NET(MyCamera.MV_GIGE_DEVICE | MyCamera.MV_USB_DEVICE, ref m_pDeviceList); + if (0 != nRet) + { + return null; + } + allCamera.Clear(); //清空设备列表 + CameraInfor cameraInfor; + 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));//获取第i个相机句柄的相机信息 + cameraInfor = new CameraInfor(); + cameraInfor.pDeviceInfo = m_pDeviceList.pDeviceInfo[i];//获取相机句柄 + if (device.nTLayerType == MyCamera.MV_GIGE_DEVICE) + { + MyCamera.MV_GIGE_DEVICE_INFO gigeInfo = (MyCamera.MV_GIGE_DEVICE_INFO)MyCamera.ByteToStruct(device.SpecialInfo.stGigEInfo, typeof(MyCamera.MV_GIGE_DEVICE_INFO));//将通用相机信息结构体转化为Gige相机结构体 + + UInt32 nNetIp1 = (gigeInfo.nNetExport & 0xFF000000) >> 24; + UInt32 nNetIp2 = (gigeInfo.nNetExport & 0x00FF0000) >> 16; + UInt32 nNetIp3 = (gigeInfo.nNetExport & 0x0000FF00) >> 8; + UInt32 nNetIp4 = (gigeInfo.nNetExport & 0x000000FF); + + // ch:显示IP | en:Display IP + UInt32 nIp1 = (gigeInfo.nCurrentIp & 0xFF000000) >> 24; + UInt32 nIp2 = (gigeInfo.nCurrentIp & 0x00FF0000) >> 16; + UInt32 nIp3 = (gigeInfo.nCurrentIp & 0x0000FF00) >> 8; + UInt32 nIp4 = (gigeInfo.nCurrentIp & 0x000000FF); + + + cameraInfor.serialNumber = gigeInfo.chSerialNumber; + cameraInfor.userDefinedName = gigeInfo.chUserDefinedName; + cameraInfor.manufacturerName = gigeInfo.chManufacturerName; + cameraInfor.modelName = gigeInfo.chModelName; + cameraInfor.deviceType = "GEV"; //千兆网工业相机技术之GigE Vision(GEV) + cameraInfor.deviceIPAdd = nIp1.ToString() + "." + nIp2.ToString() + "." + nIp3.ToString() + "." + nIp4.ToString(); + allCamera.Add(cameraInfor.userDefinedName, cameraInfor); + } + else if (device.nTLayerType == MyCamera.MV_USB_DEVICE) + { + MyCamera.MV_USB3_DEVICE_INFO usbInfo = (MyCamera.MV_USB3_DEVICE_INFO)MyCamera.ByteToStruct(device.SpecialInfo.stUsb3VInfo, typeof(MyCamera.MV_USB3_DEVICE_INFO)); + cameraInfor.serialNumber = usbInfo.chSerialNumber; + cameraInfor.userDefinedName = usbInfo.chUserDefinedName; + cameraInfor.manufacturerName = usbInfo.chManufacturerName; + cameraInfor.modelName = usbInfo.chModelName; + cameraInfor.deviceType = "U3V"; + allCamera.Add(cameraInfor.deviceIPAdd, cameraInfor); + } + + } + return allCamera; + } + /// + /// 根据相机序列号开启相机 + /// + /// + /// int cameraIndex + /// + public override bool OpenCamera(string userDefinedName, IntPtr hWnd) + { + int nRet = 0; + currentCam = allCamera[userDefinedName]; + //m_pDeviceList.pDeviceInfo[cameraIndex] + device = (MyCamera.MV_CC_DEVICE_INFO)Marshal.PtrToStructure(allCamera[userDefinedName].pDeviceInfo, typeof(MyCamera.MV_CC_DEVICE_INFO)); + IntPtr buffer = Marshal.UnsafeAddrOfPinnedArrayElement(device.SpecialInfo.stGigEInfo, 0); + MyCamera.MV_GIGE_DEVICE_INFO gigeInfo = (MyCamera.MV_GIGE_DEVICE_INFO)Marshal.PtrToStructure(buffer, typeof(MyCamera.MV_GIGE_DEVICE_INFO)); + + + if (null == hkCamera) + { + hkCamera = new MyCamera(); + if (null == hkCamera) + { + return false; + } + } + for (int i = 0; i < 10; i++) + { + nRet = hkCamera.MV_CC_CreateDevice_NET(ref device); + if (MyCamera.MV_OK != nRet) + { + Thread.Sleep(1); + if (i == 9) Console.WriteLine("创建相机失败!{0:x8}", nRet); + continue; + } + nRet = hkCamera.MV_CC_OpenDevice_NET(); + if (MyCamera.MV_OK != nRet) + { + hkCamera.MV_CC_DestroyDevice_NET(); + Thread.Sleep(10); + if (i == 9) Console.WriteLine("打开相机失败!{0:x8}", nRet); + } + else + { + break; + } + } + //探测网络最佳包大小(只对gige相机有效) + if (device.nTLayerType == MyCamera.MV_GIGE_DEVICE) + { + int nPacketSize = hkCamera.MV_CC_GetOptimalPacketSize_NET(); + if (nPacketSize > 0) + { + nRet = hkCamera.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); + } + } + + SetTriggerMode(true); + SetSoftTrigger(true); + + //注册断线重连回调函数 + nRet = hkCamera.MV_CC_RegisterExceptionCallBack_NET(pCallBackFunc, IntPtr.Zero); + if (MyCamera.MV_OK != nRet) + { + return false; + } + GC.KeepAlive(pCallBackFunc); + //注册图像回调函数 + //ImageCallback = new MyCamera.cbOutputExdelegate(ImageCallbackFunc); + //nRet = hkCamera.MV_CC_RegisterImageCallBackEx_NET(ImageCallback, IntPtr.Zero); + if (MyCamera.MV_OK != nRet) + { + Console.WriteLine("Register image callback failed!"); + return false; + } + + // ch:设置采集连续模式 | en:Set Continues Aquisition Mode + hkCamera.MV_CC_SetEnumValue_NET("AcquisitionMode", (uint)MyCamera.MV_CAM_ACQUISITION_MODE.MV_ACQ_MODE_CONTINUOUS); + //设置开启触发模式 + nRet = hkCamera.MV_CC_SetEnumValue_NET("TriggerMode", (uint)MyCamera.MV_CAM_TRIGGER_MODE.MV_TRIGGER_MODE_OFF); + //设置开启软触发模式 + //hkCamera.MV_CC_SetEnumValue_NET("TriggerSource", (uint)MyCamera.MV_CAM_TRIGGER_SOURCE.MV_TRIGGER_SOURCE_SOFTWARE); + //使用软触发命令 + //nRet = hkCamera.MV_CC_SetCommandValue_NET("TriggerSoftware"); + if (MyCamera.MV_OK != nRet) + { + m_bGrabbing = false; + return false; + } + //开始采集 + // nRet = hkCamera.MV_CC_StartGrabbing_NET(); + if (MyCamera.MV_OK != nRet) + { + Console.WriteLine("开启相机采集失败! {0:x8}", nRet); + return false; + } + + + + return true; + } + + + /// + /// 设置触发模式 + /// + /// 触发模式:true;连续采集模式:false + public void SetTriggerMode(bool isTrigger) + { + if (isTrigger) + { + hkCamera.MV_CC_SetEnumValue_NET("TriggerMode", (uint)MyCamera.MV_CAM_TRIGGER_MODE.MV_TRIGGER_MODE_ON); + } + else + { + hkCamera.MV_CC_SetEnumValue_NET("TriggerMode", (uint)MyCamera.MV_CAM_TRIGGER_MODE.MV_TRIGGER_MODE_OFF); + } + } + + /// + /// 设置软触发 + /// + /// + public void SetSoftTrigger(bool trigBySoft) + { + if (trigBySoft) + { + hkCamera.MV_CC_SetEnumValue_NET("TriggerSource", (uint)MyCamera.MV_CAM_TRIGGER_SOURCE.MV_TRIGGER_SOURCE_SOFTWARE); + } + else + { + //外部触发源:Line0~Line3,默认用Line0 + hkCamera.MV_CC_SetEnumValue_NET("TriggerSource", (uint)MyCamera.MV_CAM_TRIGGER_SOURCE.MV_TRIGGER_SOURCE_LINE0); + } + } + + + /// + /// + //public override bool OneGrap() + //{ + // try + // { + // if (m_bGrabbing) + // { + // Console.WriteLine("Camera is now Continue Grabing Images!"); + + // return false; + // } + // else + // { + // // ch:标志位置位true | en:Set position bit true + // //m_bGrabbing = true; + // int nRet; + // MyCamera.MV_FRAME_OUT frameInfo = new MyCamera.MV_FRAME_OUT(); + // //设置开启触发模式 + // nRet = hkCamera.MV_CC_SetEnumValue_NET("TriggerMode", (uint)MyCamera.MV_CAM_TRIGGER_MODE.MV_TRIGGER_MODE_ON); + // //设置开启软触发模式 + // nRet = hkCamera.MV_CC_SetEnumValue_NET("TriggerSource", (uint)MyCamera.MV_CAM_TRIGGER_SOURCE.MV_TRIGGER_SOURCE_SOFTWARE); + + // //使用软触发命令 + // nRet = hkCamera.MV_CC_SetCommandValue_NET("TriggerSoftware"); + + + // if (MyCamera.MV_OK != nRet) + // { + // throw new Exception($"相机拍照触发失败:{nRet}"); + // } + // //nRet = hkCamera.MV_CC_GetImageBuffer_NET(ref frameInfo, 1000); + // //nRet = hkCamera.MV_CC_FreeImageBuffer_NET(ref frameInfo); + // if (MyCamera.MV_OK != nRet) + // { + // m_bGrabbing = false; + // return false; + // } + // else + // { + // //if (frameInfo.pBufAddr != IntPtr.Zero) + // //{ + // if (nRet == MyCamera.MV_OK) + // { + // var pFrameInfo = frameInfo.stFrameInfo; + + // //himg.GenImage1("byte", pFrameInfo.nWidth, pFrameInfo.nHeight, frameInfo.pBufAddr); + // Mat mat = Mat.FromPixelData(pFrameInfo.nWidth, pFrameInfo.nHeight, MatType.CV_8UC3, frameInfo.pBufAddr); + // //Bitmap a = OpenCvSharp.Extensions.BitmapConverter.ToBitmap(mat); + // //OnDeliverImg?.Invoke(_mat); + // Cv2.ImWrite("test.jpg", mat); + // OnImgTransfer?.Invoke(mat); + // } + // //} + // } + + // // HeventSlim.Wait(); + // return true; + // } + // } + // catch (Exception) + // { + // return false; + // } + + //} + + bool IsGrabImg; + public void GrabImg() + { + IsGrabImg = true; + int nRet = hkCamera.MV_CC_SetCommandValue_NET("TriggerSoftware"); + MyCamera.MV_FRAME_OUT frameInfo = new MyCamera.MV_FRAME_OUT(); + + //nRet = m_MyCamera.MV_CC_GetImageBuffer_NET(ref frameInfo,10); + //nRet = m_MyCamera.MV_CC_FreeImageBuffer_NET(ref frameInfo); + if (MyCamera.MV_OK != nRet) + { + //ShowErrorMsg("Trigger Software Fail!", nRet); + } + } + + + public void StartGarb(IntPtr handle) + { + int nRet; + nRet = NecessaryOperBeforeGrab(); + + m_bGrabbing = true; + IsGrabImg = false; + m_hReceiveThread = new Thread(new ParameterizedThreadStart(ReceiveThreadProcess)); + m_hReceiveThread.Start(handle); + + m_stFrameInfo.nFrameLen = 0; + + m_stFrameInfo.enPixelType = MyCamera.MvGvspPixelType.PixelType_Gvsp_Undefined; + // nRet = hkCamera.MV_CC_SetEnumValue_NET("TriggerMode", (uint)MyCamera.MV_CAM_TRIGGER_MODE.MV_TRIGGER_MODE_ON); + //设置开启软触发模式 + //nRet = hkCamera.MV_CC_SetEnumValue_NET("TriggerSource", (uint)MyCamera.MV_CAM_TRIGGER_SOURCE.MV_TRIGGER_SOURCE_SOFTWARE); + // ch:开始采集 | en:Start Grabbing + nRet = hkCamera.MV_CC_StartGrabbing_NET(); + if (MyCamera.MV_OK != nRet) + { + m_bGrabbing = false; + m_hReceiveThread.Join(); + //ShowErrorMsg("Start Grabbing Fail!", nRet); + return; + } + } + + //public void StopGrabbing() + //{ + // int nRet = hkCamera.MV_CC_StopGrabbing_NET(); + // if (nRet != MyCamera.MV_OK) + // { + // //ShowAlarm(string.Format("相机{0}结束采集失败,错误代码:{1}", m_Name, nRet)); + // } + + //} + + public void ReceiveThreadProcess(object handle) + { + MyCamera.MV_FRAME_OUT stFrameInfo = new MyCamera.MV_FRAME_OUT(); + MyCamera.MV_DISPLAY_FRAME_INFO stDisplayInfo = new MyCamera.MV_DISPLAY_FRAME_INFO(); + MyCamera.MV_PIXEL_CONVERT_PARAM stConvertInfo = new MyCamera.MV_PIXEL_CONVERT_PARAM(); + int nRet = MyCamera.MV_OK; + + while (m_bGrabbing) + { + nRet = hkCamera.MV_CC_GetImageBuffer_NET(ref stFrameInfo, 1000); + if (nRet == MyCamera.MV_OK) + { + lock (BufForDriverLock) + { + if (m_BufForDriver == IntPtr.Zero || stFrameInfo.stFrameInfo.nFrameLen > m_nBufSizeForDriver) + { + if (m_BufForDriver != IntPtr.Zero) + { + Marshal.Release(m_BufForDriver); + m_BufForDriver = IntPtr.Zero; + } + + m_BufForDriver = Marshal.AllocHGlobal((Int32)stFrameInfo.stFrameInfo.nFrameLen); + if (m_BufForDriver == IntPtr.Zero) + { + return; + } + m_nBufSizeForDriver = stFrameInfo.stFrameInfo.nFrameLen; + } + + m_stFrameInfo = stFrameInfo.stFrameInfo; + CopyMemory(m_BufForDriver, stFrameInfo.pBufAddr, stFrameInfo.stFrameInfo.nFrameLen); + + stConvertInfo.nWidth = stFrameInfo.stFrameInfo.nWidth; + stConvertInfo.nHeight = stFrameInfo.stFrameInfo.nHeight; + stConvertInfo.enSrcPixelType = stFrameInfo.stFrameInfo.enPixelType; + stConvertInfo.pSrcData = stFrameInfo.pBufAddr; + stConvertInfo.nSrcDataLen = stFrameInfo.stFrameInfo.nFrameLen; + stConvertInfo.pDstBuffer = m_ConvertDstBuf; + stConvertInfo.nDstBufferSize = m_nConvertDstBufLen; + if (PixelFormat.Format8bppIndexed == m_bitmap.PixelFormat) + { + stConvertInfo.enDstPixelType = MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono8; + hkCamera.MV_CC_ConvertPixelType_NET(ref stConvertInfo); + } + else + { + stConvertInfo.enDstPixelType = MyCamera.MvGvspPixelType.PixelType_Gvsp_BGR8_Packed; + hkCamera.MV_CC_ConvertPixelType_NET(ref stConvertInfo); + } + + // ch:保存Bitmap数据 | en:Save Bitmap Data + BitmapData bitmapData = m_bitmap.LockBits(new Rectangle(0, 0, stConvertInfo.nWidth, stConvertInfo.nHeight), ImageLockMode.ReadWrite, m_bitmap.PixelFormat); + CopyMemory(bitmapData.Scan0, stConvertInfo.pDstBuffer, (UInt32)(bitmapData.Stride * m_bitmap.Height)); + m_bitmap.UnlockBits(bitmapData); + + } + if (RemoveCustomPixelFormats(stFrameInfo.stFrameInfo.enPixelType)) + { + hkCamera.MV_CC_FreeImageBuffer_NET(ref stFrameInfo); + continue; + } + + nRet = hkCamera.MV_CC_FreeImageBuffer_NET(ref stFrameInfo); + if (IsGrabImg) + { + if (MyCamera.MV_OK == nRet) + { + if (stFrameInfo.pBufAddr != IntPtr.Zero) + { + stDisplayInfo.hWnd = (IntPtr)handle; + stDisplayInfo.pData = stFrameInfo.pBufAddr; + stDisplayInfo.nDataLen = stFrameInfo.stFrameInfo.nFrameLen; + stDisplayInfo.nWidth = stFrameInfo.stFrameInfo.nWidth; + stDisplayInfo.nHeight = stFrameInfo.stFrameInfo.nHeight; + stDisplayInfo.enPixelType = stFrameInfo.stFrameInfo.enPixelType; + hkCamera.MV_CC_DisplayOneFrame_NET(ref stDisplayInfo); + //nRet = hkCamera.MV_CC_FreeImageBuffer_NET(ref stFrameInfo); + var pFrameInfo = stFrameInfo.stFrameInfo; + Mat ab = new Mat(pFrameInfo.nHeight, pFrameInfo.nWidth, MatType.CV_8UC3, stFrameInfo.pBufAddr); + //OnImgTransfer?.Invoke(ab); + OnHImageOutput?.Invoke(DateTime.Now, ab); + //Cv2.ImWrite("test.jpg", ab); + + } + } + } + + + } + else + { + + } + } + } + public void ConvertToImage(IntPtr pData, ref MyCamera.MV_FRAME_OUT_INFO_EX pFrameInfo, IntPtr pUser) + { + int nRet; + //HObject img = new HObject(); + Mat matImag = new Mat(); + //Bitmap bitmap = new Bitmap(); + IntPtr pImageBuf = IntPtr.Zero; + int nImageBufSize = 0; + //Bitmap cameraImg; + IntPtr pTemp = IntPtr.Zero; + if (IsColorPixelFormat(pFrameInfo.enPixelType)) + { + //cameraImg = new Bitmap(pFrameInfo.nWidth, pFrameInfo.nHeight, pFrameInfo.nWidth * 3, System.Drawing.Imaging.PixelFormat.Format24bppRgb,pData); + + //bmp.Save("1.bmp", System.Drawing.Imaging.ImageFormat.Bmp); + + if (pFrameInfo.enPixelType == MyCamera.MvGvspPixelType.PixelType_Gvsp_RGB8_Packed) + { + pTemp = pData; + } + else + { + if (IntPtr.Zero == pImageBuf || nImageBufSize < (pFrameInfo.nWidth * pFrameInfo.nHeight * 3)) + { + if (pImageBuf != IntPtr.Zero) + { + Marshal.FreeHGlobal(pImageBuf); + pImageBuf = IntPtr.Zero; + } + pImageBuf = Marshal.AllocHGlobal((int)pFrameInfo.nWidth * pFrameInfo.nHeight * 3); + if (IntPtr.Zero == pImageBuf) + { + Console.WriteLine("图像采集为空"); + return; + } + nImageBufSize = pFrameInfo.nWidth * pFrameInfo.nHeight * 3; + } + MyCamera.MV_PIXEL_CONVERT_PARAM stPixelConvertParam = new MyCamera.MV_PIXEL_CONVERT_PARAM(); + + stPixelConvertParam.pSrcData = pData;//源数据 + stPixelConvertParam.nWidth = pFrameInfo.nWidth;//图像宽度 + stPixelConvertParam.nHeight = pFrameInfo.nHeight;//图像高度 + stPixelConvertParam.enSrcPixelType = pFrameInfo.enPixelType;//源数据的格式 + stPixelConvertParam.nSrcDataLen = pFrameInfo.nFrameLen; + + stPixelConvertParam.nDstBufferSize = (uint)nImageBufSize; + stPixelConvertParam.pDstBuffer = pImageBuf;//转换后的数据 + stPixelConvertParam.enDstPixelType = MyCamera.MvGvspPixelType.PixelType_Gvsp_RGB8_Packed; + + + nRet = hkCamera.MV_CC_ConvertPixelType_NET(ref stPixelConvertParam);//格式转换 + if (MyCamera.MV_OK != nRet) + { + Console.WriteLine("图像转换异常"); + return; + } + pTemp = stPixelConvertParam.pDstBuffer; + } + try + { + HOperatorSet.GenImageInterleaved(out hPylonImage, (HTuple)pTemp, (HTuple)"rgb", (HTuple)pFrameInfo.nWidth, (HTuple)pFrameInfo.nHeight, -1, "byte", 0, 0, 0, 0, -1, 0); + + } + catch (System.Exception ex) + { + Console.WriteLine(ex.ToString()); + return; + } + } + else if (IsMonoPixelFormat(pFrameInfo.enPixelType)) + { + if (pFrameInfo.enPixelType == MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono8) + { + pTemp = pData; + } + else + { + if (IntPtr.Zero == pImageBuf || nImageBufSize < (pFrameInfo.nWidth * pFrameInfo.nHeight)) + { + if (pImageBuf != IntPtr.Zero) + { + Marshal.FreeHGlobal(pImageBuf); + pImageBuf = IntPtr.Zero; + } + + pImageBuf = Marshal.AllocHGlobal((int)pFrameInfo.nWidth * pFrameInfo.nHeight); + if (IntPtr.Zero == pImageBuf) + { + Console.WriteLine("图像采集为空"); + return; + } + nImageBufSize = pFrameInfo.nWidth * pFrameInfo.nHeight; + } + + MyCamera.MV_PIXEL_CONVERT_PARAM stPixelConvertParam = new MyCamera.MV_PIXEL_CONVERT_PARAM(); + + stPixelConvertParam.pSrcData = pData;//源数据 + stPixelConvertParam.nWidth = pFrameInfo.nWidth;//图像宽度 + stPixelConvertParam.nHeight = pFrameInfo.nHeight;//图像高度 + stPixelConvertParam.enSrcPixelType = pFrameInfo.enPixelType;//源数据的格式 + stPixelConvertParam.nSrcDataLen = pFrameInfo.nFrameLen; + + stPixelConvertParam.nDstBufferSize = (uint)nImageBufSize; + stPixelConvertParam.pDstBuffer = pImageBuf;//转换后的数据 + stPixelConvertParam.enDstPixelType = MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono8; + nRet = hkCamera.MV_CC_ConvertPixelType_NET(ref stPixelConvertParam);//格式转换 + if (MyCamera.MV_OK != nRet) + { + Console.WriteLine("图像转换异常"); + return; + } + pTemp = stPixelConvertParam.pDstBuffer; ; + } + try + { + //cameraImg = new Bitmap(); + // HOperatorSet.GenImage1Extern(out hPylonImage, "byte", pFrameInfo.nWidth, pFrameInfo.nHeight, pTemp, IntPtr.Zero); + } + catch (System.Exception ex) + { + MessageBox.Show(ex.ToString()); + return; + } + } + else + { + Console.WriteLine("采集图像格式错误,不为彩色和黑白图像"); + return; + } + + try + { + //GetImage(hPylonImage);//调用相机基类的函数,用于传出变量 + //hPylonImage.Dispose(); + m_bGrabbing = false; + } + catch (Exception e) + { + Console.WriteLine(e.ToString()); + return; + } + } + private Boolean IsMono(UInt32 enPixelType) + { + switch (enPixelType) + { + case (UInt32)MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono1p: + case (UInt32)MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono2p: + case (UInt32)MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono4p: + case (UInt32)MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono8: + case (UInt32)MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono8_Signed: + case (UInt32)MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono10: + case (UInt32)MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono10_Packed: + case (UInt32)MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono12: + case (UInt32)MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono12_Packed: + case (UInt32)MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono14: + case (UInt32)MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono16: + return true; + default: + return false; + } + } + private Int32 NecessaryOperBeforeGrab() + { + // ch:取图像宽 | en:Get Iamge Width + MyCamera.MVCC_INTVALUE_EX stWidth = new MyCamera.MVCC_INTVALUE_EX(); + int nRet = hkCamera.MV_CC_GetIntValueEx_NET("Width", ref stWidth); + if (MyCamera.MV_OK != nRet) + { + //ShowErrorMsg("Get Width Info Fail!", nRet); + return nRet; + } + // ch:取图像高 | en:Get Iamge Height + MyCamera.MVCC_INTVALUE_EX stHeight = new MyCamera.MVCC_INTVALUE_EX(); + nRet = hkCamera.MV_CC_GetIntValueEx_NET("Height", ref stHeight); + if (MyCamera.MV_OK != nRet) + { + //ShowErrorMsg("Get Height Info Fail!", nRet); + return nRet; + } + // ch:取像素格式 | en:Get Pixel Format + MyCamera.MVCC_ENUMVALUE stPixelFormat = new MyCamera.MVCC_ENUMVALUE(); + nRet = hkCamera.MV_CC_GetEnumValue_NET("PixelFormat", ref stPixelFormat); + if (MyCamera.MV_OK != nRet) + { + //ShowErrorMsg("Get Pixel Format Fail!", nRet); + return nRet; + } + + // ch:设置bitmap像素格式,申请相应大小内存 | en:Set Bitmap Pixel Format, alloc memory + if ((Int32)MyCamera.MvGvspPixelType.PixelType_Gvsp_Undefined == stPixelFormat.nCurValue) + { + //ShowErrorMsg("Unknown Pixel Format!", MyCamera.MV_E_UNKNOW); + return MyCamera.MV_E_UNKNOW; + } + else if (IsMono(stPixelFormat.nCurValue)) + { + m_bitmapPixelFormat = PixelFormat.Format8bppIndexed; + + if (IntPtr.Zero != m_ConvertDstBuf) + { + Marshal.Release(m_ConvertDstBuf); + m_ConvertDstBuf = IntPtr.Zero; + } + + // Mono8为单通道 + m_nConvertDstBufLen = (UInt32)(stWidth.nCurValue * stHeight.nCurValue); + m_ConvertDstBuf = Marshal.AllocHGlobal((Int32)m_nConvertDstBufLen); + if (IntPtr.Zero == m_ConvertDstBuf) + { + //ShowErrorMsg("Malloc Memory Fail!", MyCamera.MV_E_RESOURCE); + return MyCamera.MV_E_RESOURCE; + } + } + else + { + m_bitmapPixelFormat = PixelFormat.Format24bppRgb; + + if (IntPtr.Zero != m_ConvertDstBuf) + { + Marshal.FreeHGlobal(m_ConvertDstBuf); + m_ConvertDstBuf = IntPtr.Zero; + } + + // RGB为三通道 + m_nConvertDstBufLen = (UInt32)(3 * stWidth.nCurValue * stHeight.nCurValue); + m_ConvertDstBuf = Marshal.AllocHGlobal((Int32)m_nConvertDstBufLen); + if (IntPtr.Zero == m_ConvertDstBuf) + { + //ShowErrorMsg("Malloc Memory Fail!", MyCamera.MV_E_RESOURCE); + return MyCamera.MV_E_RESOURCE; + } + } + + // 确保释放保存了旧图像数据的bitmap实例,用新图像宽高等信息new一个新的bitmap实例 + if (null != m_bitmap) + { + m_bitmap.Dispose(); + m_bitmap = null; + } + m_bitmap = new Bitmap((Int32)stWidth.nCurValue, (Int32)stHeight.nCurValue, m_bitmapPixelFormat); + + // ch:Mono8格式,设置为标准调色板 | en:Set Standard Palette in Mono8 Format + if (PixelFormat.Format8bppIndexed == m_bitmapPixelFormat) + { + ColorPalette palette = m_bitmap.Palette; + for (int i = 0; i < palette.Entries.Length; i++) + { + palette.Entries[i] = Color.FromArgb(i, i, i); + } + m_bitmap.Palette = palette; + } + + return MyCamera.MV_OK; + } + + + + /// + /// 相机重连开启 + /// + /// + /// + public override bool ReconnectCamera(string CameraName) + { + CloserCamera(); + for (int i = 0; i < m_pDeviceList.nDeviceNum; i++) + { + device = (MyCamera.MV_CC_DEVICE_INFO)Marshal.PtrToStructure(m_pDeviceList.pDeviceInfo[i], typeof(MyCamera.MV_CC_DEVICE_INFO)); + IntPtr buffer = Marshal.UnsafeAddrOfPinnedArrayElement(device.SpecialInfo.stGigEInfo, 0); + MyCamera.MV_GIGE_DEVICE_INFO gigeInfo = (MyCamera.MV_GIGE_DEVICE_INFO)Marshal.PtrToStructure(buffer, typeof(MyCamera.MV_GIGE_DEVICE_INFO)); + if (gigeInfo.chSerialNumber == CameraName) + { + break; + } + } + int index = 0; + while (true) + { + int nRet = hkCamera.MV_CC_CreateDevice_NET(ref device); + index++; + if (index > 1000) + { + Console.WriteLine("相机重连超时,请检查相机安装"); + nRet = -1; + break; + } + if (MyCamera.MV_OK != nRet) + { + Thread.Sleep(5); + continue; + } + nRet = hkCamera.MV_CC_OpenDevice_NET(); + if (MyCamera.MV_OK != nRet) + { + Thread.Sleep(5); + hkCamera.MV_CC_DestroyDevice_NET(); + continue; + } + else + { + if (MyCamera.MV_OK != nRet) + { + Thread.Sleep(5); + hkCamera.MV_CC_DestroyDevice_NET(); + continue; + } + break; + } + } + return true; + } + + void ImageCallbackFunc(IntPtr pData, ref MyCamera.MV_FRAME_OUT_INFO_EX pFrameInfo, IntPtr pUser) + { + //Console.WriteLine("Get one frame: Width[" + Convert.ToString(pFrameInfo.nWidth) + "] , Height[" + Convert.ToString(pFrameInfo.nHeight) + // + "] , FrameNum[" + Convert.ToString(pFrameInfo.nFrameNum) + "]"); + + ConvertToImage(pData, ref pFrameInfo, pUser); + } + + + public Action OnDeliverImg { get; set; } + + + + public void Snapshot() + { + Stopwatch sw = new Stopwatch(); + sw.Start(); + // ImageSet set = new ImageSet(); + // set.SnapshotCount = SnapshotCount; + // set.SnapshotFileName = SnapshotFileNames; + + //InitialImageSet(set); + MyCamera.MV_FRAME_OUT frameInfo = new MyCamera.MV_FRAME_OUT(); + nRet = MyCamera.MV_OK; + if (true) + { + // ch: 触发命令 || en: Trigger command + nRet = hkCamera.MV_CC_SetCommandValue_NET("TriggerSoftware"); + if (MyCamera.MV_OK != nRet) + { + throw new Exception($"相机拍照触发失败:{nRet}"); + } + + nRet = hkCamera.MV_CC_GetImageBuffer_NET(ref frameInfo, 1000); + nRet = hkCamera.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; + HImage hImage = new HImage(); + hImage.GenImage1("byte", pFrameInfo.nWidth, pFrameInfo.nHeight, frameInfo.pBufAddr); + Mat mat = new Mat(); + Bitmap a = hImage.ConvertHImageToBitmap(); + OnBitmapTransfer?.Invoke(a); + + } + } + } + else + { + throw new Exception($"Grap Image Failed:{nRet:x8}"); + } + + sw.Stop(); + //LogAsync(DateTime.Now, LogLevel.Information, $"取像耗时:{sw.ElapsedMilliseconds} ms"); + } + + /// + /// 转化像素为Bit图像 + /// + /// + /// + public Bitmap GetBitmap(int nWidth, int nHeight, int nBpp, byte[] DataBuf, int nCompress = 1) + { + int nNewH = nHeight / nCompress; + int nNewW = nWidth / nCompress; + + + Bitmap BitmapImage = new Bitmap(nNewW, nNewH, PixelFormat.Format24bppRgb); + BitmapData srcBmpData = + BitmapImage.LockBits( + new Rectangle(0, 0, BitmapImage.Width, BitmapImage.Height), + ImageLockMode.ReadWrite, BitmapImage.PixelFormat); + + switch (nBpp) + { + case 0: + unsafe + { + byte* psrcBuffer = (byte*)srcBmpData.Scan0.ToPointer(); + + int nIndex = 0; + + for (int i = 0; i < nHeight; i += nCompress) + { + for (int j = 0; j < nWidth; j += nCompress) + { + psrcBuffer[nIndex++] = DataBuf[i * nWidth + j]; + psrcBuffer[nIndex++] = DataBuf[i * nWidth + j]; + psrcBuffer[nIndex++] = DataBuf[i * nWidth + j]; + } + } + + } + break; + + case 1: + unsafe + { + byte* psrcBuffer = (byte*)srcBmpData.Scan0.ToPointer(); + + int nCount = nWidth * nHeight; + int nStep = nCount * 2; + int nIndex = 0; + + for (int i = 0; i < nHeight; i += nCompress) + { + for (int j = 0; j < nWidth; j += nCompress) + { + psrcBuffer[nIndex++] = DataBuf[i * nWidth + j + nStep]; + psrcBuffer[nIndex++] = DataBuf[i * nWidth + j + nCount]; + psrcBuffer[nIndex++] = DataBuf[i * nWidth + j]; + } + } + } + break; + } + BitmapImage.UnlockBits(srcBmpData); + return BitmapImage; + } + + + public void SetHeartBeatTime(uint value) + { + try + { + //判断是否是网口相机 + if (device.nTLayerType == MyCamera.MV_GIGE_DEVICE) + { + hkCamera.MV_CC_SetHeartBeatTimeout_NET(value); + } + } + catch (Exception) + { + + } + } + + public override bool SetExpoureTime(int ExposureTime) + { + try + { + hkCamera.MV_CC_SetEnumValue_NET("ExposureAuto", 0); + int nRet = hkCamera.MV_CC_SetFloatValue_NET("ExposureTime", ExposureTime); + if (nRet != MyCamera.MV_OK) + { + return false; + } + return true; + } + catch (Exception) + { + return false; + } + } + /// + /// 判断是否为彩色图像 + /// + /// + /// + private bool IsColorPixelFormat(MyCamera.MvGvspPixelType enType) + { + switch (enType) + { + case MyCamera.MvGvspPixelType.PixelType_Gvsp_RGB8_Packed: + case MyCamera.MvGvspPixelType.PixelType_Gvsp_BGR8_Packed: + case MyCamera.MvGvspPixelType.PixelType_Gvsp_RGBA8_Packed: + case MyCamera.MvGvspPixelType.PixelType_Gvsp_BGRA8_Packed: + case MyCamera.MvGvspPixelType.PixelType_Gvsp_YUV422_Packed: + case MyCamera.MvGvspPixelType.PixelType_Gvsp_YUV422_YUYV_Packed: + case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerGR8: + case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerRG8: + case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerGB8: + case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerBG8: + case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerGB10: + case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerGB10_Packed: + case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerBG10: + case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerBG10_Packed: + case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerRG10: + case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerRG10_Packed: + case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerGR10: + case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerGR10_Packed: + case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerGB12: + case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerGB12_Packed: + case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerBG12: + case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerBG12_Packed: + case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerRG12: + case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerRG12_Packed: + case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerGR12: + case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerGR12_Packed: + return true; + default: + return false; + } + } + private bool IsMonoPixelFormat(MyCamera.MvGvspPixelType enType) + { + switch (enType) + { + 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; + } + } + private bool RemoveCustomPixelFormats(MyCamera.MvGvspPixelType enPixelFormat) + { + Int32 nResult = ((int)enPixelFormat) & (unchecked((Int32)0x80000000)); + if (0x80000000 == nResult) + { + return true; + } + else + { + return false; + } + } + + + public void SetTriggerMode() + { + hkCamera.MV_CC_SetEnumValue_NET("TriggerMode", (uint)MyCamera.MV_CAM_TRIGGER_MODE.MV_TRIGGER_MODE_OFF); + } + public void SetTriggerModeON() + { + hkCamera.MV_CC_SetEnumValue_NET("TriggerMode", (uint)MyCamera.MV_CAM_TRIGGER_MODE.MV_TRIGGER_MODE_ON); + } + public void SetTriggerSource() + { + hkCamera.MV_CC_SetEnumValue_NET("TriggerSource", (uint)MyCamera.MV_CAM_TRIGGER_SOURCE.MV_TRIGGER_SOURCE_SOFTWARE); + } + public void SetTriggerSourceLine0() + { + hkCamera.MV_CC_SetEnumValue_NET("TriggerSource", (uint)MyCamera.MV_CAM_TRIGGER_SOURCE.MV_TRIGGER_SOURCE_LINE0); + } + public void SetTriggerMode1() + { + int nRet; + nRet = hkCamera.MV_CC_SetEnumValue_NET("TriggerMode", (uint)MyCamera.MV_CAM_TRIGGER_MODE.MV_TRIGGER_MODE_ON); + //设置开启软触发模式 + nRet = hkCamera.MV_CC_SetEnumValue_NET("TriggerSource", (uint)MyCamera.MV_CAM_TRIGGER_SOURCE.MV_TRIGGER_SOURCE_SOFTWARE); + } + + } + public static class HalconHelper + { + [DllImport("kernel32.dll", EntryPoint = "CopyMemory", SetLastError = false)] + public static extern void CopyMemory(IntPtr dest, IntPtr src, uint count); + public static Bitmap ConvertHImageToBitmap(this HObject hImage) + { + HOperatorSet.CountChannels(hImage, out HTuple chanels); + if (chanels.I == 1) + { + return hImage.ConvertHImageTo8GrayBitmap(); + } + else + { + return hImage.ConvertHImageToRGBBitmap(); + // return hImage.HObject2BitmapRGB(); + } + } + public static Bitmap ConvertHImageTo8GrayBitmap(this HObject hImage) + { + try + { + HTuple type, width, height, pointer; + HOperatorSet.GetImagePointer1(hImage, out pointer, out type, out width, out height); + + Bitmap bmp = new Bitmap(width.I, height.I, PixelFormat.Format8bppIndexed); + ColorPalette pal = bmp.Palette; + for (int i = 0; i <= 255; i++) + { + pal.Entries[i] = Color.FromArgb(255, i, i, i); + } + bmp.Palette = pal; + + BitmapData bitmapData = bmp.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.WriteOnly, PixelFormat.Format8bppIndexed); + + if (width % 4 == 0) + { + CopyMemory(bitmapData.Scan0, (IntPtr)pointer.D, (uint)(bitmapData.Stride * height.I)); + } + else + { + Parallel.For(0, height.I, h => + { + CopyMemory(bitmapData.Scan0 + h * bitmapData.Stride, (IntPtr)(pointer.D + h * width.I), (uint)width.I); + }); + } + + bmp.UnlockBits(bitmapData); + return bmp; + } + catch (Exception ex) + { + return null; + } + } + public static Bitmap ConvertHImageToRGBBitmap(this HObject hImage) + { + try + { + HOperatorSet.GetImagePointer3(hImage, out HTuple pointRed, out HTuple pointGreen, out HTuple pointBlue, out HTuple type, out HTuple width, out HTuple height); + + Bitmap image = new Bitmap(width.I, height.I, PixelFormat.Format24bppRgb); + BitmapData imageData = image.LockBits(new Rectangle(0, 0, width.I, height.I), ImageLockMode.ReadWrite, image.PixelFormat); + + IntPtr pR = (IntPtr)pointRed.D; + IntPtr pG = (IntPtr)pointGreen.D; + IntPtr pB = (IntPtr)pointBlue.D; + + Parallel.For(0, imageData.Height, h => + { + Parallel.For(0, imageData.Width, w => + { + int dest = h * imageData.Stride + w * 3; + int source = h * imageData.Width + w; + + Marshal.WriteByte(imageData.Scan0, dest, Marshal.ReadByte(pB, source)); + Marshal.WriteByte(imageData.Scan0, dest + 1, Marshal.ReadByte(pG, source)); + Marshal.WriteByte(imageData.Scan0, dest + 2, Marshal.ReadByte(pR, source)); + }); + }); + + image.UnlockBits(imageData); + return image; + } + catch (Exception exc) + { + return null; + } + } + } + public class CameraInfor + { + public string userDefinedName { get; set; } //用户定义的名字 + public string serialNumber { get; set; } //序列号 + public string deviceIPAdd { get; set; } //设备IP地址 + public string manufacturerName { get; set; }//制造厂商名 + public string modelName { get; set; } //型号名称 + public string deviceType { get; set; } //型号名称 + public IntPtr pDeviceInfo; //相机句柄 + public float ExposureTime { get; set; } //曝光时间 + public float Gain { get; set; } //增益 + public float ResultingFrameRate { get; set; } //帧率 + public bool isOpenTriggerMode { get; set; } //是否打开触发方式 + } + public class ASCameraParamInfor + { + /// + /// 曝光时间 + /// + public float ExposureTime { get; set; } + /// + /// 增益 + /// + public float Gain { get; set; } + /// + /// 获取帧率 + /// + public float FrameRate { get; set; } + } + +} diff --git a/HikCameraDriver.cs b/HikCameraDriver.cs new file mode 100644 index 0000000..a8104a5 --- /dev/null +++ b/HikCameraDriver.cs @@ -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; + /// + /// 相机拍照计数 + /// + public volatile int SnapshotCount = 0; + + public Action OnHImageOutput { get; set; } + + public void Init() + { + + //_bufferImgSetQueue = new ConcurrentQueue(); + //_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 _bufferImgSetQueue = new ConcurrentQueue(); + //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 +} + diff --git a/JianZhenQi1.db b/JianZhenQi1.db new file mode 100644 index 0000000..e69de29 diff --git a/LuJiaYi.csproj b/LuJiaYi.csproj new file mode 100644 index 0000000..804bec6 --- /dev/null +++ b/LuJiaYi.csproj @@ -0,0 +1,293 @@ + + + + + + + + + Debug + AnyCPU + {B79451BB-0B27-4B9E-9DFE-2ED254D26903} + WinExe + WindowsFormsApp1 + WindowsFormsApp1 + v4.7.2 + 512 + true + true + + + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + true + false + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + true + bin\x64\Debug\ + DEBUG;TRACE + full + x64 + 7.3 + prompt + false + true + 0 + false + + + bin\x64\Release\ + TRACE + true + pdbonly + x64 + 7.3 + prompt + true + + + + packages\Portable.BouncyCastle.1.9.0\lib\net40\BouncyCastle.Crypto.dll + + + packages\BouncyCastle.Cryptography.2.4.0\lib\net461\BouncyCastle.Cryptography.dll + + + False + bin\x64\Debug\DVPCameraCS64.dll + + + packages\Emgu.CV.4.7.0.5276\lib\netstandard2.0\Emgu.CV.dll + + + packages\EntityFramework.6.4.4\lib\net45\EntityFramework.dll + + + packages\EntityFramework.6.4.4\lib\net45\EntityFramework.SqlServer.dll + + + packages\Google.Protobuf.3.21.9\lib\net45\Google.Protobuf.dll + + + packages\HalconDotNet.19.11.0\lib\net35\halcondotnet.dll + + + packages\HslCommunication.12.0.3\lib\net451\HslCommunication.dll + + + packages\K4os.Compression.LZ4.1.2.16\lib\net46\K4os.Compression.LZ4.dll + + + packages\K4os.Compression.LZ4.Streams.1.2.16\lib\net46\K4os.Compression.LZ4.Streams.dll + + + packages\K4os.Hash.xxHash.1.0.7\lib\net46\K4os.Hash.xxHash.dll + + + packages\Microsoft.Bcl.AsyncInterfaces.8.0.0\lib\net462\Microsoft.Bcl.AsyncInterfaces.dll + + + packages\Microsoft.ML.OnnxRuntime.Managed.1.15.1\lib\netstandard2.0\Microsoft.ML.OnnxRuntime.dll + + + False + bin\x64\Debug\MvCameraControl.Net.dll + + + packages\MySql.Data.8.0.32.1\lib\net452\MySql.Data.dll + + + packages\Newtonsoft.Json.13.0.3\lib\net45\Newtonsoft.Json.dll + + + packages\OpenCvSharp4.4.5.3.20211207\lib\net461\OpenCvSharp.dll + + + packages\OpenCvSharp4.4.5.3.20211207\lib\net461\OpenCvSharp.Extensions.dll + + + False + bin\x64\Debug\picEx.dll + + + packages\SQLitePCLRaw.core.2.1.9\lib\netstandard2.0\SQLitePCLRaw.core.dll + + + + packages\System.Buffers.4.5.1\lib\net461\System.Buffers.dll + + + packages\System.Collections.Immutable.8.0.0\lib\net462\System.Collections.Immutable.dll + + + + + + packages\System.Configuration.ConfigurationManager.4.4.1\lib\net461\System.Configuration.ConfigurationManager.dll + + + + + packages\Stub.System.Data.SQLite.Core.NetFramework.1.0.118.0\lib\net46\System.Data.SQLite.dll + + + packages\System.Data.SQLite.EF6.1.0.118.0\lib\net46\System.Data.SQLite.EF6.dll + + + packages\System.Data.SQLite.Linq.1.0.118.0\lib\net46\System.Data.SQLite.Linq.dll + + + packages\System.Diagnostics.DiagnosticSource.8.0.1\lib\net462\System.Diagnostics.DiagnosticSource.dll + + + packages\System.Drawing.Common.8.0.7\lib\net462\System.Drawing.Common.dll + + + packages\System.Drawing.Primitives.4.3.0\lib\net45\System.Drawing.Primitives.dll + True + True + + + packages\System.IO.Pipelines.6.0.3\lib\net461\System.IO.Pipelines.dll + + + + packages\System.Memory.4.5.5\lib\net461\System.Memory.dll + + + + packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll + + + packages\System.Reflection.Metadata.5.0.0\lib\net461\System.Reflection.Metadata.dll + + + + packages\System.Runtime.CompilerServices.Unsafe.6.0.0\lib\net461\System.Runtime.CompilerServices.Unsafe.dll + + + packages\System.Runtime.Extensions.4.3.1\lib\net462\System.Runtime.Extensions.dll + True + True + + + packages\System.Runtime.InteropServices.RuntimeInformation.4.3.0\lib\net45\System.Runtime.InteropServices.RuntimeInformation.dll + True + True + + + packages\System.Text.Encodings.Web.8.0.0\lib\net462\System.Text.Encodings.Web.dll + + + packages\System.Text.Json.6.0.9\lib\net461\System.Text.Json.dll + + + packages\System.Threading.Tasks.Extensions.4.5.4\lib\net461\System.Threading.Tasks.Extensions.dll + + + + packages\System.ValueTuple.4.5.0\lib\net47\System.ValueTuple.dll + + + + + + + + + + + + packages\ZstdSharp.Port.0.6.5\lib\net461\ZstdSharp.dll + + + + + + + + + + + + + + + + + + + + Form + + + MainForm.cs + + + + + MainForm.cs + + + ResXFileCodeGenerator + Resources.Designer.cs + Designer + + + True + Resources.resx + + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + True + Settings.settings + True + + + + + + + + + + + + 这台计算机上缺少此项目引用的 NuGet 程序包。使用“NuGet 程序包还原”可下载这些程序包。有关更多信息,请参见 http://go.microsoft.com/fwlink/?LinkID=322105。缺少的文件是 {0}。 + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/LuJiaYi.sln b/LuJiaYi.sln new file mode 100644 index 0000000..92450f6 --- /dev/null +++ b/LuJiaYi.sln @@ -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 diff --git a/MGSCameraDriver.cs b/MGSCameraDriver.cs new file mode 100644 index 0000000..b8cf1a8 --- /dev/null +++ b/MGSCameraDriver.cs @@ -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; + + /// + /// 相机拍照计数 + /// + public volatile int SnapshotCount = 0; + + + /// + /// 当前相机的配置 + /// + + + 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; + } + /// + /// 获取曝光 + /// + /// + 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; + } + /// + /// 获取增益 + /// + /// + 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 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; + /// + /// 设置曝光值 + /// + /// 曝光值 + /// + 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}"); + } + } + } + + + /// + /// 设置增益 + /// + /// + /// + 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) + { + } + + + + } + + + + + + + /// + /// 回调函数 + /// + /// + /// + /// + /// + /// + /// + 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 + + + + +} + diff --git a/MLResultDisplay.cs b/MLResultDisplay.cs new file mode 100644 index 0000000..01e31fd --- /dev/null +++ b/MLResultDisplay.cs @@ -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 mlResultList = null; + public List 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 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 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})"; + } + + + } +} diff --git a/MainForm.Designer.cs b/MainForm.Designer.cs new file mode 100644 index 0000000..bc22d6f --- /dev/null +++ b/MainForm.Designer.cs @@ -0,0 +1,1547 @@ +namespace WindowsFormsApp1 +{ + partial class MainForm + { + /// + /// 必需的设计器变量。 + /// + private System.ComponentModel.IContainer components = null; + + /// + /// 清理所有正在使用的资源。 + /// + /// 如果应释放托管资源,为 true;否则为 false。 + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows 窗体设计器生成的代码 + + /// + /// 设计器支持所需的方法 - 不要修改 + /// 使用代码编辑器修改此方法的内容。 + /// + private void InitializeComponent() + { + this.tabControl1 = new System.Windows.Forms.TabControl(); + this.tabPage1 = new System.Windows.Forms.TabPage(); + this.panel1 = new System.Windows.Forms.Panel(); + this.groupBox3 = new System.Windows.Forms.GroupBox(); + this.groupBox13 = new System.Windows.Forms.GroupBox(); + this.groupBox22 = new System.Windows.Forms.GroupBox(); + this.textBox24 = new System.Windows.Forms.TextBox(); + this.label34 = new System.Windows.Forms.Label(); + this.label35 = new System.Windows.Forms.Label(); + this.textBox25 = new System.Windows.Forms.TextBox(); + this.label36 = new System.Windows.Forms.Label(); + this.textBox26 = new System.Windows.Forms.TextBox(); + this.label38 = new System.Windows.Forms.Label(); + this.textBox28 = new System.Windows.Forms.TextBox(); + this.groupBox21 = new System.Windows.Forms.GroupBox(); + this.textBox27 = new System.Windows.Forms.TextBox(); + this.label37 = new System.Windows.Forms.Label(); + this.label2 = new System.Windows.Forms.Label(); + this.textBox3 = new System.Windows.Forms.TextBox(); + this.label3 = new System.Windows.Forms.Label(); + this.textBox2 = new System.Windows.Forms.TextBox(); + this.label4 = new System.Windows.Forms.Label(); + this.textBox1 = new System.Windows.Forms.TextBox(); + this.groupBox12 = new System.Windows.Forms.GroupBox(); + this.comboBox2 = new System.Windows.Forms.ComboBox(); + this.comboBox1 = new System.Windows.Forms.ComboBox(); + this.label33 = new System.Windows.Forms.Label(); + this.label32 = new System.Windows.Forms.Label(); + this.button2 = new System.Windows.Forms.Button(); + this.button1 = new System.Windows.Forms.Button(); + this.Diary = new System.Windows.Forms.GroupBox(); + this.richTextBox1 = new System.Windows.Forms.RichTextBox(); + this.groupBox9 = new System.Windows.Forms.GroupBox(); + this.panel6 = new System.Windows.Forms.Panel(); + this.pictureBox4 = new picEx.UserControl1(); + this.groupBox20 = new System.Windows.Forms.GroupBox(); + this.pictureBox8 = new System.Windows.Forms.PictureBox(); + this.groupBox16 = new System.Windows.Forms.GroupBox(); + this.textBox23 = new System.Windows.Forms.TextBox(); + this.textBox20 = new System.Windows.Forms.TextBox(); + this.label26 = new System.Windows.Forms.Label(); + this.textBox21 = new System.Windows.Forms.TextBox(); + this.label27 = new System.Windows.Forms.Label(); + this.label28 = new System.Windows.Forms.Label(); + this.textBox22 = new System.Windows.Forms.TextBox(); + this.label29 = new System.Windows.Forms.Label(); + this.label30 = new System.Windows.Forms.Label(); + this.label31 = new System.Windows.Forms.Label(); + this.groupBox8 = new System.Windows.Forms.GroupBox(); + this.panel5 = new System.Windows.Forms.Panel(); + this.pictureBox2 = new picEx.UserControl1(); + this.groupBox19 = new System.Windows.Forms.GroupBox(); + this.pictureBox7 = new System.Windows.Forms.PictureBox(); + this.groupBox15 = new System.Windows.Forms.GroupBox(); + this.textBox19 = new System.Windows.Forms.TextBox(); + this.textBox16 = new System.Windows.Forms.TextBox(); + this.label20 = new System.Windows.Forms.Label(); + this.textBox17 = new System.Windows.Forms.TextBox(); + this.label21 = new System.Windows.Forms.Label(); + this.label22 = new System.Windows.Forms.Label(); + this.textBox18 = new System.Windows.Forms.TextBox(); + this.label23 = new System.Windows.Forms.Label(); + this.label24 = new System.Windows.Forms.Label(); + this.label25 = new System.Windows.Forms.Label(); + this.groupBox5 = new System.Windows.Forms.GroupBox(); + this.panel4 = new System.Windows.Forms.Panel(); + this.pictureBox3 = new picEx.UserControl1(); + this.groupBox18 = new System.Windows.Forms.GroupBox(); + this.pictureBox6 = new System.Windows.Forms.PictureBox(); + this.groupBox14 = new System.Windows.Forms.GroupBox(); + this.textBox15 = new System.Windows.Forms.TextBox(); + this.textBox12 = new System.Windows.Forms.TextBox(); + this.label14 = new System.Windows.Forms.Label(); + this.textBox13 = new System.Windows.Forms.TextBox(); + this.label15 = new System.Windows.Forms.Label(); + this.label16 = new System.Windows.Forms.Label(); + this.textBox14 = new System.Windows.Forms.TextBox(); + this.label17 = new System.Windows.Forms.Label(); + this.label18 = new System.Windows.Forms.Label(); + this.label19 = new System.Windows.Forms.Label(); + this.groupBox4 = new System.Windows.Forms.GroupBox(); + this.panel3 = new System.Windows.Forms.Panel(); + this.pictureBox1 = new picEx.UserControl1(); + this.groupBox17 = new System.Windows.Forms.GroupBox(); + this.pictureBox5 = new System.Windows.Forms.PictureBox(); + this.groupBox11 = new System.Windows.Forms.GroupBox(); + this.textBox4 = new System.Windows.Forms.TextBox(); + this.textBox11 = new System.Windows.Forms.TextBox(); + this.label13 = new System.Windows.Forms.Label(); + this.textBox6 = new System.Windows.Forms.TextBox(); + this.label7 = new System.Windows.Forms.Label(); + this.label8 = new System.Windows.Forms.Label(); + this.textBox5 = new System.Windows.Forms.TextBox(); + this.label6 = new System.Windows.Forms.Label(); + this.label5 = new System.Windows.Forms.Label(); + this.label1 = new System.Windows.Forms.Label(); + this.tabPage2 = new System.Windows.Forms.TabPage(); + this.groupBox2 = new System.Windows.Forms.GroupBox(); + this.richTextBox2 = new System.Windows.Forms.RichTextBox(); + this.groupBox1 = new System.Windows.Forms.GroupBox(); + this.dataGridView1 = new System.Windows.Forms.DataGridView(); + this.groupBox10 = new System.Windows.Forms.GroupBox(); + this.button6 = new System.Windows.Forms.Button(); + this.button4 = new System.Windows.Forms.Button(); + this.button5 = new System.Windows.Forms.Button(); + this.groupBox6 = new System.Windows.Forms.GroupBox(); + this.textBox10 = new System.Windows.Forms.TextBox(); + this.label12 = new System.Windows.Forms.Label(); + this.textBox9 = new System.Windows.Forms.TextBox(); + this.label11 = new System.Windows.Forms.Label(); + this.checkBox1 = new System.Windows.Forms.CheckBox(); + this.textBox8 = new System.Windows.Forms.TextBox(); + this.label10 = new System.Windows.Forms.Label(); + this.textBox7 = new System.Windows.Forms.TextBox(); + this.label9 = new System.Windows.Forms.Label(); + this.groupBox7 = new System.Windows.Forms.GroupBox(); + this.panel2 = new System.Windows.Forms.Panel(); + this.userControl11 = new picEx.UserControl1(); + this.button3 = new System.Windows.Forms.Button(); + this.tabControl1.SuspendLayout(); + this.tabPage1.SuspendLayout(); + this.panel1.SuspendLayout(); + this.groupBox3.SuspendLayout(); + this.groupBox13.SuspendLayout(); + this.groupBox22.SuspendLayout(); + this.groupBox21.SuspendLayout(); + this.groupBox12.SuspendLayout(); + this.Diary.SuspendLayout(); + this.groupBox9.SuspendLayout(); + this.panel6.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.pictureBox4)).BeginInit(); + this.groupBox20.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.pictureBox8)).BeginInit(); + this.groupBox16.SuspendLayout(); + this.groupBox8.SuspendLayout(); + this.panel5.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.pictureBox2)).BeginInit(); + this.groupBox19.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.pictureBox7)).BeginInit(); + this.groupBox15.SuspendLayout(); + this.groupBox5.SuspendLayout(); + this.panel4.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.pictureBox3)).BeginInit(); + this.groupBox18.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.pictureBox6)).BeginInit(); + this.groupBox14.SuspendLayout(); + this.groupBox4.SuspendLayout(); + this.panel3.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit(); + this.groupBox17.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.pictureBox5)).BeginInit(); + this.groupBox11.SuspendLayout(); + this.tabPage2.SuspendLayout(); + this.groupBox2.SuspendLayout(); + this.groupBox1.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).BeginInit(); + this.groupBox10.SuspendLayout(); + this.groupBox6.SuspendLayout(); + this.groupBox7.SuspendLayout(); + this.panel2.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.userControl11)).BeginInit(); + this.SuspendLayout(); + // + // tabControl1 + // + this.tabControl1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.tabControl1.Appearance = System.Windows.Forms.TabAppearance.Buttons; + this.tabControl1.Controls.Add(this.tabPage1); + this.tabControl1.Controls.Add(this.tabPage2); + this.tabControl1.Font = new System.Drawing.Font("宋体", 10.5F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + this.tabControl1.Location = new System.Drawing.Point(2, 3); + this.tabControl1.Name = "tabControl1"; + this.tabControl1.SelectedIndex = 0; + this.tabControl1.Size = new System.Drawing.Size(1178, 835); + this.tabControl1.TabIndex = 0; + // + // tabPage1 + // + this.tabPage1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; + this.tabPage1.Controls.Add(this.panel1); + this.tabPage1.Location = new System.Drawing.Point(4, 27); + this.tabPage1.Name = "tabPage1"; + this.tabPage1.Padding = new System.Windows.Forms.Padding(3); + this.tabPage1.Size = new System.Drawing.Size(1170, 804); + this.tabPage1.TabIndex = 0; + this.tabPage1.Text = "主界面"; + // + // panel1 + // + this.panel1.Controls.Add(this.groupBox3); + this.panel1.Location = new System.Drawing.Point(-1, -1); + this.panel1.Name = "panel1"; + this.panel1.Size = new System.Drawing.Size(1170, 804); + this.panel1.TabIndex = 0; + // + // groupBox3 + // + this.groupBox3.Controls.Add(this.groupBox13); + this.groupBox3.Controls.Add(this.groupBox12); + this.groupBox3.Controls.Add(this.Diary); + this.groupBox3.Controls.Add(this.groupBox9); + this.groupBox3.Controls.Add(this.groupBox8); + this.groupBox3.Controls.Add(this.groupBox5); + this.groupBox3.Controls.Add(this.groupBox4); + this.groupBox3.Font = new System.Drawing.Font("宋体", 10.5F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + this.groupBox3.Location = new System.Drawing.Point(0, 3); + this.groupBox3.Name = "groupBox3"; + this.groupBox3.Size = new System.Drawing.Size(1170, 801); + this.groupBox3.TabIndex = 7; + this.groupBox3.TabStop = false; + this.groupBox3.Text = "图像显示"; + // + // groupBox13 + // + this.groupBox13.Controls.Add(this.groupBox22); + this.groupBox13.Controls.Add(this.groupBox21); + this.groupBox13.Font = new System.Drawing.Font("宋体", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + this.groupBox13.Location = new System.Drawing.Point(876, 368); + this.groupBox13.Name = "groupBox13"; + this.groupBox13.Size = new System.Drawing.Size(288, 306); + this.groupBox13.TabIndex = 4; + this.groupBox13.TabStop = false; + this.groupBox13.Text = "生产信息"; + // + // groupBox22 + // + this.groupBox22.Controls.Add(this.textBox24); + this.groupBox22.Controls.Add(this.label34); + this.groupBox22.Controls.Add(this.label35); + this.groupBox22.Controls.Add(this.textBox25); + this.groupBox22.Controls.Add(this.label36); + this.groupBox22.Controls.Add(this.textBox26); + this.groupBox22.Controls.Add(this.label38); + this.groupBox22.Controls.Add(this.textBox28); + this.groupBox22.Location = new System.Drawing.Point(163, 51); + this.groupBox22.Name = "groupBox22"; + this.groupBox22.Size = new System.Drawing.Size(119, 196); + this.groupBox22.TabIndex = 8; + this.groupBox22.TabStop = false; + this.groupBox22.Text = "类型二"; + // + // textBox24 + // + this.textBox24.Location = new System.Drawing.Point(68, 158); + this.textBox24.Name = "textBox24"; + this.textBox24.Size = new System.Drawing.Size(47, 26); + this.textBox24.TabIndex = 7; + // + // label34 + // + this.label34.AutoSize = true; + this.label34.Font = new System.Drawing.Font("宋体", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + this.label34.Location = new System.Drawing.Point(6, 162); + this.label34.Name = "label34"; + this.label34.Size = new System.Drawing.Size(55, 16); + this.label34.TabIndex = 6; + this.label34.Text = "不良率"; + // + // label35 + // + this.label35.AutoSize = true; + this.label35.Font = new System.Drawing.Font("宋体", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + this.label35.Location = new System.Drawing.Point(6, 28); + this.label35.Name = "label35"; + this.label35.Size = new System.Drawing.Size(55, 16); + this.label35.TabIndex = 0; + this.label35.Text = "总产量"; + // + // textBox25 + // + this.textBox25.Location = new System.Drawing.Point(68, 114); + this.textBox25.Name = "textBox25"; + this.textBox25.Size = new System.Drawing.Size(47, 26); + this.textBox25.TabIndex = 5; + // + // label36 + // + this.label36.AutoSize = true; + this.label36.Font = new System.Drawing.Font("宋体", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + this.label36.Location = new System.Drawing.Point(14, 74); + this.label36.Name = "label36"; + this.label36.Size = new System.Drawing.Size(39, 16); + this.label36.TabIndex = 1; + this.label36.Text = "OK数"; + // + // textBox26 + // + this.textBox26.Location = new System.Drawing.Point(68, 69); + this.textBox26.Name = "textBox26"; + this.textBox26.Size = new System.Drawing.Size(47, 26); + this.textBox26.TabIndex = 4; + // + // label38 + // + this.label38.AutoSize = true; + this.label38.Font = new System.Drawing.Font("宋体", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + this.label38.Location = new System.Drawing.Point(15, 119); + this.label38.Name = "label38"; + this.label38.Size = new System.Drawing.Size(39, 16); + this.label38.TabIndex = 2; + this.label38.Text = "NG数"; + // + // textBox28 + // + this.textBox28.Location = new System.Drawing.Point(68, 22); + this.textBox28.Name = "textBox28"; + this.textBox28.Size = new System.Drawing.Size(47, 26); + this.textBox28.TabIndex = 3; + // + // groupBox21 + // + this.groupBox21.Controls.Add(this.textBox27); + this.groupBox21.Controls.Add(this.label37); + this.groupBox21.Controls.Add(this.label2); + this.groupBox21.Controls.Add(this.textBox3); + this.groupBox21.Controls.Add(this.label3); + this.groupBox21.Controls.Add(this.textBox2); + this.groupBox21.Controls.Add(this.label4); + this.groupBox21.Controls.Add(this.textBox1); + this.groupBox21.Location = new System.Drawing.Point(15, 51); + this.groupBox21.Name = "groupBox21"; + this.groupBox21.Size = new System.Drawing.Size(119, 196); + this.groupBox21.TabIndex = 6; + this.groupBox21.TabStop = false; + this.groupBox21.Text = "类型一"; + // + // textBox27 + // + this.textBox27.Location = new System.Drawing.Point(68, 158); + this.textBox27.Name = "textBox27"; + this.textBox27.Size = new System.Drawing.Size(47, 26); + this.textBox27.TabIndex = 7; + // + // label37 + // + this.label37.AutoSize = true; + this.label37.Font = new System.Drawing.Font("宋体", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + this.label37.Location = new System.Drawing.Point(6, 162); + this.label37.Name = "label37"; + this.label37.Size = new System.Drawing.Size(55, 16); + this.label37.TabIndex = 6; + this.label37.Text = "不良率"; + // + // label2 + // + this.label2.AutoSize = true; + this.label2.Font = new System.Drawing.Font("宋体", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + this.label2.Location = new System.Drawing.Point(6, 28); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(55, 16); + this.label2.TabIndex = 0; + this.label2.Text = "总产量"; + // + // textBox3 + // + this.textBox3.Location = new System.Drawing.Point(68, 114); + this.textBox3.Name = "textBox3"; + this.textBox3.Size = new System.Drawing.Size(47, 26); + this.textBox3.TabIndex = 5; + // + // label3 + // + this.label3.AutoSize = true; + this.label3.Font = new System.Drawing.Font("宋体", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + this.label3.Location = new System.Drawing.Point(14, 74); + this.label3.Name = "label3"; + this.label3.Size = new System.Drawing.Size(39, 16); + this.label3.TabIndex = 1; + this.label3.Text = "OK数"; + // + // textBox2 + // + this.textBox2.Location = new System.Drawing.Point(68, 69); + this.textBox2.Name = "textBox2"; + this.textBox2.Size = new System.Drawing.Size(47, 26); + this.textBox2.TabIndex = 4; + // + // label4 + // + this.label4.AutoSize = true; + this.label4.Font = new System.Drawing.Font("宋体", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + this.label4.Location = new System.Drawing.Point(15, 119); + this.label4.Name = "label4"; + this.label4.Size = new System.Drawing.Size(39, 16); + this.label4.TabIndex = 2; + this.label4.Text = "NG数"; + // + // textBox1 + // + this.textBox1.Location = new System.Drawing.Point(68, 23); + this.textBox1.Name = "textBox1"; + this.textBox1.Size = new System.Drawing.Size(47, 26); + this.textBox1.TabIndex = 3; + // + // groupBox12 + // + this.groupBox12.Controls.Add(this.button3); + this.groupBox12.Controls.Add(this.comboBox2); + this.groupBox12.Controls.Add(this.comboBox1); + this.groupBox12.Controls.Add(this.label33); + this.groupBox12.Controls.Add(this.label32); + this.groupBox12.Controls.Add(this.button2); + this.groupBox12.Controls.Add(this.button1); + this.groupBox12.Font = new System.Drawing.Font("宋体", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + this.groupBox12.Location = new System.Drawing.Point(876, 22); + this.groupBox12.Name = "groupBox12"; + this.groupBox12.Size = new System.Drawing.Size(287, 316); + this.groupBox12.TabIndex = 9; + this.groupBox12.TabStop = false; + this.groupBox12.Text = "更改型号"; + // + // comboBox2 + // + this.comboBox2.FormattingEnabled = true; + this.comboBox2.Location = new System.Drawing.Point(110, 238); + this.comboBox2.Name = "comboBox2"; + this.comboBox2.Size = new System.Drawing.Size(166, 24); + this.comboBox2.TabIndex = 9; + // + // comboBox1 + // + this.comboBox1.FormattingEnabled = true; + this.comboBox1.Location = new System.Drawing.Point(110, 161); + this.comboBox1.Name = "comboBox1"; + this.comboBox1.Size = new System.Drawing.Size(166, 24); + this.comboBox1.TabIndex = 8; + // + // label33 + // + this.label33.AutoSize = true; + this.label33.Font = new System.Drawing.Font("宋体", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + this.label33.Location = new System.Drawing.Point(12, 241); + this.label33.Name = "label33"; + this.label33.Size = new System.Drawing.Size(79, 16); + this.label33.TabIndex = 7; + this.label33.Text = "产品型号2"; + // + // label32 + // + this.label32.AutoSize = true; + this.label32.Font = new System.Drawing.Font("宋体", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + this.label32.Location = new System.Drawing.Point(12, 163); + this.label32.Name = "label32"; + this.label32.Size = new System.Drawing.Size(79, 16); + this.label32.TabIndex = 6; + this.label32.Text = "产品型号1"; + // + // button2 + // + this.button2.Location = new System.Drawing.Point(108, 47); + this.button2.Name = "button2"; + this.button2.Size = new System.Drawing.Size(79, 47); + this.button2.TabIndex = 1; + this.button2.Text = "开始检测"; + this.button2.UseVisualStyleBackColor = true; + this.button2.Click += new System.EventHandler(this.button2_Click_1); + // + // button1 + // + this.button1.Location = new System.Drawing.Point(7, 47); + this.button1.Name = "button1"; + this.button1.Size = new System.Drawing.Size(84, 47); + this.button1.TabIndex = 0; + this.button1.Text = "启动设备"; + this.button1.UseVisualStyleBackColor = true; + this.button1.Click += new System.EventHandler(this.button1_Click_1); + // + // Diary + // + this.Diary.Controls.Add(this.richTextBox1); + this.Diary.Location = new System.Drawing.Point(20, 680); + this.Diary.Name = "Diary"; + this.Diary.Size = new System.Drawing.Size(1147, 121); + this.Diary.TabIndex = 8; + this.Diary.TabStop = false; + this.Diary.Text = "日志"; + // + // richTextBox1 + // + this.richTextBox1.Location = new System.Drawing.Point(6, 18); + this.richTextBox1.Name = "richTextBox1"; + this.richTextBox1.Size = new System.Drawing.Size(1135, 96); + this.richTextBox1.TabIndex = 0; + this.richTextBox1.Text = ""; + // + // groupBox9 + // + this.groupBox9.Controls.Add(this.panel6); + this.groupBox9.Controls.Add(this.groupBox20); + this.groupBox9.Controls.Add(this.groupBox16); + this.groupBox9.Font = new System.Drawing.Font("宋体", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + this.groupBox9.Location = new System.Drawing.Point(462, 359); + this.groupBox9.Name = "groupBox9"; + this.groupBox9.Size = new System.Drawing.Size(393, 315); + this.groupBox9.TabIndex = 7; + this.groupBox9.TabStop = false; + this.groupBox9.Text = "产线4"; + // + // panel6 + // + this.panel6.Controls.Add(this.pictureBox4); + this.panel6.Location = new System.Drawing.Point(4, 19); + this.panel6.Name = "panel6"; + this.panel6.Size = new System.Drawing.Size(238, 296); + this.panel6.TabIndex = 17; + // + // pictureBox4 + // + this.pictureBox4.Location = new System.Drawing.Point(3, 4); + this.pictureBox4.Name = "pictureBox4"; + this.pictureBox4.Size = new System.Drawing.Size(232, 289); + this.pictureBox4.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom; + this.pictureBox4.TabIndex = 3; + this.pictureBox4.TabStop = false; + // + // groupBox20 + // + this.groupBox20.Controls.Add(this.pictureBox8); + this.groupBox20.Location = new System.Drawing.Point(248, 195); + this.groupBox20.Name = "groupBox20"; + this.groupBox20.Size = new System.Drawing.Size(136, 118); + this.groupBox20.TabIndex = 3; + this.groupBox20.TabStop = false; + this.groupBox20.Text = "检测结果"; + // + // pictureBox8 + // + this.pictureBox8.Location = new System.Drawing.Point(27, 25); + this.pictureBox8.Name = "pictureBox8"; + this.pictureBox8.Size = new System.Drawing.Size(86, 87); + this.pictureBox8.TabIndex = 3; + this.pictureBox8.TabStop = false; + // + // groupBox16 + // + this.groupBox16.Controls.Add(this.textBox23); + this.groupBox16.Controls.Add(this.textBox20); + this.groupBox16.Controls.Add(this.label26); + this.groupBox16.Controls.Add(this.textBox21); + this.groupBox16.Controls.Add(this.label27); + this.groupBox16.Controls.Add(this.label28); + this.groupBox16.Controls.Add(this.textBox22); + this.groupBox16.Controls.Add(this.label29); + this.groupBox16.Controls.Add(this.label30); + this.groupBox16.Controls.Add(this.label31); + this.groupBox16.Location = new System.Drawing.Point(248, 15); + this.groupBox16.Name = "groupBox16"; + this.groupBox16.Size = new System.Drawing.Size(136, 174); + this.groupBox16.TabIndex = 16; + this.groupBox16.TabStop = false; + this.groupBox16.Text = "产品信息"; + // + // textBox23 + // + this.textBox23.Location = new System.Drawing.Point(9, 45); + this.textBox23.Name = "textBox23"; + this.textBox23.Size = new System.Drawing.Size(121, 26); + this.textBox23.TabIndex = 18; + // + // textBox20 + // + this.textBox20.Location = new System.Drawing.Point(81, 143); + this.textBox20.Name = "textBox20"; + this.textBox20.Size = new System.Drawing.Size(49, 26); + this.textBox20.TabIndex = 14; + // + // label26 + // + this.label26.AutoSize = true; + this.label26.Location = new System.Drawing.Point(13, 148); + this.label26.Name = "label26"; + this.label26.Size = new System.Drawing.Size(55, 16); + this.label26.TabIndex = 13; + this.label26.Text = "螺丝孔"; + // + // textBox21 + // + this.textBox21.Location = new System.Drawing.Point(81, 109); + this.textBox21.Name = "textBox21"; + this.textBox21.Size = new System.Drawing.Size(49, 26); + this.textBox21.TabIndex = 12; + // + // label27 + // + this.label27.AutoSize = true; + this.label27.Location = new System.Drawing.Point(16, 115); + this.label27.Name = "label27"; + this.label27.Size = new System.Drawing.Size(39, 16); + this.label27.TabIndex = 11; + this.label27.Text = "距离"; + // + // label28 + // + this.label28.AutoSize = true; + this.label28.Location = new System.Drawing.Point(6, 175); + this.label28.Name = "label28"; + this.label28.Size = new System.Drawing.Size(0, 16); + this.label28.TabIndex = 10; + // + // textBox22 + // + this.textBox22.Location = new System.Drawing.Point(81, 78); + this.textBox22.Name = "textBox22"; + this.textBox22.Size = new System.Drawing.Size(49, 26); + this.textBox22.TabIndex = 9; + // + // label29 + // + this.label29.AutoSize = true; + this.label29.Location = new System.Drawing.Point(5, 84); + this.label29.Name = "label29"; + this.label29.Size = new System.Drawing.Size(71, 16); + this.label29.TabIndex = 8; + this.label29.Text = "金属圈数"; + // + // label30 + // + this.label30.AutoSize = true; + this.label30.Location = new System.Drawing.Point(6, 123); + this.label30.Name = "label30"; + this.label30.Size = new System.Drawing.Size(0, 16); + this.label30.TabIndex = 7; + // + // label31 + // + this.label31.AutoSize = true; + this.label31.Location = new System.Drawing.Point(11, 22); + this.label31.Name = "label31"; + this.label31.Size = new System.Drawing.Size(39, 16); + this.label31.TabIndex = 0; + this.label31.Text = "型号"; + // + // groupBox8 + // + this.groupBox8.Controls.Add(this.panel5); + this.groupBox8.Controls.Add(this.groupBox19); + this.groupBox8.Controls.Add(this.groupBox15); + this.groupBox8.Font = new System.Drawing.Font("宋体", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + this.groupBox8.Location = new System.Drawing.Point(20, 359); + this.groupBox8.Name = "groupBox8"; + this.groupBox8.Size = new System.Drawing.Size(419, 315); + this.groupBox8.TabIndex = 6; + this.groupBox8.TabStop = false; + this.groupBox8.Text = "产线3"; + // + // panel5 + // + this.panel5.Controls.Add(this.pictureBox2); + this.panel5.Location = new System.Drawing.Point(10, 19); + this.panel5.Name = "panel5"; + this.panel5.Size = new System.Drawing.Size(245, 294); + this.panel5.TabIndex = 5; + // + // pictureBox2 + // + this.pictureBox2.Location = new System.Drawing.Point(3, 4); + this.pictureBox2.Name = "pictureBox2"; + this.pictureBox2.Size = new System.Drawing.Size(239, 287); + this.pictureBox2.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom; + this.pictureBox2.TabIndex = 1; + this.pictureBox2.TabStop = false; + // + // groupBox19 + // + this.groupBox19.Controls.Add(this.pictureBox7); + this.groupBox19.Location = new System.Drawing.Point(261, 195); + this.groupBox19.Name = "groupBox19"; + this.groupBox19.Size = new System.Drawing.Size(124, 118); + this.groupBox19.TabIndex = 3; + this.groupBox19.TabStop = false; + this.groupBox19.Text = "检测结果"; + // + // pictureBox7 + // + this.pictureBox7.Location = new System.Drawing.Point(17, 25); + this.pictureBox7.Name = "pictureBox7"; + this.pictureBox7.Size = new System.Drawing.Size(86, 87); + this.pictureBox7.TabIndex = 2; + this.pictureBox7.TabStop = false; + // + // groupBox15 + // + this.groupBox15.Controls.Add(this.textBox19); + this.groupBox15.Controls.Add(this.textBox16); + this.groupBox15.Controls.Add(this.label20); + this.groupBox15.Controls.Add(this.textBox17); + this.groupBox15.Controls.Add(this.label21); + this.groupBox15.Controls.Add(this.label22); + this.groupBox15.Controls.Add(this.textBox18); + this.groupBox15.Controls.Add(this.label23); + this.groupBox15.Controls.Add(this.label24); + this.groupBox15.Controls.Add(this.label25); + this.groupBox15.Location = new System.Drawing.Point(261, 11); + this.groupBox15.Name = "groupBox15"; + this.groupBox15.Size = new System.Drawing.Size(137, 178); + this.groupBox15.TabIndex = 4; + this.groupBox15.TabStop = false; + this.groupBox15.Text = "产品信息"; + // + // textBox19 + // + this.textBox19.Location = new System.Drawing.Point(6, 45); + this.textBox19.Name = "textBox19"; + this.textBox19.Size = new System.Drawing.Size(125, 26); + this.textBox19.TabIndex = 17; + // + // textBox16 + // + this.textBox16.Location = new System.Drawing.Point(82, 147); + this.textBox16.Name = "textBox16"; + this.textBox16.Size = new System.Drawing.Size(49, 26); + this.textBox16.TabIndex = 14; + // + // label20 + // + this.label20.AutoSize = true; + this.label20.Location = new System.Drawing.Point(14, 151); + this.label20.Name = "label20"; + this.label20.Size = new System.Drawing.Size(55, 16); + this.label20.TabIndex = 13; + this.label20.Text = "螺丝孔"; + // + // textBox17 + // + this.textBox17.Location = new System.Drawing.Point(82, 112); + this.textBox17.Name = "textBox17"; + this.textBox17.Size = new System.Drawing.Size(49, 26); + this.textBox17.TabIndex = 12; + // + // label21 + // + this.label21.AutoSize = true; + this.label21.Location = new System.Drawing.Point(17, 119); + this.label21.Name = "label21"; + this.label21.Size = new System.Drawing.Size(39, 16); + this.label21.TabIndex = 11; + this.label21.Text = "距离"; + // + // label22 + // + this.label22.AutoSize = true; + this.label22.Location = new System.Drawing.Point(6, 175); + this.label22.Name = "label22"; + this.label22.Size = new System.Drawing.Size(0, 16); + this.label22.TabIndex = 10; + // + // textBox18 + // + this.textBox18.Location = new System.Drawing.Point(82, 77); + this.textBox18.Name = "textBox18"; + this.textBox18.Size = new System.Drawing.Size(49, 26); + this.textBox18.TabIndex = 9; + // + // label23 + // + this.label23.AutoSize = true; + this.label23.Location = new System.Drawing.Point(6, 84); + this.label23.Name = "label23"; + this.label23.Size = new System.Drawing.Size(71, 16); + this.label23.TabIndex = 8; + this.label23.Text = "金属圈数"; + // + // label24 + // + this.label24.AutoSize = true; + this.label24.Location = new System.Drawing.Point(6, 123); + this.label24.Name = "label24"; + this.label24.Size = new System.Drawing.Size(0, 16); + this.label24.TabIndex = 7; + // + // label25 + // + this.label25.AutoSize = true; + this.label25.Location = new System.Drawing.Point(11, 22); + this.label25.Name = "label25"; + this.label25.Size = new System.Drawing.Size(39, 16); + this.label25.TabIndex = 0; + this.label25.Text = "型号"; + // + // groupBox5 + // + this.groupBox5.Controls.Add(this.panel4); + this.groupBox5.Controls.Add(this.groupBox18); + this.groupBox5.Controls.Add(this.groupBox14); + this.groupBox5.Font = new System.Drawing.Font("宋体", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + this.groupBox5.Location = new System.Drawing.Point(462, 22); + this.groupBox5.Name = "groupBox5"; + this.groupBox5.Size = new System.Drawing.Size(393, 316); + this.groupBox5.TabIndex = 5; + this.groupBox5.TabStop = false; + this.groupBox5.Text = " 产线2"; + this.groupBox5.Enter += new System.EventHandler(this.groupBox5_Enter); + // + // panel4 + // + this.panel4.Controls.Add(this.pictureBox3); + this.panel4.Location = new System.Drawing.Point(6, 22); + this.panel4.Name = "panel4"; + this.panel4.Size = new System.Drawing.Size(237, 288); + this.panel4.TabIndex = 16; + // + // pictureBox3 + // + this.pictureBox3.Location = new System.Drawing.Point(0, 0); + this.pictureBox3.Name = "pictureBox3"; + this.pictureBox3.Size = new System.Drawing.Size(234, 288); + this.pictureBox3.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom; + this.pictureBox3.TabIndex = 2; + this.pictureBox3.TabStop = false; + // + // groupBox18 + // + this.groupBox18.Controls.Add(this.pictureBox6); + this.groupBox18.Location = new System.Drawing.Point(248, 192); + this.groupBox18.Name = "groupBox18"; + this.groupBox18.Size = new System.Drawing.Size(136, 121); + this.groupBox18.TabIndex = 3; + this.groupBox18.TabStop = false; + this.groupBox18.Text = "检测结果"; + // + // pictureBox6 + // + this.pictureBox6.Location = new System.Drawing.Point(27, 25); + this.pictureBox6.Name = "pictureBox6"; + this.pictureBox6.Size = new System.Drawing.Size(86, 87); + this.pictureBox6.TabIndex = 1; + this.pictureBox6.TabStop = false; + // + // groupBox14 + // + this.groupBox14.Controls.Add(this.textBox15); + this.groupBox14.Controls.Add(this.textBox12); + this.groupBox14.Controls.Add(this.label14); + this.groupBox14.Controls.Add(this.textBox13); + this.groupBox14.Controls.Add(this.label15); + this.groupBox14.Controls.Add(this.label16); + this.groupBox14.Controls.Add(this.textBox14); + this.groupBox14.Controls.Add(this.label17); + this.groupBox14.Controls.Add(this.label18); + this.groupBox14.Controls.Add(this.label19); + this.groupBox14.Location = new System.Drawing.Point(248, 12); + this.groupBox14.Name = "groupBox14"; + this.groupBox14.Size = new System.Drawing.Size(136, 177); + this.groupBox14.TabIndex = 15; + this.groupBox14.TabStop = false; + this.groupBox14.Text = "产品信息"; + // + // textBox15 + // + this.textBox15.Location = new System.Drawing.Point(9, 45); + this.textBox15.Name = "textBox15"; + this.textBox15.Size = new System.Drawing.Size(116, 26); + this.textBox15.TabIndex = 16; + // + // textBox12 + // + this.textBox12.Location = new System.Drawing.Point(76, 145); + this.textBox12.Name = "textBox12"; + this.textBox12.Size = new System.Drawing.Size(49, 26); + this.textBox12.TabIndex = 14; + // + // label14 + // + this.label14.AutoSize = true; + this.label14.Location = new System.Drawing.Point(8, 150); + this.label14.Name = "label14"; + this.label14.Size = new System.Drawing.Size(55, 16); + this.label14.TabIndex = 13; + this.label14.Text = "螺丝孔"; + // + // textBox13 + // + this.textBox13.Location = new System.Drawing.Point(76, 112); + this.textBox13.Name = "textBox13"; + this.textBox13.Size = new System.Drawing.Size(49, 26); + this.textBox13.TabIndex = 12; + // + // label15 + // + this.label15.AutoSize = true; + this.label15.Location = new System.Drawing.Point(11, 117); + this.label15.Name = "label15"; + this.label15.Size = new System.Drawing.Size(39, 16); + this.label15.TabIndex = 11; + this.label15.Text = "距离"; + // + // label16 + // + this.label16.AutoSize = true; + this.label16.Location = new System.Drawing.Point(6, 209); + this.label16.Name = "label16"; + this.label16.Size = new System.Drawing.Size(0, 16); + this.label16.TabIndex = 10; + // + // textBox14 + // + this.textBox14.Location = new System.Drawing.Point(76, 76); + this.textBox14.Name = "textBox14"; + this.textBox14.Size = new System.Drawing.Size(49, 26); + this.textBox14.TabIndex = 9; + // + // label17 + // + this.label17.AutoSize = true; + this.label17.Location = new System.Drawing.Point(1, 82); + this.label17.Name = "label17"; + this.label17.Size = new System.Drawing.Size(71, 16); + this.label17.TabIndex = 8; + this.label17.Text = "金属圈数"; + // + // label18 + // + this.label18.AutoSize = true; + this.label18.Location = new System.Drawing.Point(6, 157); + this.label18.Name = "label18"; + this.label18.Size = new System.Drawing.Size(0, 16); + this.label18.TabIndex = 7; + // + // label19 + // + this.label19.AutoSize = true; + this.label19.Location = new System.Drawing.Point(6, 22); + this.label19.Name = "label19"; + this.label19.Size = new System.Drawing.Size(39, 16); + this.label19.TabIndex = 0; + this.label19.Text = "型号"; + // + // groupBox4 + // + this.groupBox4.Controls.Add(this.panel3); + this.groupBox4.Controls.Add(this.groupBox17); + this.groupBox4.Controls.Add(this.groupBox11); + this.groupBox4.Font = new System.Drawing.Font("宋体", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + this.groupBox4.Location = new System.Drawing.Point(20, 22); + this.groupBox4.Name = "groupBox4"; + this.groupBox4.Size = new System.Drawing.Size(419, 316); + this.groupBox4.TabIndex = 4; + this.groupBox4.TabStop = false; + this.groupBox4.Text = "产线1"; + this.groupBox4.Enter += new System.EventHandler(this.groupBox4_Enter); + // + // panel3 + // + this.panel3.Controls.Add(this.pictureBox1); + this.panel3.Location = new System.Drawing.Point(6, 19); + this.panel3.Name = "panel3"; + this.panel3.Size = new System.Drawing.Size(249, 288); + this.panel3.TabIndex = 3; + // + // pictureBox1 + // + this.pictureBox1.Location = new System.Drawing.Point(0, 0); + this.pictureBox1.Name = "pictureBox1"; + this.pictureBox1.Size = new System.Drawing.Size(246, 288); + this.pictureBox1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom; + this.pictureBox1.TabIndex = 0; + this.pictureBox1.TabStop = false; + // + // groupBox17 + // + this.groupBox17.Controls.Add(this.pictureBox5); + this.groupBox17.Location = new System.Drawing.Point(261, 195); + this.groupBox17.Name = "groupBox17"; + this.groupBox17.Size = new System.Drawing.Size(137, 118); + this.groupBox17.TabIndex = 2; + this.groupBox17.TabStop = false; + this.groupBox17.Text = "检测结果"; + // + // pictureBox5 + // + this.pictureBox5.Location = new System.Drawing.Point(21, 25); + this.pictureBox5.Name = "pictureBox5"; + this.pictureBox5.Size = new System.Drawing.Size(86, 87); + this.pictureBox5.TabIndex = 0; + this.pictureBox5.TabStop = false; + // + // groupBox11 + // + this.groupBox11.Controls.Add(this.textBox4); + this.groupBox11.Controls.Add(this.textBox11); + this.groupBox11.Controls.Add(this.label13); + this.groupBox11.Controls.Add(this.textBox6); + this.groupBox11.Controls.Add(this.label7); + this.groupBox11.Controls.Add(this.label8); + this.groupBox11.Controls.Add(this.textBox5); + this.groupBox11.Controls.Add(this.label6); + this.groupBox11.Controls.Add(this.label5); + this.groupBox11.Controls.Add(this.label1); + this.groupBox11.Location = new System.Drawing.Point(261, 12); + this.groupBox11.Name = "groupBox11"; + this.groupBox11.Size = new System.Drawing.Size(137, 177); + this.groupBox11.TabIndex = 1; + this.groupBox11.TabStop = false; + this.groupBox11.Text = "产品信息"; + // + // textBox4 + // + this.textBox4.Location = new System.Drawing.Point(6, 47); + this.textBox4.Name = "textBox4"; + this.textBox4.Size = new System.Drawing.Size(125, 26); + this.textBox4.TabIndex = 15; + // + // textBox11 + // + this.textBox11.Location = new System.Drawing.Point(85, 148); + this.textBox11.Name = "textBox11"; + this.textBox11.Size = new System.Drawing.Size(49, 26); + this.textBox11.TabIndex = 14; + // + // label13 + // + this.label13.AutoSize = true; + this.label13.Location = new System.Drawing.Point(17, 154); + this.label13.Name = "label13"; + this.label13.Size = new System.Drawing.Size(55, 16); + this.label13.TabIndex = 13; + this.label13.Text = "螺丝孔"; + // + // textBox6 + // + this.textBox6.Location = new System.Drawing.Point(85, 115); + this.textBox6.Name = "textBox6"; + this.textBox6.Size = new System.Drawing.Size(49, 26); + this.textBox6.TabIndex = 12; + // + // label7 + // + this.label7.AutoSize = true; + this.label7.Location = new System.Drawing.Point(20, 120); + this.label7.Name = "label7"; + this.label7.Size = new System.Drawing.Size(39, 16); + this.label7.TabIndex = 11; + this.label7.Text = "距离"; + // + // label8 + // + this.label8.AutoSize = true; + this.label8.Location = new System.Drawing.Point(6, 175); + this.label8.Name = "label8"; + this.label8.Size = new System.Drawing.Size(0, 16); + this.label8.TabIndex = 10; + // + // textBox5 + // + this.textBox5.Location = new System.Drawing.Point(85, 79); + this.textBox5.Name = "textBox5"; + this.textBox5.Size = new System.Drawing.Size(49, 26); + this.textBox5.TabIndex = 9; + // + // label6 + // + this.label6.AutoSize = true; + this.label6.Location = new System.Drawing.Point(9, 84); + this.label6.Name = "label6"; + this.label6.Size = new System.Drawing.Size(71, 16); + this.label6.TabIndex = 8; + this.label6.Text = "金属圈数"; + this.label6.Click += new System.EventHandler(this.label6_Click); + // + // label5 + // + this.label5.AutoSize = true; + this.label5.Location = new System.Drawing.Point(6, 123); + this.label5.Name = "label5"; + this.label5.Size = new System.Drawing.Size(0, 16); + this.label5.TabIndex = 7; + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(11, 22); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(39, 16); + this.label1.TabIndex = 0; + this.label1.Text = "型号"; + // + // tabPage2 + // + this.tabPage2.Controls.Add(this.groupBox2); + this.tabPage2.Controls.Add(this.groupBox1); + this.tabPage2.Controls.Add(this.groupBox10); + this.tabPage2.Controls.Add(this.groupBox6); + this.tabPage2.Controls.Add(this.groupBox7); + this.tabPage2.Location = new System.Drawing.Point(4, 27); + this.tabPage2.Name = "tabPage2"; + this.tabPage2.Padding = new System.Windows.Forms.Padding(3); + this.tabPage2.Size = new System.Drawing.Size(1170, 804); + this.tabPage2.TabIndex = 1; + this.tabPage2.Text = "模板插入"; + this.tabPage2.Click += new System.EventHandler(this.tabPage2_Click); + // + // groupBox2 + // + this.groupBox2.Controls.Add(this.richTextBox2); + this.groupBox2.Font = new System.Drawing.Font("宋体", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + this.groupBox2.Location = new System.Drawing.Point(21, 624); + this.groupBox2.Name = "groupBox2"; + this.groupBox2.Size = new System.Drawing.Size(1141, 177); + this.groupBox2.TabIndex = 5; + this.groupBox2.TabStop = false; + this.groupBox2.Text = "日志"; + // + // richTextBox2 + // + this.richTextBox2.Location = new System.Drawing.Point(9, 17); + this.richTextBox2.Name = "richTextBox2"; + this.richTextBox2.Size = new System.Drawing.Size(1126, 157); + this.richTextBox2.TabIndex = 2; + this.richTextBox2.Text = ""; + // + // groupBox1 + // + this.groupBox1.Controls.Add(this.dataGridView1); + this.groupBox1.Font = new System.Drawing.Font("宋体", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + this.groupBox1.Location = new System.Drawing.Point(766, 276); + this.groupBox1.Name = "groupBox1"; + this.groupBox1.Size = new System.Drawing.Size(396, 337); + this.groupBox1.TabIndex = 4; + this.groupBox1.TabStop = false; + this.groupBox1.Text = "数据库信息"; + // + // dataGridView1 + // + this.dataGridView1.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; + this.dataGridView1.Location = new System.Drawing.Point(8, 22); + this.dataGridView1.Name = "dataGridView1"; + this.dataGridView1.RowTemplate.Height = 23; + this.dataGridView1.Size = new System.Drawing.Size(382, 312); + this.dataGridView1.TabIndex = 3; + this.dataGridView1.CellContentClick += new System.Windows.Forms.DataGridViewCellEventHandler(this.dataGridView1_CellContentClick); + // + // groupBox10 + // + this.groupBox10.Controls.Add(this.button6); + this.groupBox10.Controls.Add(this.button4); + this.groupBox10.Controls.Add(this.button5); + this.groupBox10.Font = new System.Drawing.Font("宋体", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + this.groupBox10.Location = new System.Drawing.Point(778, 10); + this.groupBox10.Name = "groupBox10"; + this.groupBox10.Size = new System.Drawing.Size(384, 96); + this.groupBox10.TabIndex = 2; + this.groupBox10.TabStop = false; + this.groupBox10.Text = "操作面板"; + // + // button6 + // + this.button6.Font = new System.Drawing.Font("宋体", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + this.button6.Location = new System.Drawing.Point(12, 35); + this.button6.Name = "button6"; + this.button6.Size = new System.Drawing.Size(94, 41); + this.button6.TabIndex = 6; + this.button6.Text = "启动相机"; + this.button6.UseVisualStyleBackColor = true; + this.button6.Click += new System.EventHandler(this.button6_Click); + // + // button4 + // + this.button4.Font = new System.Drawing.Font("宋体", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + this.button4.Location = new System.Drawing.Point(270, 35); + this.button4.Name = "button4"; + this.button4.Size = new System.Drawing.Size(88, 41); + this.button4.TabIndex = 7; + this.button4.Text = "保存模板"; + this.button4.UseVisualStyleBackColor = true; + this.button4.Click += new System.EventHandler(this.button4_Click); + // + // button5 + // + this.button5.Font = new System.Drawing.Font("宋体", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + this.button5.Location = new System.Drawing.Point(144, 35); + this.button5.Name = "button5"; + this.button5.Size = new System.Drawing.Size(88, 41); + this.button5.TabIndex = 1; + this.button5.Text = "拍摄照片"; + this.button5.UseVisualStyleBackColor = true; + this.button5.Click += new System.EventHandler(this.button5_Click); + // + // groupBox6 + // + this.groupBox6.Controls.Add(this.textBox10); + this.groupBox6.Controls.Add(this.label12); + this.groupBox6.Controls.Add(this.textBox9); + this.groupBox6.Controls.Add(this.label11); + this.groupBox6.Controls.Add(this.checkBox1); + this.groupBox6.Controls.Add(this.textBox8); + this.groupBox6.Controls.Add(this.label10); + this.groupBox6.Controls.Add(this.textBox7); + this.groupBox6.Controls.Add(this.label9); + this.groupBox6.Font = new System.Drawing.Font("宋体", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + this.groupBox6.Location = new System.Drawing.Point(778, 112); + this.groupBox6.Name = "groupBox6"; + this.groupBox6.Size = new System.Drawing.Size(384, 144); + this.groupBox6.TabIndex = 0; + this.groupBox6.TabStop = false; + this.groupBox6.Text = "基础信息"; + // + // textBox10 + // + this.textBox10.Location = new System.Drawing.Point(292, 110); + this.textBox10.Multiline = true; + this.textBox10.Name = "textBox10"; + this.textBox10.Size = new System.Drawing.Size(68, 23); + this.textBox10.TabIndex = 9; + // + // label12 + // + this.label12.AutoSize = true; + this.label12.Font = new System.Drawing.Font("宋体", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + this.label12.Location = new System.Drawing.Point(206, 110); + this.label12.Name = "label12"; + this.label12.Size = new System.Drawing.Size(71, 16); + this.label12.TabIndex = 8; + this.label12.Text = "模板个数"; + // + // textBox9 + // + this.textBox9.Location = new System.Drawing.Point(292, 66); + this.textBox9.Multiline = true; + this.textBox9.Name = "textBox9"; + this.textBox9.Size = new System.Drawing.Size(68, 23); + this.textBox9.TabIndex = 6; + // + // label11 + // + this.label11.AutoSize = true; + this.label11.Font = new System.Drawing.Font("宋体", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + this.label11.Location = new System.Drawing.Point(206, 67); + this.label11.Name = "label11"; + this.label11.Size = new System.Drawing.Size(71, 16); + this.label11.TabIndex = 5; + this.label11.Text = "金属圈数"; + this.label11.Click += new System.EventHandler(this.label11_Click); + // + // checkBox1 + // + this.checkBox1.AutoSize = true; + this.checkBox1.Checked = true; + this.checkBox1.CheckState = System.Windows.Forms.CheckState.Checked; + this.checkBox1.Font = new System.Drawing.Font("宋体", 14.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + this.checkBox1.Location = new System.Drawing.Point(44, 108); + this.checkBox1.Name = "checkBox1"; + this.checkBox1.Size = new System.Drawing.Size(85, 23); + this.checkBox1.TabIndex = 4; + this.checkBox1.Text = "螺丝孔"; + this.checkBox1.UseVisualStyleBackColor = true; + this.checkBox1.CheckedChanged += new System.EventHandler(this.checkBox1_CheckedChanged); + // + // textBox8 + // + this.textBox8.Location = new System.Drawing.Point(85, 67); + this.textBox8.Multiline = true; + this.textBox8.Name = "textBox8"; + this.textBox8.Size = new System.Drawing.Size(69, 23); + this.textBox8.TabIndex = 3; + // + // label10 + // + this.label10.AutoSize = true; + this.label10.Font = new System.Drawing.Font("宋体", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + this.label10.Location = new System.Drawing.Point(24, 72); + this.label10.Name = "label10"; + this.label10.Size = new System.Drawing.Size(39, 16); + this.label10.TabIndex = 2; + this.label10.Text = "距离"; + // + // textBox7 + // + this.textBox7.Location = new System.Drawing.Point(85, 22); + this.textBox7.Name = "textBox7"; + this.textBox7.Size = new System.Drawing.Size(287, 26); + this.textBox7.TabIndex = 1; + // + // label9 + // + this.label9.AutoSize = true; + this.label9.Font = new System.Drawing.Font("宋体", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + this.label9.Location = new System.Drawing.Point(24, 29); + this.label9.Name = "label9"; + this.label9.Size = new System.Drawing.Size(39, 16); + this.label9.TabIndex = 0; + this.label9.Text = "型号"; + // + // groupBox7 + // + this.groupBox7.Controls.Add(this.panel2); + this.groupBox7.Font = new System.Drawing.Font("宋体", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + this.groupBox7.Location = new System.Drawing.Point(21, 6); + this.groupBox7.Name = "groupBox7"; + this.groupBox7.Size = new System.Drawing.Size(727, 612); + this.groupBox7.TabIndex = 1; + this.groupBox7.TabStop = false; + this.groupBox7.Text = "图像信息"; + this.groupBox7.Enter += new System.EventHandler(this.groupBox7_Enter); + // + // panel2 + // + this.panel2.Controls.Add(this.userControl11); + this.panel2.Location = new System.Drawing.Point(6, 22); + this.panel2.Name = "panel2"; + this.panel2.Size = new System.Drawing.Size(712, 585); + this.panel2.TabIndex = 1; + // + // userControl11 + // + this.userControl11.Location = new System.Drawing.Point(3, 3); + this.userControl11.Name = "userControl11"; + this.userControl11.Size = new System.Drawing.Size(708, 579); + this.userControl11.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom; + this.userControl11.TabIndex = 0; + this.userControl11.TabStop = false; + this.userControl11.Paint += new System.Windows.Forms.PaintEventHandler(this.userControl11_Paint); + this.userControl11.MouseDown += new System.Windows.Forms.MouseEventHandler(this.userControl11_MouseDown); + this.userControl11.MouseMove += new System.Windows.Forms.MouseEventHandler(this.userControl11_MouseMove); + // + // button3 + // + this.button3.Location = new System.Drawing.Point(199, 47); + this.button3.Name = "button3"; + this.button3.Size = new System.Drawing.Size(79, 47); + this.button3.TabIndex = 10; + this.button3.Text = "更改型号"; + this.button3.UseVisualStyleBackColor = true; + this.button3.Click += new System.EventHandler(this.button3_Click); + // + // MainForm + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.AutoScroll = true; + this.ClientSize = new System.Drawing.Size(1180, 841); + this.Controls.Add(this.tabControl1); + this.Name = "MainForm"; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; + this.Text = "减震器检测"; + this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.MainForm_FormClosing); + this.Load += new System.EventHandler(this.Form1_Load); + this.Resize += new System.EventHandler(this.MainForm_Resize); + this.tabControl1.ResumeLayout(false); + this.tabPage1.ResumeLayout(false); + this.panel1.ResumeLayout(false); + this.groupBox3.ResumeLayout(false); + this.groupBox13.ResumeLayout(false); + this.groupBox22.ResumeLayout(false); + this.groupBox22.PerformLayout(); + this.groupBox21.ResumeLayout(false); + this.groupBox21.PerformLayout(); + this.groupBox12.ResumeLayout(false); + this.groupBox12.PerformLayout(); + this.Diary.ResumeLayout(false); + this.groupBox9.ResumeLayout(false); + this.panel6.ResumeLayout(false); + ((System.ComponentModel.ISupportInitialize)(this.pictureBox4)).EndInit(); + this.groupBox20.ResumeLayout(false); + ((System.ComponentModel.ISupportInitialize)(this.pictureBox8)).EndInit(); + this.groupBox16.ResumeLayout(false); + this.groupBox16.PerformLayout(); + this.groupBox8.ResumeLayout(false); + this.panel5.ResumeLayout(false); + ((System.ComponentModel.ISupportInitialize)(this.pictureBox2)).EndInit(); + this.groupBox19.ResumeLayout(false); + ((System.ComponentModel.ISupportInitialize)(this.pictureBox7)).EndInit(); + this.groupBox15.ResumeLayout(false); + this.groupBox15.PerformLayout(); + this.groupBox5.ResumeLayout(false); + this.panel4.ResumeLayout(false); + ((System.ComponentModel.ISupportInitialize)(this.pictureBox3)).EndInit(); + this.groupBox18.ResumeLayout(false); + ((System.ComponentModel.ISupportInitialize)(this.pictureBox6)).EndInit(); + this.groupBox14.ResumeLayout(false); + this.groupBox14.PerformLayout(); + this.groupBox4.ResumeLayout(false); + this.panel3.ResumeLayout(false); + ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit(); + this.groupBox17.ResumeLayout(false); + ((System.ComponentModel.ISupportInitialize)(this.pictureBox5)).EndInit(); + this.groupBox11.ResumeLayout(false); + this.groupBox11.PerformLayout(); + this.tabPage2.ResumeLayout(false); + this.groupBox2.ResumeLayout(false); + this.groupBox1.ResumeLayout(false); + ((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).EndInit(); + this.groupBox10.ResumeLayout(false); + this.groupBox6.ResumeLayout(false); + this.groupBox6.PerformLayout(); + this.groupBox7.ResumeLayout(false); + this.panel2.ResumeLayout(false); + ((System.ComponentModel.ISupportInitialize)(this.userControl11)).EndInit(); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.TabControl tabControl1; + private System.Windows.Forms.TabPage tabPage1; + private System.Windows.Forms.TabPage tabPage2; + private System.Windows.Forms.GroupBox groupBox7; + private System.Windows.Forms.GroupBox groupBox6; + private System.Windows.Forms.RichTextBox richTextBox2; + private System.Windows.Forms.Label label9; + private System.Windows.Forms.TextBox textBox7; + private System.Windows.Forms.TextBox textBox8; + private System.Windows.Forms.Label label10; + private System.Windows.Forms.TextBox textBox9; + private System.Windows.Forms.Label label11; + private System.Windows.Forms.CheckBox checkBox1; + private System.Windows.Forms.Panel panel1; + private System.Windows.Forms.GroupBox groupBox3; + private System.Windows.Forms.GroupBox groupBox10; + private System.Windows.Forms.Button button6; + private System.Windows.Forms.Button button5; + private picEx.UserControl1 userControl11; + private picEx.UserControl1 pictureBox1; + private picEx.UserControl1 pictureBox3; + private picEx.UserControl1 pictureBox2; + private picEx.UserControl1 pictureBox4; + private System.Windows.Forms.Panel panel2; + private System.Windows.Forms.Button button4; + private System.Windows.Forms.DataGridView dataGridView1; + private System.Windows.Forms.Label label12; + private System.Windows.Forms.TextBox textBox10; + private System.Windows.Forms.GroupBox groupBox4; + private System.Windows.Forms.GroupBox groupBox2; + private System.Windows.Forms.GroupBox groupBox1; + private System.Windows.Forms.GroupBox groupBox5; + private System.Windows.Forms.GroupBox groupBox9; + private System.Windows.Forms.GroupBox groupBox8; + private System.Windows.Forms.GroupBox groupBox13; + private System.Windows.Forms.GroupBox groupBox12; + private System.Windows.Forms.GroupBox Diary; + private System.Windows.Forms.RichTextBox richTextBox1; + private System.Windows.Forms.Button button2; + private System.Windows.Forms.Button button1; + private System.Windows.Forms.TextBox textBox3; + private System.Windows.Forms.TextBox textBox2; + private System.Windows.Forms.TextBox textBox1; + private System.Windows.Forms.Label label4; + private System.Windows.Forms.Label label3; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.GroupBox groupBox11; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.TextBox textBox5; + private System.Windows.Forms.Label label6; + private System.Windows.Forms.Label label5; + private System.Windows.Forms.GroupBox groupBox16; + private System.Windows.Forms.TextBox textBox20; + private System.Windows.Forms.Label label26; + private System.Windows.Forms.TextBox textBox21; + private System.Windows.Forms.Label label27; + private System.Windows.Forms.Label label28; + private System.Windows.Forms.TextBox textBox22; + private System.Windows.Forms.Label label29; + private System.Windows.Forms.Label label30; + private System.Windows.Forms.Label label31; + private System.Windows.Forms.GroupBox groupBox15; + private System.Windows.Forms.TextBox textBox16; + private System.Windows.Forms.Label label20; + private System.Windows.Forms.TextBox textBox17; + private System.Windows.Forms.Label label21; + private System.Windows.Forms.Label label22; + private System.Windows.Forms.TextBox textBox18; + private System.Windows.Forms.Label label23; + private System.Windows.Forms.Label label24; + private System.Windows.Forms.Label label25; + private System.Windows.Forms.GroupBox groupBox14; + private System.Windows.Forms.TextBox textBox12; + private System.Windows.Forms.Label label14; + private System.Windows.Forms.TextBox textBox13; + private System.Windows.Forms.Label label15; + private System.Windows.Forms.Label label16; + private System.Windows.Forms.TextBox textBox14; + private System.Windows.Forms.Label label17; + private System.Windows.Forms.Label label18; + private System.Windows.Forms.Label label19; + private System.Windows.Forms.TextBox textBox11; + private System.Windows.Forms.Label label13; + private System.Windows.Forms.TextBox textBox6; + private System.Windows.Forms.Label label7; + private System.Windows.Forms.Label label8; + private System.Windows.Forms.GroupBox groupBox19; + private System.Windows.Forms.GroupBox groupBox18; + private System.Windows.Forms.GroupBox groupBox17; + private System.Windows.Forms.GroupBox groupBox20; + private System.Windows.Forms.PictureBox pictureBox8; + private System.Windows.Forms.PictureBox pictureBox7; + private System.Windows.Forms.PictureBox pictureBox6; + private System.Windows.Forms.PictureBox pictureBox5; + private System.Windows.Forms.TextBox textBox23; + private System.Windows.Forms.TextBox textBox19; + private System.Windows.Forms.TextBox textBox15; + private System.Windows.Forms.TextBox textBox4; + private System.Windows.Forms.ComboBox comboBox2; + private System.Windows.Forms.ComboBox comboBox1; + private System.Windows.Forms.Label label33; + private System.Windows.Forms.Label label32; + private System.Windows.Forms.GroupBox groupBox22; + private System.Windows.Forms.TextBox textBox24; + private System.Windows.Forms.Label label34; + private System.Windows.Forms.Label label35; + private System.Windows.Forms.TextBox textBox25; + private System.Windows.Forms.Label label36; + private System.Windows.Forms.TextBox textBox26; + private System.Windows.Forms.Label label38; + private System.Windows.Forms.TextBox textBox28; + private System.Windows.Forms.GroupBox groupBox21; + private System.Windows.Forms.TextBox textBox27; + private System.Windows.Forms.Label label37; + private System.Windows.Forms.Panel panel3; + private System.Windows.Forms.Panel panel4; + private System.Windows.Forms.Panel panel6; + private System.Windows.Forms.Panel panel5; + private System.Windows.Forms.Button button3; + } +} + diff --git a/MainForm.cs b/MainForm.cs new file mode 100644 index 0000000..5ed4de0 --- /dev/null +++ b/MainForm.cs @@ -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 _cameraThreads; + private readonly List _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) + { + + } + // + /// 主窗口 + /// + 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); + //} + // + /// NG图片路径按钮 + /// + + + 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); + } + + + // + /// 拍摄照片按钮 + /// + 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; + } + + // + /// 启动相机(插入) + /// + 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; + + } + + // + /// 窗体关闭事件 + /// + 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) + { + + } + + + // + /// 保存模板 + /// + 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 columnMappings = new Dictionary + { + { "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型号 + } + } +} diff --git a/MainForm.resx b/MainForm.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/MainForm.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/PLCItem.cs b/PLCItem.cs new file mode 100644 index 0000000..888dc8c --- /dev/null +++ b/PLCItem.cs @@ -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, + + + /// + /// 报警监控 1+8 + /// + [Description("报警监控")] + WarningMonitor = 9, + + /// + /// CT监控 1+16 + /// + [Description("CT监控")] + CTMonitor = 17, +} +public class PLCItem +{ + /// + /// 读写地址 + /// + public string Address { get; set; } = ""; + + /// + /// 读写地址长度 + /// + public int ItemLength { get; set; } = 1; + + /// + /// PLC项目值 + /// + public List ItemValues { get; set; } = new List(); + + /// + /// 是否写数据 1:读数据 2:写数据 4:监控 参见枚举PLCOpType + /// + public PLCOpType PLCOpType { get; set; } = PLCOpType.Read; + + public DateTime OpTimeStamp { get; set; } = DateTime.Now; + + +} + diff --git a/PlcContorl.cs b/PlcContorl.cs new file mode 100644 index 0000000..0e4505f --- /dev/null +++ b/PlcContorl.cs @@ -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 Read(string startAddress, int length) + { + PLCItem item = new PLCItem(); + item.Address = startAddress; + item.ItemLength = length; + + ReadItem(item); + //List valueList = new List(); + //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"); + } + + /// + /// 写单独地址 + /// + /// 地址 + /// + /// + 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"); + } + /// + /// 写单独地址 string值 + /// + /// 地址 + /// + /// + 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"); + } + + /// + /// 写单独地址 float值 + /// + /// 地址 + /// + /// + 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 GetMonitorValues(int startAddress, int length) + { + List res = new List(); + // 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(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 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) + { + + } + } + } + }); + } +} + diff --git a/Process_Img.cs b/Process_Img.cs new file mode 100644 index 0000000..d474a98 --- /dev/null +++ b/Process_Img.cs @@ -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); + } + } + } + } +} diff --git a/Program.cs b/Program.cs new file mode 100644 index 0000000..e516fc7 --- /dev/null +++ b/Program.cs @@ -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 + { + /// + /// 应用程序的主入口点。 + /// + [STAThread] + static void Main() + { + Application.EnableVisualStyles(); + Application.SetCompatibleTextRenderingDefault(false); + Application.Run(new MainForm()); + } + } +} diff --git a/Properties/AssemblyInfo.cs b/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..507b3dd --- /dev/null +++ b/Properties/AssemblyInfo.cs @@ -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")] diff --git a/Properties/Resources.Designer.cs b/Properties/Resources.Designer.cs new file mode 100644 index 0000000..8b479b7 --- /dev/null +++ b/Properties/Resources.Designer.cs @@ -0,0 +1,71 @@ +//------------------------------------------------------------------------------ +// +// 此代码由工具生成。 +// 运行时版本: 4.0.30319.42000 +// +// 对此文件的更改可能导致不正确的行为,如果 +// 重新生成代码,则所做更改将丢失。 +// +//------------------------------------------------------------------------------ + +namespace WindowsFormsApp1.Properties +{ + + + /// + /// 强类型资源类,用于查找本地化字符串等。 + /// + // 此类是由 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() + { + } + + /// + /// 返回此类使用的缓存 ResourceManager 实例。 + /// + [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; + } + } + + /// + /// 重写当前线程的 CurrentUICulture 属性,对 + /// 使用此强类型资源类的所有资源查找执行重写。 + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture + { + get + { + return resourceCulture; + } + set + { + resourceCulture = value; + } + } + } +} diff --git a/Properties/Resources.resx b/Properties/Resources.resx new file mode 100644 index 0000000..af7dbeb --- /dev/null +++ b/Properties/Resources.resx @@ -0,0 +1,117 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/Properties/Settings.Designer.cs b/Properties/Settings.Designer.cs new file mode 100644 index 0000000..438df21 --- /dev/null +++ b/Properties/Settings.Designer.cs @@ -0,0 +1,30 @@ +//------------------------------------------------------------------------------ +// +// 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. +// +//------------------------------------------------------------------------------ + +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; + } + } + } +} diff --git a/Properties/Settings.settings b/Properties/Settings.settings new file mode 100644 index 0000000..3964565 --- /dev/null +++ b/Properties/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + diff --git a/README.md b/README.md new file mode 100644 index 0000000..3e60343 --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +# Lujiayi \ No newline at end of file diff --git a/SQLConnect.cs b/SQLConnect.cs new file mode 100644 index 0000000..181d62d --- /dev/null +++ b/SQLConnect.cs @@ -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语句 + + /// + /// 执行SQL语句,返回影响的记录数 + /// + /// SQL语句 + /// 影响的记录数 + 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); + } + } + } + } + + /// + /// 执行SQL语句,设置命令的执行等待时间 + /// + /// + /// + /// + 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); + } + } + } + } + + /// + /// 执行多条SQL语句,实现数据库事务。 + /// + /// 多条SQL语句 + 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; + } + + /// + /// 执行带一个存储过程参数的的SQL语句。 + /// + /// SQL语句 + /// 参数内容,比如一个字段是格式复杂的文章,有特殊符号,可以通过这个方式添加 + /// 影响的记录数 + 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(); + } + } + } + + /// + /// 执行带一个存储过程参数的的SQL语句。 + /// + /// SQL语句 + /// 参数内容,比如一个字段是格式复杂的文章,有特殊符号,可以通过这个方式添加 + /// 影响的记录数 + 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(); + } + } + } + + /// + /// 向数据库里插入图像格式的字段(和上面情况类似的另一种实例) + /// + /// SQL语句 + /// 图像字节,数据库的字段类型为image的情况 + /// 影响的记录数 + 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(); + } + } + } + + /// + /// 执行一条计算查询结果语句,返回查询结果(object)。 + /// + /// 计算查询结果语句 + /// 查询结果(object) + 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); + } + } + } + } + + /// + /// 执行查询语句,返回SQLiteDataReader(使用该方法切记要手工关闭SQLiteDataReader和连接) + /// + /// 查询语句 + /// SQLiteDataReader + 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(); + //} + } + + /// + /// 执行查询语句,返回DataSet + /// + /// 查询语句 + /// DataSet + 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 ExecuteQuery(string SQLString, Func 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 list = new List(); + 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; + } + } + + /// + /// 执行查询语句,返回DataSet,设置命令的执行等待时间 + /// + /// + /// + /// + 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语句 + + /// + /// 执行SQL语句,返回影响的记录数 + /// + /// SQL语句 + /// 影响的记录数 + 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); + } + } + } + } + + /// + /// 执行多条SQL语句,实现数据库事务。 + /// + /// SQL语句的哈希表(key为sql语句,value是该语句的SQLiteParameter[]) + 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); + } + } + } + } + + /// + /// 执行一条计算查询结果语句,返回查询结果(object)。 + /// + /// 计算查询结果语句 + /// 查询结果(object) + 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); + } + } + } + } + + /// + /// 执行查询语句,返回SQLiteDataReader (使用该方法切记要手工关闭SQLiteDataReader和连接) + /// + /// 查询语句 + /// SQLiteDataReader + 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(); + //} + + } + + /// + /// 执行查询语句,返回DataSet + /// + /// 查询语句 + /// DataSet + 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 参数转换 + /// + /// 放回一个SQLiteParameter + /// + /// 参数名字 + /// 参数类型 + /// 参数大小 + /// 参数值 + /// SQLiteParameter的值 + 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 GetColumnData(string tableName, string columnName) + { + List dataList = new List(); + 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; + } + + /// + /// 绑定列数据到ComboBox + /// + /// ComboBox控件 + /// 表名 + /// 列名 + public static void DataToComboBox(ComboBox comboBox, string tableName, string columnName) + { + List 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 +} diff --git a/SimboObjectDetection.cs b/SimboObjectDetection.cs new file mode 100644 index 0000000..cd3c150 --- /dev/null +++ b/SimboObjectDetection.cs @@ -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 SegmentResult; + public class Result + { + + public double fScore; + public int classId; + public string classname; + + public double area; + public List rect; + + + } + +} + + +/// +/// 实例分割 maskrcnn +/// +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(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(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(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(); + } + } + + +} + diff --git a/StaticHelper.cs b/StaticHelper.cs new file mode 100644 index 0000000..4940eae --- /dev/null +++ b/StaticHelper.cs @@ -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()); + } + /// + /// 数值转换为byte数组 高位在前,低位在后 + /// + /// + /// + /// + 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; + } + + /// + /// 字节数组转换为整数 + /// + /// 字节数组 + /// true:数组序号低的在高位 false:数组序号低的在低位 + /// + 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; + } + + /// + /// 获取一个类指定的属性值 + /// + /// object对象 + /// 属性名称 + /// + public static object GetPropertyValue(object info, string field) + { + if (info == null) return null; + Type t = info.GetType(); + IEnumerable property = from pi in t.GetProperties() where pi.Name.ToLower() == field.ToLower() select pi; + return property.First().GetValue(info, null); + } + + /// + /// 将32位整形拆分为无符号16位整形 + /// + /// 需要拆分的32位整形 + /// 拆分为16位整形的位数 1或者2 + /// true:高位在前,低位在后;false:高位在后,低位在前 + /// + public static List 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() { high, low }; + } + else + { + return new List() { low, high }; + } + } + else + { + if (num < 0) + { + num = ushort.MaxValue + 1 + num; + } + + return new List() { (ushort)num }; + } + } + + /// + /// 将32位整形数组拆分为无符号16位整形数组 + /// + /// 需要拆分的32位整形 + /// 拆分为16位整形的位数 1或者2 + /// true:高位在前,低位在后;false:高位在后,低位在前 + /// + public static List ParseIntToUnsignShortList(this List list, int bitNum = 2, bool HtL = false) + { + return list.SelectMany(u => u.ParseIntToUnsignShortList(bitNum, HtL)).ToList(); + } + + /// + /// 将ushort的集合转换为16位带符号整形 + /// + /// + /// 合并的位数 1或者2 + /// true:高位在前,低位在后;false:高位在后,低位在前 + /// + public static List ParseUnsignShortListToInt(this List 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 list = new List(); + 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(this T t) + //{ + // return JsonConvert.DeserializeObject(JsonConvert.SerializeObject(t)); + //} + + public static void DataFrom(this T1 destT, T2 sourceT, List 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; + } + /// + /// 缺陷灰度图转彩色图像函数 + /// + /// 灰度图 + /// 返回构造的伪彩色图像 + public static Bitmap GrayMapToColorMap(this Bitmap src, Dictionary 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(this ObservableCollection collection) where T : IComparable + { + List sortedList = collection.OrderByDescending(x => x).ToList();//这里用降序 + for (int i = 0; i < sortedList.Count(); i++) + { + collection.Move(collection.IndexOf(sortedList[i]), i); + } + } + + /// + /// 获得字符串中开始和结束字符串中间的值 + /// + /// + /// + /// + /// + 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; + } + + /// + /// 获得字符串中开始和结束字符串中间的值 + /// + /// 字符串 + /// 开始 + /// 结束 + /// + 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); + /// + /// 检测文件是否只读或被使用 + /// + /// 要检测的文件 + /// true可用,false在用或只读 + 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 + + /// + /// 获取指定文件夹下所有的文件名称 + /// + /// 指定文件夹名称,绝对路径 + /// 文件类型过滤,根据文件后缀名,如:*,*.txt,*.xls + /// 是否包含子文件夹 + /// ArrayList数组,为所有需要的文件路径名称 + public static List GetAllFilesByFolder(string folderName, string fileFilter, bool isContainSubFolder = false) + { + List resList = new List(); + 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; + } + + /// + /// 获取指定文件夹下所有的文件名称,不过滤文件类型 + /// + /// 指定文件夹名称,绝对路径 + /// 是否包含子文件夹 + /// ArrayList数组,为所有需要的文件路径名称 + public static List GetAllFilesByFolder(string folderName, bool isContainSubFolder) + { + return GetAllFilesByFolder(folderName, "*", isContainSubFolder); + } +} + +public class Compare : IEqualityComparer +{ + private Func _getField; + public Compare(Func getfield) + { + _getField = getfield; + } + public bool Equals(T x, T y) + { + return EqualityComparer.Default.Equals(_getField(x), _getField(y)); + } + public int GetHashCode(T obj) + { + return EqualityComparer.Default.GetHashCode(_getField(obj)); + } +} + +public static class ObjectExtensions +{ + public static IEnumerable DistinctBy(this IEnumerable source, Func getfield) + { + return source.Distinct(new Compare(getfield)); + } + + public static IQueryable DistinctBy(this IQueryable source, Func getfield) + { + return source.Distinct(new Compare(getfield)); + } +} + diff --git a/Thread.cs b/Thread.cs new file mode 100644 index 0000000..3743232 --- /dev/null +++ b/Thread.cs @@ -0,0 +1,51 @@ +using System; +using System.Threading; +using System.Drawing; // 或者使用其他图像处理库 + +public class CameraThread +{ + private readonly int _cameraId; + private readonly Action _onImageCaptured; + private Thread _thread; + private bool _running; + + public CameraThread(int cameraId, Action 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); // 模拟图像 + } +} \ No newline at end of file diff --git a/WriteLog.cs b/WriteLog.cs new file mode 100644 index 0000000..0c733fb --- /dev/null +++ b/WriteLog.cs @@ -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; + + /// + /// 构造函数传入RichTextBox控件的实例。 + /// + /// + public WriteLog(RichTextBox richTextBox1) + { + this.richTextBox1 = richTextBox1; + this.logAppendDelegate = new LogAppendDelegate(LogAppend); + } + + /// + /// LogAppendDelegate委托指向的方法 + /// + /// + /// + private void LogAppend(Color color, string text) + { + richTextBox1.SelectionColor = color; + richTextBox1.AppendText(text + Environment.NewLine); + } + + /// + /// 追加显示文本 + /// + /// + public void LogAppendMsg(string text) + { + richTextBox1.Invoke(logAppendDelegate, Color.Black, DateTime.Now.ToString("yyyy.MM.dd HH:mm:ss") + " " + text); + } + + /// + /// 显示错误日志 + /// + /// + public void LogError(string text) + { + richTextBox1.Invoke(logAppendDelegate, Color.Red, DateTime.Now.ToString("yyyy.MM.dd HH:mm:ss") + " " + text); + } + + /// + /// 显示警告信息 + /// + /// + public void LogWarning(string text) + { + richTextBox1.Invoke(logAppendDelegate, Color.Violet, DateTime.Now.ToString("yyyy.MM.dd HH:mm:ss") + " " + text); + } + + /// + /// 显示信息 + /// + /// + public void LogMessage(string text) + { + richTextBox1.Invoke(logAppendDelegate, Color.Black, DateTime.Now.ToString("yyyy.MM.dd HH:mm:ss") + " " + text); + } + } +} diff --git a/packages.config b/packages.config new file mode 100644 index 0000000..e755b32 --- /dev/null +++ b/packages.config @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file