C3032
3 天以前 ebcc1d53f14112363bbf539bcaf0202aadcdc9d7
2D取图计数功能完成
已修改7个文件
已添加4个文件
1678 ■■■■■ 文件已修改
LB_SmartVision/CSV/CsvRecordProductData.cs 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
LB_SmartVision/ProcessRun/ProcessContext.cs 80 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
LB_SmartVision/ProcessRun/ProcessRunBll.cs 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
LB_SmartVision/SQL/RecordProductData.cs 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
LB_VisionProcesses/Cameras/2DCameraForm.cs 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
LB_VisionProcesses/Cameras/CameraConfig.cs 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
LB_VisionProcesses/Cameras/ICamera.cs 88 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
LB_VisionProcesses/Processes/TyreCounter/TyreCounterProcess.cs 413 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
LB_VisionProcesses/Processes/TyreCounter/TyreCounterProcessEdit.Designer.cs 567 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
LB_VisionProcesses/Processes/TyreCounter/TyreCounterProcessEdit.cs 161 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
LB_VisionProcesses/Processes/TyreCounter/TyreStatistics.cs 266 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
LB_SmartVision/CSV/CsvRecordProductData.cs
@@ -47,6 +47,26 @@
        /// æ£€æµ‹ç›¸æœº
        /// </summary>
        public string CameraInspection { get; set; }
        /// <summary>
        /// è½®èƒŽID
        /// </summary>
        public int TyreID { get; set; }
        /// <summary>
        /// å›¾åƒåºå·ï¼ˆ1~n)
        /// </summary>
        public int ImageIndex { get; set; }
        /// <summary>
        /// è½®èƒŽçº§æ£€æµ‹ç»“æžœ
        /// </summary>
        public string TyreResult { get; set; }
        /// <summary>
        /// æ¯å¼ è½®èƒŽå›¾åƒæ•°
        /// </summary>
        public int ImagesPerTyre { get; set; }
    }
}
LB_SmartVision/ProcessRun/ProcessContext.cs
@@ -6,6 +6,7 @@
using LB_VisionProcesses.Alogrithms;
using LB_VisionProcesses.Cameras;
using LB_VisionProcesses.Communicators;
using LB_VisionProcesses.Processes;
using LB_VisionProcesses.Processes.ScriptTool;
using OpenCvSharp;
using System.Collections.Concurrent;
@@ -585,7 +586,86 @@
        [Node("Halcon2D图像滤波", "Halcon2D工具", "Basic", "Halcon2D图像滤波")]
        public void Halcon2D图像滤波(FlowNode node) { RunNodeAsync(node); }
        [Node("轮胎计数", "控制", "Logic", "轮胎计数节点")]
        public void è½®èƒŽè®¡æ•°(FlowNode node)
        {
            string ProcessName = node.Text;
            try
            {
                if (dicContext.TryGetValue(ProcessName, out IProcess obj)
                    && obj is TyreCounterProcess counter)
                {
                    UpdateInputs(counter);
                    if (node.Break)
                    {
                        node.BranchIndex = "0";
                        node.Result = true;
                        counter.Result = true;
                        counter.Msg = "轮胎计数节点已跳过";
                        return;
                    }
                    // ä»Žå‰ç½®èŠ‚ç‚¹èŽ·å–æ£€æµ‹ç»“æžœï¼ˆé€šè¿‡è¾“å…¥æ˜ å°„ï¼‰
                    bool imageResult = GetPreviousResult(node);
                    // è®¾ç½®è¾“入结果
                    counter.InputImage = imageResult;
                    // è¿è¡Œè½®èƒŽè®¡æ•°
                    if (!counter.Run())
                    {
                        node.Result = false;
                        Result &= false;
                        Msg += $"[{ProcessName}]{counter.Msg}";
                    }
                    else
                    {
                        node.Result = true;
                        // å¦‚果完成一个轮胎,输出完成信号
                        if (counter.IsTyreComplete)
                        {
                            Msg += $"[{ProcessName}]完成轮胎 #{counter.CurrentTyreID - 1},结果: {(counter.TyreResult ? "OK" : "NG")}";
                        }
                    }
                }
                else
                {
                    node.Result = false;
                    Result &= false;
                    Msg += $"[{ProcessName}]未找到轮胎计数工具实例";
                }
            }
            catch (Exception ex)
            {
                node.Result = false;
                Result &= false;
                Msg += $"[{ProcessName}]运行发生意外,{ex.Message}";
            }
        }
        /// <summary>
        /// èŽ·å–å‰ç½®èŠ‚ç‚¹çš„æ£€æµ‹ç»“æžœ
        /// </summary>
        private bool GetPreviousResult(FlowNode node)
        {
            try
            {
                // æŸ¥æ‰¾å‰ç½®èŠ‚ç‚¹
                var prevNode = dicContext.Values
                    .OfType<IProcess>()
                    .FirstOrDefault(p => p.Result == true || p.Result == false);
                if (prevNode != null)
                {
                    return prevNode.Result;
                }
            }
            catch { }
            return true; // é»˜è®¤è¿”回OK
        }
        #endregion
LB_SmartVision/ProcessRun/ProcessRunBll.cs
@@ -875,9 +875,26 @@
        double total_OK;
        double total_NG;
        /// <summary>
        /// è½®èƒŽçº§ç»Ÿè®¡ - OK计数
        /// </summary>
        double tyre_OK;
        /// <summary>
        /// è½®èƒŽçº§ç»Ÿè®¡ - NG计数
        /// </summary>
        double tyre_NG;
        public double total
        {
            get { return total_OK + total_NG; }
        }
        /// <summary>
        /// è½®èƒŽæ€»æ•°
        /// </summary>
        public double tyreTotal
        {
            get { return tyre_OK + tyre_NG; }
        }
        public double Rate_OK
@@ -890,10 +907,37 @@
            }
        }
        /// <summary>
        /// è½®èƒŽè‰¯å“çއ
        /// </summary>
        public double TyreRate_OK
        {
            get
            {
                if (tyreTotal == 0)
                    return 100;
                return (tyre_OK / tyreTotal) * 100;
            }
        }
        public void ClearTotal()
        {
            total_OK = 0;
            total_NG = 0;
            tyre_OK = 0;
            tyre_NG = 0;
        }
        /// <summary>
        /// æ·»åŠ è½®èƒŽç»Ÿè®¡
        /// </summary>
        /// <param name="isOK">轮胎是否OK</param>
        public void AddTyreResult(bool isOK)
        {
            if (isOK)
                tyre_OK++;
            else
                tyre_NG++;
        }
        /// <summary>
LB_SmartVision/SQL/RecordProductData.cs
@@ -71,5 +71,37 @@
        [DisplayName("检测相机")]
        [Browsable(true)]
        public string CameraInspection { get; set; }
        /// <summary>
        /// è½®èƒŽID
        /// </summary>
        [Category("RecordProductData"), PropertyOrder(7)]
        [DisplayName("轮胎ID")]
        [Browsable(true)]
        public int TyreID { get; set; }
        /// <summary>
        /// å›¾åƒåºå·ï¼ˆ1~n)
        /// </summary>
        [Category("RecordProductData"), PropertyOrder(8)]
        [DisplayName("图像序号")]
        [Browsable(true)]
        public int ImageIndex { get; set; }
        /// <summary>
        /// è½®èƒŽçº§æ£€æµ‹ç»“æžœ
        /// </summary>
        [Category("RecordProductData"), PropertyOrder(9)]
        [DisplayName("轮胎结果")]
        [Browsable(true)]
        public string TyreResult { get; set; }
        /// <summary>
        /// æ¯å¼ è½®èƒŽå›¾åƒæ•°
        /// </summary>
        [Category("RecordProductData"), PropertyOrder(10)]
        [DisplayName("轮胎图像数")]
        [Browsable(true)]
        public int ImagesPerTyre { get; set; }
    }
}
LB_VisionProcesses/Cameras/2DCameraForm.cs
@@ -78,7 +78,7 @@
        UserPictureBox onlinePictureBox { get; set; }
        private System.Windows.Forms.Timer updateTimer;
        Total total = new Total { iImageCount = 0, iScanCount = 0 };
        Total total = new Total { iImageCount = 0, iScanCount = 0, ImagesPerTyre = 1 };
        DateTime startGrabtime = DateTime.Now;
        
        // åŠ¨æ€æ·»åŠ çš„å¢žç›Šä¸‹æ‹‰æ¡†
LB_VisionProcesses/Cameras/CameraConfig.cs
@@ -42,6 +42,11 @@
            Params.Inputs.Add("超时时间", 1000);
            Params.Inputs.Add("是否失败重新取图", false);
            // 2D轮胎计数配置(默认为1,表示3D模式;2D相机设置为n)
            Params.Inputs.Add("ImagesPerTyre", 1);
            Params.Inputs.Add("当前轮胎ID", 1);
            Params.Inputs.Add("当前图像序号", 0);
        }
        /// <summary>
LB_VisionProcesses/Cameras/ICamera.cs
@@ -8,8 +8,45 @@
{
    public class Total
    {
        /// <summary>
        /// å›¾åƒè®¡æ•°
        /// </summary>
        public int iImageCount { get; set; } = 0;
        /// <summary>
        /// æ‰«æè®¡æ•°
        /// </summary>
        public int iScanCount { get; set; } = 0;
        /// <summary>
        /// å®Œæ•´è½®èƒŽè®¡æ•°
        /// </summary>
        public int TyreCount { get; set; } = 0;
        /// <summary>
        /// æ¯å¼ è½®èƒŽæ‰€éœ€å›¾åƒæ•°ï¼ˆ2D相机使用,默认1表示3D相机)
        /// </summary>
        public int ImagesPerTyre { get; set; } = 1;
        /// <summary>
        /// å½“前轮胎的图像序号(0~ImagesPerTyre-1)
        /// </summary>
        public int CurrentImageIndex { get; set; } = 0;
        /// <summary>
        /// è½®èƒŽOK计数
        /// </summary>
        public int TyreOK { get; set; } = 0;
        /// <summary>
        /// è½®èƒŽNG计数
        /// </summary>
        public int TyreNG { get; set; } = 0;
        /// <summary>
        /// å½“前轮胎ID
        /// </summary>
        public int CurrentTyreID { get; set; } = 1;
        public Total() { }
@@ -19,10 +56,61 @@
            this.iScanCount = iScanCount;
        }
        /// <summary>
        /// æ·»åŠ å›¾åƒå¹¶æ›´æ–°è½®èƒŽè®¡æ•°
        /// </summary>
        /// <param name="imageResult">图像检测结果</param>
        /// <returns>是否完成一个轮胎</returns>
        public bool AddImageResult(bool imageResult)
        {
            iImageCount++;
            CurrentImageIndex++;
            // æ£€æŸ¥æ˜¯å¦å®Œæˆä¸€ä¸ªè½®èƒŽ
            if (CurrentImageIndex >= ImagesPerTyre)
            {
                TyreCount++;
                CurrentImageIndex = 0;
                // æ›´æ–°è½®èƒŽOK/NG计数(n张中任一NG则整胎NG)
                if (imageResult)
                    TyreOK++;
                else
                    TyreNG++;
                CurrentTyreID++;
                return true;
            }
            return false;
        }
        /// <summary>
        /// èŽ·å–è½®èƒŽè‰¯å“çŽ‡
        /// </summary>
        public double TyreRateOK => TyreCount > 0 ? (TyreOK / (double)TyreCount) * 100 : 0;
        public void Clear()
        {
            iImageCount = 0;
            iScanCount = 0;
            TyreCount = 0;
            CurrentImageIndex = 0;
            TyreOK = 0;
            TyreNG = 0;
            CurrentTyreID = 1;
        }
        /// <summary>
        /// é‡ç½®è½®èƒŽè®¡æ•°ï¼ˆä¿ç•™ImagesPerTyre配置)
        /// </summary>
        public void ResetTyreCount()
        {
            TyreCount = 0;
            CurrentImageIndex = 0;
            TyreOK = 0;
            TyreNG = 0;
            CurrentTyreID = 1;
        }
    }
    public interface ICamera : IDisposable
LB_VisionProcesses/Processes/TyreCounter/TyreCounterProcess.cs
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,413 @@
using HalconDotNet;
using LB_VisionProcesses.Alogrithms;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace LB_VisionProcesses.Processes
{
    /// <summary>
    /// è½®èƒŽè®¡æ•°å·¥å…· - ç”¨äºŽæµç¨‹èŠ‚ç‚¹ä¸­ç»Ÿè®¡è½®èƒŽæ•°é‡
    /// </summary>
    [Process("轮胎计数", Category = "控制", Description = "用于2D工位轮胎计数,配置n张图/轮胎")]
    public class TyreCounterProcess : BaseProcess
    {
        #region é…ç½®å±žæ€§
        /// <summary>
        /// æ¯å¼ è½®èƒŽæ‰€éœ€å›¾åƒæ•°
        /// </summary>
        public int ImagesPerTyre
        {
            get
            {
                if (Params.Inputs.ContainsKey("ImagesPerTyre"))
                    return Convert.ToInt32(Params.Inputs["ImagesPerTyre"]);
                return 8;
            }
            set
            {
                Params.Inputs["ImagesPerTyre"] = value;
            }
        }
        /// <summary>
        /// åˆ¤å®šè§„则
        /// </summary>
        public TyreJudgeRule JudgeRule
        {
            get
            {
                if (Params.Inputs.ContainsKey("JudgeRule"))
                    return (TyreJudgeRule)Enum.Parse(typeof(TyreJudgeRule), Params.Inputs["JudgeRule"].ToString());
                return TyreJudgeRule.AnyNG;
            }
            set
            {
                Params.Inputs["JudgeRule"] = value.ToString();
            }
        }
        /// <summary>
        /// æ˜¯å¦è‡ªåŠ¨é‡ç½®ï¼ˆå®Œæˆä¸€ä¸ªè½®èƒŽåŽè‡ªåŠ¨é‡ç½®è®¡æ•°ï¼‰
        /// </summary>
        public bool AutoReset
        {
            get
            {
                if (Params.Inputs.ContainsKey("AutoReset"))
                    return Convert.ToBoolean(Params.Inputs["AutoReset"]);
                return true;
            }
            set
            {
                Params.Inputs["AutoReset"] = value;
            }
        }
        #endregion
        #region è¾“出属性
        /// <summary>
        /// å½“前轮胎ID
        /// </summary>
        public int CurrentTyreID
        {
            get
            {
                if (Params.Outputs.ContainsKey("CurrentTyreID"))
                    return Convert.ToInt32(Params.Outputs["CurrentTyreID"]);
                return 1;
            }
            private set
            {
                Params.Outputs["CurrentTyreID"] = value;
            }
        }
        /// <summary>
        /// å½“前图像序号(1~n)
        /// </summary>
        public int CurrentImageIndex
        {
            get
            {
                if (Params.Outputs.ContainsKey("CurrentImageIndex"))
                    return Convert.ToInt32(Params.Outputs["CurrentImageIndex"]);
                return 0;
            }
            private set
            {
                Params.Outputs["CurrentImageIndex"] = value;
            }
        }
        /// <summary>
        /// æ˜¯å¦å®Œæˆè½®èƒŽ
        /// </summary>
        public bool IsTyreComplete
        {
            get
            {
                if (Params.Outputs.ContainsKey("IsTyreComplete"))
                    return Convert.ToBoolean(Params.Outputs["IsTyreComplete"]);
                return false;
            }
            private set
            {
                Params.Outputs["IsTyreComplete"] = value;
            }
        }
        /// <summary>
        /// è½®èƒŽç»“æžœ
        /// </summary>
        public bool TyreResult
        {
            get
            {
                if (Params.Outputs.ContainsKey("TyreResult"))
                    return Convert.ToBoolean(Params.Outputs["TyreResult"]);
                return false;
            }
            private set
            {
                Params.Outputs["TyreResult"] = value;
            }
        }
        /// <summary>
        /// è½®èƒŽæ€»æ•°
        /// </summary>
        public int TyreTotal
        {
            get
            {
                if (Params.Outputs.ContainsKey("TyreTotal"))
                    return Convert.ToInt32(Params.Outputs["TyreTotal"]);
                return 0;
            }
            private set
            {
                Params.Outputs["TyreTotal"] = value;
            }
        }
        /// <summary>
        /// è½®èƒŽOK数
        /// </summary>
        public int TyreOK
        {
            get
            {
                if (Params.Outputs.ContainsKey("TyreOK"))
                    return Convert.ToInt32(Params.Outputs["TyreOK"]);
                return 0;
            }
            private set
            {
                Params.Outputs["TyreOK"] = value;
            }
        }
        /// <summary>
        /// è½®èƒŽNG数
        /// </summary>
        public int TyreNG
        {
            get
            {
                if (Params.Outputs.ContainsKey("TyreNG"))
                    return Convert.ToInt32(Params.Outputs["TyreNG"]);
                return 0;
            }
            private set
            {
                Params.Outputs["TyreNG"] = value;
            }
        }
        /// <summary>
        /// è‰¯å“çއ
        /// </summary>
        public double TyreRateOK
        {
            get
            {
                if (Params.Outputs.ContainsKey("TyreRateOK"))
                    return Convert.ToDouble(Params.Outputs["TyreRateOK"]);
                return 0;
            }
            private set
            {
                Params.Outputs["TyreRateOK"] = value;
            }
        }
        #endregion
        #region ç§æœ‰å­—段
        /// <summary>
        /// è½®èƒŽç»Ÿè®¡å™¨å®žä¾‹
        /// </summary>
        private TyreStatistics? _tyreStatistics;
        /// <summary>
        /// è¾“入的图像结果(从前置节点获取)
        /// </summary>
        private bool _inputImageResult = true;
        #endregion
        #region æž„造方法
        public TyreCounterProcess()
        {
            strProcessClass = "LB_VisionProcesses.Processes.TyreCounterProcess";
            _tyreStatistics = new TyreStatistics();
            InitParams();
        }
        /// <summary>
        /// åˆå§‹åŒ–参数
        /// </summary>
        private void InitParams()
        {
            // è¾“入参数
            if (!Params.Inputs.ContainsKey("ImagesPerTyre"))
                Params.Inputs.Add("ImagesPerTyre", 8);
            if (!Params.Inputs.ContainsKey("JudgeRule"))
                Params.Inputs.Add("JudgeRule", TyreJudgeRule.AnyNG.ToString());
            if (!Params.Inputs.ContainsKey("AutoReset"))
                Params.Inputs.Add("AutoReset", true);
            // è¾“出参数
            if (!Params.Outputs.ContainsKey("CurrentTyreID"))
                Params.Outputs.Add("CurrentTyreID", 1);
            if (!Params.Outputs.ContainsKey("CurrentImageIndex"))
                Params.Outputs.Add("CurrentImageIndex", 0);
            if (!Params.Outputs.ContainsKey("IsTyreComplete"))
                Params.Outputs.Add("IsTyreComplete", false);
            if (!Params.Outputs.ContainsKey("TyreResult"))
                Params.Outputs.Add("TyreResult", false);
            if (!Params.Outputs.ContainsKey("TyreTotal"))
                Params.Outputs.Add("TyreTotal", 0);
            if (!Params.Outputs.ContainsKey("TyreOK"))
                Params.Outputs.Add("TyreOK", 0);
            if (!Params.Outputs.ContainsKey("TyreNG"))
                Params.Outputs.Add("TyreNG", 0);
            if (!Params.Outputs.ContainsKey("TyreRateOK"))
                Params.Outputs.Add("TyreRateOK", 0.0);
        }
        #endregion
        #region æ ¸å¿ƒæ–¹æ³•
        /// <summary>
        /// è¿è¡Œè½®èƒŽè®¡æ•°é€»è¾‘
        /// </summary>
        public override bool Run()
        {
            DateTime startTime = DateTime.Now;
            try
            {
                // èŽ·å–è¾“å…¥ç»“æžœï¼ˆä»Žå‰ç½®èŠ‚ç‚¹çš„Result参数)
                GetInputResult();
                // æ›´æ–°ç»Ÿè®¡å™¨é…ç½®
                _tyreStatistics.ImagesPerTyre = ImagesPerTyre;
                _tyreStatistics.JudgeRule = JudgeRule;
                // æ·»åŠ å›¾åƒç»“æžœ
                var result = _tyreStatistics.AddImageResult(_inputImageResult);
                // æ›´æ–°è¾“出参数
                UpdateOutputs(result);
                // è®¾ç½®ç»“æžœ
                Result = true;
                Msg = result.Message;
                RunTime = (DateTime.Now - startTime).TotalMilliseconds;
                return true;
            }
            catch (Exception ex)
            {
                Result = false;
                Msg = $"轮胎计数运行失败: {ex.Message}";
                RunTime = (DateTime.Now - startTime).TotalMilliseconds;
                return false;
            }
        }
        /// <summary>
        /// èŽ·å–è¾“å…¥ç»“æžœï¼ˆä»Žå‰ç½®èŠ‚ç‚¹ä¼ é€’çš„Result)
        /// </summary>
        private void GetInputResult()
        {
            // å¦‚æžœInputImage是bool类型,说明前置节点传递了结果
            if (InputImage is bool boolResult)
            {
                _inputImageResult = boolResult;
            }
            else
            {
                // é»˜è®¤è®¤ä¸ºOK
                _inputImageResult = true;
            }
        }
        /// <summary>
        /// æ›´æ–°è¾“出参数
        /// </summary>
        private void UpdateOutputs(TyreCountResult result)
        {
            CurrentTyreID = result.TyreID > 0 ? result.TyreID : _tyreStatistics.CurrentTyreID;
            CurrentImageIndex = result.CurrentImageIndex;
            IsTyreComplete = result.IsTyreComplete;
            TyreResult = result.TyreResult;
            TyreTotal = _tyreStatistics.TyreTotal;
            TyreOK = _tyreStatistics.TyreOK;
            TyreNG = _tyreStatistics.TyreNG;
            TyreRateOK = _tyreStatistics.TyreRateOK;
        }
        /// <summary>
        /// åˆå§‹åŒ–运行参数
        /// </summary>
        public override void InitRunParams()
        {
            base.InitRunParams();
            _inputImageResult = true;
        }
        /// <summary>
        /// é‡ç½®è½®èƒŽè®¡æ•°
        /// </summary>
        public void ResetTyreCount()
        {
            _tyreStatistics?.Reset();
            UpdateOutputs(new TyreCountResult());
        }
        /// <summary>
        /// èŽ·å–ç»Ÿè®¡ä¿¡æ¯
        /// </summary>
        public string GetStatisticsInfo()
        {
            return _tyreStatistics?.GetStatisticsInfo() ?? "统计器未初始化";
        }
        /// <summary>
        /// èŽ·å–è¿›åº¦ä¿¡æ¯
        /// </summary>
        public string GetProgressInfo()
        {
            return _tyreStatistics?.GetProgressInfo() ?? "统计器未初始化";
        }
        #endregion
        #region é‡å†™æ–¹æ³•
        public override bool Load(string fullPath = null)
        {
            bool result = base.Load(fullPath);
            if (result)
            {
                // åŠ è½½é…ç½®åŽé‡æ–°åˆå§‹åŒ–ç»Ÿè®¡å™¨
                _tyreStatistics = new TyreStatistics(ImagesPerTyre, JudgeRule);
            }
            return result;
        }
        public override bool Save(string filePath = null)
        {
            return base.Save(filePath);
        }
        public override object Clone()
        {
            TyreCounterProcess clone = (TyreCounterProcess)MemberwiseClone();
            clone._tyreStatistics = new TyreStatistics(ImagesPerTyre, JudgeRule);
            return clone;
        }
        public override void Dispose()
        {
            _tyreStatistics = null;
            base.Dispose();
        }
        #endregion
    }
}
LB_VisionProcesses/Processes/TyreCounter/TyreCounterProcessEdit.Designer.cs
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,567 @@
namespace LB_VisionProcesses.Processes
{
    partial class TyreCounterProcessEdit
    {
        /// <summary>
        /// å¿…需的设计器变量。
        /// </summary>
        private System.ComponentModel.IContainer components = null;
        /// <summary>
        /// æ¸…理所有正在使用的资源。
        /// </summary>
        /// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }
        #region ç»„件设计器生成的代码
        /// <summary>
        /// è®¾è®¡å™¨æ”¯æŒæ‰€éœ€çš„æ–¹æ³• - ä¸è¦ä¿®æ”¹
        /// ä½¿ç”¨ä»£ç ç¼–辑器修改此方法的内容。
        /// </summary>
        private void InitializeComponent()
        {
            splitContainer1 = new SplitContainer();
            groupBoxInputs = new GroupBox();
            dataGridInputs = new DataGridView();
            groupBoxConfig = new GroupBox();
            tableLayoutPanelConfig = new TableLayoutPanel();
            lblImagesPerTyre = new Label();
            numericUpDownImagesPerTyre = new NumericUpDown();
            lblJudgeRule = new Label();
            comboBoxJudgeRule = new ComboBox();
            checkBoxAutoReset = new CheckBox();
            groupBoxStatistics = new GroupBox();
            tableLayoutPanelStats = new TableLayoutPanel();
            lblCurrentTyreID = new Label();
            txtCurrentTyreID = new TextBox();
            lblCurrentImageIndex = new Label();
            txtCurrentImageIndex = new TextBox();
            lblTyreTotal = new Label();
            txtTyreTotal = new TextBox();
            lblTyreOK = new Label();
            txtTyreOK = new TextBox();
            lblTyreNG = new Label();
            txtTyreNG = new TextBox();
            lblTyreRateOK = new Label();
            txtTyreRateOK = new TextBox();
            groupBoxOutputs = new GroupBox();
            dataGridOutputs = new DataGridView();
            topToolStrip = new ToolStrip();
            btnRun = new ToolStripButton();
            btnSave = new ToolStripButton();
            btnReset = new ToolStripButton();
            statusStrip = new StatusStrip();
            lblResult = new ToolStripStatusLabel();
            lblMsg = new ToolStripStatusLabel();
            ((System.ComponentModel.ISupportInitialize)splitContainer1).BeginInit();
            splitContainer1.Panel1.SuspendLayout();
            splitContainer1.Panel2.SuspendLayout();
            splitContainer1.SuspendLayout();
            groupBoxInputs.SuspendLayout();
            ((System.ComponentModel.ISupportInitialize)dataGridInputs).BeginInit();
            groupBoxConfig.SuspendLayout();
            tableLayoutPanelConfig.SuspendLayout();
            ((System.ComponentModel.ISupportInitialize)numericUpDownImagesPerTyre).BeginInit();
            groupBoxStatistics.SuspendLayout();
            tableLayoutPanelStats.SuspendLayout();
            groupBoxOutputs.SuspendLayout();
            ((System.ComponentModel.ISupportInitialize)dataGridOutputs).BeginInit();
            topToolStrip.SuspendLayout();
            statusStrip.SuspendLayout();
            SuspendLayout();
            //
            // splitContainer1
            //
            splitContainer1.BackColor = Color.FromArgb(32, 41, 50);
            splitContainer1.Dock = DockStyle.Fill;
            splitContainer1.Location = new Point(0, 31);
            splitContainer1.Name = "splitContainer1";
            //
            // splitContainer1.Panel1
            //
            splitContainer1.Panel1.Controls.Add(groupBoxInputs);
            //
            // splitContainer1.Panel2
            //
            splitContainer1.Panel2.Controls.Add(groupBoxOutputs);
            splitContainer1.Size = new Size(884, 458);
            splitContainer1.SplitterDistance = 294;
            splitContainer1.TabIndex = 0;
            //
            // groupBoxInputs
            //
            groupBoxInputs.BackColor = Color.FromArgb(32, 41, 50);
            groupBoxInputs.Controls.Add(dataGridInputs);
            groupBoxInputs.Dock = DockStyle.Fill;
            groupBoxInputs.Font = new Font("Microsoft YaHei UI", 12F, FontStyle.Regular, GraphicsUnit.Point, 134);
            groupBoxInputs.ForeColor = SystemColors.Control;
            groupBoxInputs.Location = new Point(0, 0);
            groupBoxInputs.Name = "groupBoxInputs";
            groupBoxInputs.Size = new Size(294, 458);
            groupBoxInputs.TabIndex = 0;
            groupBoxInputs.TabStop = false;
            groupBoxInputs.Text = "输入参数";
            //
            // dataGridInputs
            //
            dataGridInputs.BackgroundColor = Color.FromArgb(32, 46, 50);
            dataGridInputs.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
            dataGridInputs.Dock = DockStyle.Fill;
            dataGridInputs.GridColor = SystemColors.Control;
            dataGridInputs.Location = new Point(3, 24);
            dataGridInputs.Name = "dataGridInputs";
            dataGridInputs.Size = new Size(288, 431);
            dataGridInputs.TabIndex = 0;
            //
            // groupBoxConfig
            //
            groupBoxConfig.BackColor = Color.FromArgb(32, 41, 50);
            groupBoxConfig.Controls.Add(tableLayoutPanelConfig);
            groupBoxConfig.Dock = DockStyle.Top;
            groupBoxConfig.Font = new Font("Microsoft YaHei UI", 12F, FontStyle.Regular, GraphicsUnit.Point, 134);
            groupBoxConfig.ForeColor = SystemColors.Control;
            groupBoxConfig.Location = new Point(0, 0);
            groupBoxConfig.Name = "groupBoxConfig";
            groupBoxConfig.Size = new Size(586, 180);
            groupBoxConfig.TabIndex = 1;
            groupBoxConfig.TabStop = false;
            groupBoxConfig.Text = "配置";
            //
            // tableLayoutPanelConfig
            //
            tableLayoutPanelConfig.ColumnCount = 2;
            tableLayoutPanelConfig.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 150F));
            tableLayoutPanelConfig.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100F));
            tableLayoutPanelConfig.Controls.Add(lblImagesPerTyre, 0, 0);
            tableLayoutPanelConfig.Controls.Add(numericUpDownImagesPerTyre, 1, 0);
            tableLayoutPanelConfig.Controls.Add(lblJudgeRule, 0, 1);
            tableLayoutPanelConfig.Controls.Add(comboBoxJudgeRule, 1, 1);
            tableLayoutPanelConfig.Controls.Add(checkBoxAutoReset, 1, 2);
            tableLayoutPanelConfig.Dock = DockStyle.Fill;
            tableLayoutPanelConfig.Location = new Point(3, 24);
            tableLayoutPanelConfig.Name = "tableLayoutPanelConfig";
            tableLayoutPanelConfig.RowCount = 3;
            tableLayoutPanelConfig.RowStyles.Add(new RowStyle(SizeType.Absolute, 40F));
            tableLayoutPanelConfig.RowStyles.Add(new RowStyle(SizeType.Absolute, 40F));
            tableLayoutPanelConfig.RowStyles.Add(new RowStyle(SizeType.Absolute, 40F));
            tableLayoutPanelConfig.Size = new Size(580, 153);
            tableLayoutPanelConfig.TabIndex = 0;
            //
            // lblImagesPerTyre
            //
            lblImagesPerTyre.AutoSize = true;
            lblImagesPerTyre.Dock = DockStyle.Fill;
            lblImagesPerTyre.Location = new Point(3, 0);
            lblImagesPerTyre.Name = "lblImagesPerTyre";
            lblImagesPerTyre.Size = new Size(144, 40);
            lblImagesPerTyre.TabIndex = 0;
            lblImagesPerTyre.Text = "每张轮胎图像数:";
            lblImagesPerTyre.TextAlign = ContentAlignment.MiddleLeft;
            //
            // numericUpDownImagesPerTyre
            //
            numericUpDownImagesPerTyre.Location = new Point(153, 3);
            numericUpDownImagesPerTyre.Maximum = new decimal(new int[] { 64, 0, 0, 0 });
            numericUpDownImagesPerTyre.Minimum = new decimal(new int[] { 1, 0, 0, 0 });
            numericUpDownImagesPerTyre.Name = "numericUpDownImagesPerTyre";
            numericUpDownImagesPerTyre.Size = new Size(100, 29);
            numericUpDownImagesPerTyre.TabIndex = 1;
            numericUpDownImagesPerTyre.Value = new decimal(new int[] { 8, 0, 0, 0 });
            //
            // lblJudgeRule
            //
            lblJudgeRule.AutoSize = true;
            lblJudgeRule.Dock = DockStyle.Fill;
            lblJudgeRule.Location = new Point(3, 40);
            lblJudgeRule.Name = "lblJudgeRule";
            lblJudgeRule.Size = new Size(144, 40);
            lblJudgeRule.TabIndex = 2;
            lblJudgeRule.Text = "判定规则:";
            lblJudgeRule.TextAlign = ContentAlignment.MiddleLeft;
            //
            // comboBoxJudgeRule
            //
            comboBoxJudgeRule.DropDownStyle = ComboBoxStyle.DropDownList;
            comboBoxJudgeRule.FormattingEnabled = true;
            comboBoxJudgeRule.Items.AddRange(new object[] { "AnyNG", "AllOK", "MajorityVote" });
            comboBoxJudgeRule.Location = new Point(153, 43);
            comboBoxJudgeRule.Name = "comboBoxJudgeRule";
            comboBoxJudgeRule.Size = new Size(160, 29);
            comboBoxJudgeRule.TabIndex = 3;
            //
            // checkBoxAutoReset
            //
            checkBoxAutoReset.AutoSize = true;
            checkBoxAutoReset.Checked = true;
            checkBoxAutoReset.CheckState = CheckState.Checked;
            checkBoxAutoReset.Location = new Point(153, 83);
            checkBoxAutoReset.Name = "checkBoxAutoReset";
            checkBoxAutoReset.Size = new Size(161, 25);
            checkBoxAutoReset.TabIndex = 4;
            checkBoxAutoReset.Text = "完成轮胎自动重置";
            checkBoxAutoReset.UseVisualStyleBackColor = true;
            //
            // groupBoxStatistics
            //
            groupBoxStatistics.BackColor = Color.FromArgb(32, 41, 50);
            groupBoxStatistics.Controls.Add(tableLayoutPanelStats);
            groupBoxStatistics.Dock = DockStyle.Fill;
            groupBoxStatistics.Font = new Font("Microsoft YaHei UI", 12F, FontStyle.Regular, GraphicsUnit.Point, 134);
            groupBoxStatistics.ForeColor = SystemColors.Control;
            groupBoxStatistics.Location = new Point(0, 180);
            groupBoxStatistics.Name = "groupBoxStatistics";
            groupBoxStatistics.Size = new Size(586, 278);
            groupBoxStatistics.TabIndex = 2;
            groupBoxStatistics.TabStop = false;
            groupBoxStatistics.Text = "统计信息";
            //
            // tableLayoutPanelStats
            //
            tableLayoutPanelStats.ColumnCount = 2;
            tableLayoutPanelStats.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 150F));
            tableLayoutPanelStats.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100F));
            tableLayoutPanelStats.Controls.Add(lblCurrentTyreID, 0, 0);
            tableLayoutPanelStats.Controls.Add(txtCurrentTyreID, 1, 0);
            tableLayoutPanelStats.Controls.Add(lblCurrentImageIndex, 0, 1);
            tableLayoutPanelStats.Controls.Add(txtCurrentImageIndex, 1, 1);
            tableLayoutPanelStats.Controls.Add(lblTyreTotal, 0, 2);
            tableLayoutPanelStats.Controls.Add(txtTyreTotal, 1, 2);
            tableLayoutPanelStats.Controls.Add(lblTyreOK, 0, 3);
            tableLayoutPanelStats.Controls.Add(txtTyreOK, 1, 3);
            tableLayoutPanelStats.Controls.Add(lblTyreNG, 0, 4);
            tableLayoutPanelStats.Controls.Add(txtTyreNG, 1, 4);
            tableLayoutPanelStats.Controls.Add(lblTyreRateOK, 0, 5);
            tableLayoutPanelStats.Controls.Add(txtTyreRateOK, 1, 5);
            tableLayoutPanelStats.Dock = DockStyle.Fill;
            tableLayoutPanelStats.Location = new Point(3, 24);
            tableLayoutPanelStats.Name = "tableLayoutPanelStats";
            tableLayoutPanelStats.RowCount = 6;
            tableLayoutPanelStats.RowStyles.Add(new RowStyle(SizeType.Absolute, 35F));
            tableLayoutPanelStats.RowStyles.Add(new RowStyle(SizeType.Absolute, 35F));
            tableLayoutPanelStats.RowStyles.Add(new RowStyle(SizeType.Absolute, 35F));
            tableLayoutPanelStats.RowStyles.Add(new RowStyle(SizeType.Absolute, 35F));
            tableLayoutPanelStats.RowStyles.Add(new RowStyle(SizeType.Absolute, 35F));
            tableLayoutPanelStats.RowStyles.Add(new RowStyle(SizeType.Absolute, 35F));
            tableLayoutPanelStats.Size = new Size(580, 251);
            tableLayoutPanelStats.TabIndex = 0;
            //
            // lblCurrentTyreID
            //
            lblCurrentTyreID.AutoSize = true;
            lblCurrentTyreID.Dock = DockStyle.Fill;
            lblCurrentTyreID.Location = new Point(3, 0);
            lblCurrentTyreID.Name = "lblCurrentTyreID";
            lblCurrentTyreID.Size = new Size(144, 35);
            lblCurrentTyreID.TabIndex = 0;
            lblCurrentTyreID.Text = "当前轮胎ID:";
            lblCurrentTyreID.TextAlign = ContentAlignment.MiddleLeft;
            //
            // txtCurrentTyreID
            //
            txtCurrentTyreID.BackColor = Color.FromArgb(32, 46, 50);
            txtCurrentTyreID.BorderStyle = BorderStyle.FixedSingle;
            txtCurrentTyreID.ForeColor = SystemColors.Control;
            txtCurrentTyreID.Location = new Point(153, 3);
            txtCurrentTyreID.Name = "txtCurrentTyreID";
            txtCurrentTyreID.ReadOnly = true;
            txtCurrentTyreID.Size = new Size(100, 29);
            txtCurrentTyreID.TabIndex = 1;
            txtCurrentTyreID.Text = "1";
            //
            // lblCurrentImageIndex
            //
            lblCurrentImageIndex.AutoSize = true;
            lblCurrentImageIndex.Dock = DockStyle.Fill;
            lblCurrentImageIndex.Location = new Point(3, 35);
            lblCurrentImageIndex.Name = "lblCurrentImageIndex";
            lblCurrentImageIndex.Size = new Size(144, 35);
            lblCurrentImageIndex.TabIndex = 2;
            lblCurrentImageIndex.Text = "当前图像序号:";
            lblCurrentImageIndex.TextAlign = ContentAlignment.MiddleLeft;
            //
            // txtCurrentImageIndex
            //
            txtCurrentImageIndex.BackColor = Color.FromArgb(32, 46, 50);
            txtCurrentImageIndex.BorderStyle = BorderStyle.FixedSingle;
            txtCurrentImageIndex.ForeColor = SystemColors.Control;
            txtCurrentImageIndex.Location = new Point(153, 38);
            txtCurrentImageIndex.Name = "txtCurrentImageIndex";
            txtCurrentImageIndex.ReadOnly = true;
            txtCurrentImageIndex.Size = new Size(100, 29);
            txtCurrentImageIndex.TabIndex = 3;
            txtCurrentImageIndex.Text = "0/8";
            //
            // lblTyreTotal
            //
            lblTyreTotal.AutoSize = true;
            lblTyreTotal.Dock = DockStyle.Fill;
            lblTyreTotal.Location = new Point(3, 70);
            lblTyreTotal.Name = "lblTyreTotal";
            lblTyreTotal.Size = new Size(144, 35);
            lblTyreTotal.TabIndex = 4;
            lblTyreTotal.Text = "轮胎总数:";
            lblTyreTotal.TextAlign = ContentAlignment.MiddleLeft;
            //
            // txtTyreTotal
            //
            txtTyreTotal.BackColor = Color.FromArgb(32, 46, 50);
            txtTyreTotal.BorderStyle = BorderStyle.FixedSingle;
            txtTyreTotal.ForeColor = SystemColors.Control;
            txtTyreTotal.Location = new Point(153, 73);
            txtTyreTotal.Name = "txtTyreTotal";
            txtTyreTotal.ReadOnly = true;
            txtTyreTotal.Size = new Size(100, 29);
            txtTyreTotal.TabIndex = 5;
            txtTyreTotal.Text = "0";
            //
            // lblTyreOK
            //
            lblTyreOK.AutoSize = true;
            lblTyreOK.Dock = DockStyle.Fill;
            lblTyreOK.ForeColor = Color.LightGreen;
            lblTyreOK.Location = new Point(3, 105);
            lblTyreOK.Name = "lblTyreOK";
            lblTyreOK.Size = new Size(144, 35);
            lblTyreOK.TabIndex = 6;
            lblTyreOK.Text = "轮胎OK:";
            lblTyreOK.TextAlign = ContentAlignment.MiddleLeft;
            //
            // txtTyreOK
            //
            txtTyreOK.BackColor = Color.FromArgb(32, 46, 50);
            txtTyreOK.BorderStyle = BorderStyle.FixedSingle;
            txtTyreOK.ForeColor = Color.LightGreen;
            txtTyreOK.Location = new Point(153, 108);
            txtTyreOK.Name = "txtTyreOK";
            txtTyreOK.ReadOnly = true;
            txtTyreOK.Size = new Size(100, 29);
            txtTyreOK.TabIndex = 7;
            txtTyreOK.Text = "0";
            //
            // lblTyreNG
            //
            lblTyreNG.AutoSize = true;
            lblTyreNG.Dock = DockStyle.Fill;
            lblTyreNG.ForeColor = Color.LightCoral;
            lblTyreNG.Location = new Point(3, 140);
            lblTyreNG.Name = "lblTyreNG";
            lblTyreNG.Size = new Size(144, 35);
            lblTyreNG.TabIndex = 8;
            lblTyreNG.Text = "轮胎NG:";
            lblTyreNG.TextAlign = ContentAlignment.MiddleLeft;
            //
            // txtTyreNG
            //
            txtTyreNG.BackColor = Color.FromArgb(32, 46, 50);
            txtTyreNG.BorderStyle = BorderStyle.FixedSingle;
            txtTyreNG.ForeColor = Color.LightCoral;
            txtTyreNG.Location = new Point(153, 143);
            txtTyreNG.Name = "txtTyreNG";
            txtTyreNG.ReadOnly = true;
            txtTyreNG.Size = new Size(100, 29);
            txtTyreNG.TabIndex = 9;
            txtTyreNG.Text = "0";
            //
            // lblTyreRateOK
            //
            lblTyreRateOK.AutoSize = true;
            lblTyreRateOK.Dock = DockStyle.Fill;
            lblTyreRateOK.Location = new Point(3, 175);
            lblTyreRateOK.Name = "lblTyreRateOK";
            lblTyreRateOK.Size = new Size(144, 35);
            lblTyreRateOK.TabIndex = 10;
            lblTyreRateOK.Text = "良品率:";
            lblTyreRateOK.TextAlign = ContentAlignment.MiddleLeft;
            //
            // txtTyreRateOK
            //
            txtTyreRateOK.BackColor = Color.FromArgb(32, 46, 50);
            txtTyreRateOK.BorderStyle = BorderStyle.FixedSingle;
            txtTyreRateOK.ForeColor = SystemColors.Control;
            txtTyreRateOK.Location = new Point(153, 178);
            txtTyreRateOK.Name = "txtTyreRateOK";
            txtTyreRateOK.ReadOnly = true;
            txtTyreRateOK.Size = new Size(100, 29);
            txtTyreRateOK.TabIndex = 11;
            txtTyreRateOK.Text = "0.00%";
            //
            // groupBoxOutputs
            //
            groupBoxOutputs.BackColor = Color.FromArgb(32, 41, 50);
            groupBoxOutputs.Controls.Add(groupBoxStatistics);
            groupBoxOutputs.Controls.Add(groupBoxConfig);
            groupBoxOutputs.Dock = DockStyle.Fill;
            groupBoxOutputs.Font = new Font("Microsoft YaHei UI", 12F, FontStyle.Regular, GraphicsUnit.Point, 134);
            groupBoxOutputs.ForeColor = SystemColors.Control;
            groupBoxOutputs.Location = new Point(0, 0);
            groupBoxOutputs.Name = "groupBoxOutputs";
            groupBoxOutputs.Size = new Size(586, 458);
            groupBoxOutputs.TabIndex = 0;
            groupBoxOutputs.TabStop = false;
            groupBoxOutputs.Text = "输出与配置";
            //
            // dataGridOutputs
            //
            dataGridOutputs.BackgroundColor = Color.FromArgb(32, 46, 50);
            dataGridOutputs.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
            dataGridOutputs.Dock = DockStyle.Fill;
            dataGridOutputs.GridColor = SystemColors.Control;
            dataGridOutputs.Location = new Point(3, 24);
            dataGridOutputs.Name = "dataGridOutputs";
            dataGridOutputs.Size = new Size(580, 431);
            dataGridOutputs.TabIndex = 0;
            //
            // topToolStrip
            //
            topToolStrip.BackColor = Color.FromArgb(32, 41, 50);
            topToolStrip.GripStyle = ToolStripGripStyle.Hidden;
            topToolStrip.Items.AddRange(new ToolStripItem[] { btnRun, btnSave, btnReset });
            topToolStrip.Location = new Point(0, 0);
            topToolStrip.Name = "topToolStrip";
            topToolStrip.Size = new Size(884, 31);
            topToolStrip.TabIndex = 1;
            topToolStrip.Text = "toolStrip1";
            //
            // btnRun
            //
            btnRun.DisplayStyle = ToolStripItemDisplayStyle.Text;
            btnRun.Font = new Font("Microsoft YaHei UI", 10F, FontStyle.Regular, GraphicsUnit.Point, 134);
            btnRun.ForeColor = SystemColors.Control;
            btnRun.ImageTransparentColor = Color.Magenta;
            btnRun.Name = "btnRun";
            btnRun.Size = new Size(41, 28);
            btnRun.Text = "运行";
            btnRun.Click += btnRun_Click;
            //
            // btnSave
            //
            btnSave.DisplayStyle = ToolStripItemDisplayStyle.Text;
            btnSave.Font = new Font("Microsoft YaHei UI", 10F, FontStyle.Regular, GraphicsUnit.Point, 134);
            btnSave.ForeColor = SystemColors.Control;
            btnSave.ImageTransparentColor = Color.Magenta;
            btnSave.Name = "btnSave";
            btnSave.Size = new Size(41, 28);
            btnSave.Text = "保存";
            btnSave.Click += btnSave_Click;
            //
            // btnReset
            //
            btnReset.DisplayStyle = ToolStripItemDisplayStyle.Text;
            btnReset.Font = new Font("Microsoft YaHei UI", 10F, FontStyle.Regular, GraphicsUnit.Point, 134);
            btnReset.ForeColor = SystemColors.Control;
            btnReset.ImageTransparentColor = Color.Magenta;
            btnReset.Name = "btnReset";
            btnReset.Size = new Size(73, 28);
            btnReset.Text = "重置计数";
            btnReset.Click += btnReset_Click;
            //
            // statusStrip
            //
            statusStrip.BackColor = Color.FromArgb(32, 41, 50);
            statusStrip.Items.AddRange(new ToolStripItem[] { lblResult, lblMsg });
            statusStrip.Location = new Point(0, 489);
            statusStrip.Name = "statusStrip";
            statusStrip.Size = new Size(884, 30);
            statusStrip.TabIndex = 2;
            statusStrip.Text = "statusStrip1";
            //
            // lblResult
            //
            lblResult.AutoSize = false;
            lblResult.BackColor = Color.FromArgb(32, 41, 50);
            lblResult.Font = new Font("Microsoft YaHei UI", 10F, FontStyle.Regular, GraphicsUnit.Point, 134);
            lblResult.ForeColor = SystemColors.Control;
            lblResult.Name = "lblResult";
            lblResult.Size = new Size(100, 25);
            lblResult.Text = "结果: --";
            //
            // lblMsg
            //
            lblMsg.BackColor = Color.FromArgb(32, 41, 50);
            lblMsg.Font = new Font("Microsoft YaHei UI", 10F, FontStyle.Regular, GraphicsUnit.Point, 134);
            lblMsg.ForeColor = SystemColors.Control;
            lblMsg.Name = "lblMsg";
            lblMsg.Size = new Size(769, 25);
            lblMsg.Spring = true;
            lblMsg.Text = "就绪";
            lblMsg.TextAlign = ContentAlignment.MiddleLeft;
            //
            // TyreCounterProcessEdit
            //
            AutoScaleDimensions = new SizeF(9F, 20F);
            AutoScaleMode = AutoScaleMode.Font;
            BackColor = Color.FromArgb(32, 41, 50);
            Controls.Add(splitContainer1);
            Controls.Add(topToolStrip);
            Controls.Add(statusStrip);
            Name = "TyreCounterProcessEdit";
            Size = new Size(884, 519);
            Load += TyreCounterProcessEdit_Load;
            splitContainer1.Panel1.ResumeLayout(false);
            splitContainer1.Panel2.ResumeLayout(false);
            ((System.ComponentModel.ISupportInitialize)splitContainer1).EndInit();
            splitContainer1.ResumeLayout(false);
            groupBoxInputs.ResumeLayout(false);
            ((System.ComponentModel.ISupportInitialize)dataGridInputs).EndInit();
            groupBoxConfig.ResumeLayout(false);
            tableLayoutPanelConfig.ResumeLayout(false);
            tableLayoutPanelConfig.PerformLayout();
            ((System.ComponentModel.ISupportInitialize)numericUpDownImagesPerTyre).EndInit();
            groupBoxStatistics.ResumeLayout(false);
            tableLayoutPanelStats.ResumeLayout(false);
            tableLayoutPanelStats.PerformLayout();
            groupBoxOutputs.ResumeLayout(false);
            ((System.ComponentModel.ISupportInitialize)dataGridOutputs).EndInit();
            topToolStrip.ResumeLayout(false);
            topToolStrip.PerformLayout();
            statusStrip.ResumeLayout(false);
            statusStrip.PerformLayout();
            ResumeLayout(false);
            statusStrip.PerformLayout();
        }
        #endregion
        private SplitContainer splitContainer1;
        private GroupBox groupBoxInputs;
        private DataGridView dataGridInputs;
        private GroupBox groupBoxOutputs;
        private DataGridView dataGridOutputs;
        private ToolStrip topToolStrip;
        private ToolStripButton btnRun;
        private ToolStripButton btnSave;
        private ToolStripButton btnReset;
        private StatusStrip statusStrip;
        private ToolStripStatusLabel lblResult;
        private ToolStripStatusLabel lblMsg;
        private GroupBox groupBoxConfig;
        private TableLayoutPanel tableLayoutPanelConfig;
        private Label lblImagesPerTyre;
        private NumericUpDown numericUpDownImagesPerTyre;
        private Label lblJudgeRule;
        private ComboBox comboBoxJudgeRule;
        private CheckBox checkBoxAutoReset;
        private GroupBox groupBoxStatistics;
        private TableLayoutPanel tableLayoutPanelStats;
        private Label lblCurrentTyreID;
        private TextBox txtCurrentTyreID;
        private Label lblCurrentImageIndex;
        private TextBox txtCurrentImageIndex;
        private Label lblTyreTotal;
        private TextBox txtTyreTotal;
        private Label lblTyreOK;
        private TextBox txtTyreOK;
        private Label lblTyreNG;
        private TextBox txtTyreNG;
        private Label lblTyreRateOK;
        private TextBox txtTyreRateOK;
    }
}
LB_VisionProcesses/Processes/TyreCounter/TyreCounterProcessEdit.cs
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,161 @@
using LB_VisionProcesses.Alogrithms;
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;
namespace LB_VisionProcesses.Processes
{
    /// <summary>
    /// è½®èƒŽè®¡æ•°å·¥å…·ç¼–辑器
    /// </summary>
    public partial class TyreCounterProcessEdit : TAlgorithmEdit
    {
        DataTable DataTableInputs = new DataTable();
        DataTable DataTableOutputs = new DataTable();
        public TyreCounterProcessEdit(TyreCounterProcess subject = null)
        {
            InitializeComponent();
            if (subject == null)
                subject = new TyreCounterProcess();
            this.Subject = subject;
        }
        private void TyreCounterProcessEdit_Load(object sender, EventArgs e)
        {
            LoadParas();
        }
        /// <summary>
        /// åŠ è½½å‚æ•°
        /// </summary>
        public override void LoadParas()
        {
            if (Subject is TyreCounterProcess counter)
            {
                // åŠ è½½é…ç½®å‚æ•°
                numericUpDownImagesPerTyre.Value = counter.ImagesPerTyre;
                comboBoxJudgeRule.SelectedItem = counter.JudgeRule.ToString();
                checkBoxAutoReset.Checked = counter.AutoReset;
                // åŠ è½½ç»Ÿè®¡ä¿¡æ¯
                UpdateStatistics();
                // ç»‘定输入参数
                DataTableInputs.Columns.Add("Key", typeof(string));
                DataTableInputs.Columns.Add("Value", typeof(object));
                DataTableInputs.Rows.Clear();
                var inputs = new Dictionary<string, object>
                {
                    { "ImagesPerTyre", counter.ImagesPerTyre },
                    { "JudgeRule", counter.JudgeRule.ToString() },
                    { "AutoReset", counter.AutoReset }
                };
                foreach (var item in inputs)
                    DataTableInputs.Rows.Add(item.Key, item.Value);
                dataGridInputs.DataSource = DataTableInputs;
                // ç»‘定输出参数
                DataTableOutputs.Columns.Add("Key", typeof(string));
                DataTableOutputs.Columns.Add("Value", typeof(object));
                DataTableOutputs.Rows.Clear();
                var outputs = new Dictionary<string, object>
                {
                    { "CurrentTyreID", counter.CurrentTyreID },
                    { "CurrentImageIndex", counter.CurrentImageIndex },
                    { "IsTyreComplete", counter.IsTyreComplete },
                    { "TyreResult", counter.TyreResult },
                    { "TyreTotal", counter.TyreTotal },
                    { "TyreOK", counter.TyreOK },
                    { "TyreNG", counter.TyreNG },
                    { "TyreRateOK", counter.TyreRateOK }
                };
                foreach (var item in outputs)
                    DataTableOutputs.Rows.Add(item.Key, item.Value);
                dataGridOutputs.DataSource = DataTableOutputs;
                // è®¾ç½®çŠ¶æ€æ 
                lblResult.Text = $"结果: {(counter.Result ? "OK" : "NG")}";
                lblResult.ForeColor = counter.Result ? Color.LightGreen : Color.LightCoral;
                lblMsg.Text = counter.Msg;
            }
        }
        /// <summary>
        /// æ›´æ–°ç»Ÿè®¡ä¿¡æ¯æ˜¾ç¤º
        /// </summary>
        private void UpdateStatistics()
        {
            if (Subject is TyreCounterProcess counter)
            {
                txtCurrentTyreID.Text = counter.CurrentTyreID.ToString();
                txtCurrentImageIndex.Text = $"{counter.CurrentImageIndex}/{counter.ImagesPerTyre}";
                txtTyreTotal.Text = counter.TyreTotal.ToString();
                txtTyreOK.Text = counter.TyreOK.ToString();
                txtTyreNG.Text = counter.TyreNG.ToString();
                txtTyreRateOK.Text = $"{counter.TyreRateOK:F2}%";
            }
        }
        /// <summary>
        /// æ›´æ–°è¾“入参数
        /// </summary>
        public override void UpdataInputs()
        {
            if (Subject is TyreCounterProcess counter)
            {
                counter.ImagesPerTyre = (int)numericUpDownImagesPerTyre.Value;
                counter.JudgeRule = (TyreJudgeRule)Enum.Parse(typeof(TyreJudgeRule), comboBoxJudgeRule.SelectedItem?.ToString() ?? "AnyNG");
                counter.AutoReset = checkBoxAutoReset.Checked;
                // æ›´æ–°è¾“入参数表
                Subject.Params.Inputs["ImagesPerTyre"] = counter.ImagesPerTyre;
                Subject.Params.Inputs["JudgeRule"] = counter.JudgeRule.ToString();
                Subject.Params.Inputs["AutoReset"] = counter.AutoReset;
            }
        }
        private void btnSave_Click(object sender, EventArgs e)
        {
            UpdataInputs();
            lblMsg.Text = "参数已保存";
            lblMsg.ForeColor = Color.LightGreen;
        }
        private void btnReset_Click(object sender, EventArgs e)
        {
            if (Subject is TyreCounterProcess counter)
            {
                counter.ResetTyreCount();
                UpdateStatistics();
                LoadParas();
                lblMsg.Text = "计数器已重置";
                lblMsg.ForeColor = Color.LightGreen;
            }
        }
        private void btnRun_Click(object sender, EventArgs e)
        {
            UpdataInputs();
            Subject.Run();
            UpdateStatistics();
            LoadParas();
            lblResult.Text = $"结果: {(Subject.Result ? "OK" : "NG")}";
            lblResult.ForeColor = Subject.Result ? Color.LightGreen : Color.LightCoral;
            lblMsg.Text = Subject.Msg;
        }
    }
}
LB_VisionProcesses/Processes/TyreCounter/TyreStatistics.cs
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,266 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace LB_VisionProcesses.Processes
{
    /// <summary>
    /// è½®èƒŽåˆ¤å®šè§„则
    /// </summary>
    public enum TyreJudgeRule
    {
        /// <summary>
        /// ä»»ä¸€NG则整胎NG
        /// </summary>
        AnyNG,
        /// <summary>
        /// å…¨éƒ¨OK才整胎OK
        /// </summary>
        AllOK,
        /// <summary>
        /// å¤šæ•°è¡¨å†³ï¼ˆè¶…过半数OK则OK)
        /// </summary>
        MajorityVote
    }
    /// <summary>
    /// è½®èƒŽè®¡æ•°ç»“æžœ
    /// </summary>
    public class TyreCountResult
    {
        /// <summary>
        /// æ˜¯å¦å®Œæˆä¸€ä¸ªè½®èƒŽ
        /// </summary>
        public bool IsTyreComplete { get; set; }
        /// <summary>
        /// è½®èƒŽID
        /// </summary>
        public int TyreID { get; set; }
        /// <summary>
        /// è½®èƒŽæ•´ä½“结果
        /// </summary>
        public bool TyreResult { get; set; }
        /// <summary>
        /// å„图像结果列表
        /// </summary>
        public List<bool> ImageResults { get; set; } = new List<bool>();
        /// <summary>
        /// å½“前图像序号(1~n)
        /// </summary>
        public int CurrentImageIndex { get; set; }
        /// <summary>
        /// æ¶ˆæ¯
        /// </summary>
        public string Message { get; set; }
    }
    /// <summary>
    /// è½®èƒŽç»Ÿè®¡å™¨ - ç”¨äºŽç®¡ç†è½®èƒŽçº§åˆ«çš„计数和统计
    /// </summary>
    public class TyreStatistics
    {
        #region é…ç½®å‚æ•°
        /// <summary>
        /// æ¯å¼ è½®èƒŽæ‰€éœ€å›¾åƒæ•°ï¼ˆé»˜è®¤8张)
        /// </summary>
        public int ImagesPerTyre { get; set; } = 8;
        /// <summary>
        /// åˆ¤å®šè§„则
        /// </summary>
        public TyreJudgeRule JudgeRule { get; set; } = TyreJudgeRule.AnyNG;
        #endregion
        #region ç»Ÿè®¡æ•°æ®
        /// <summary>
        /// è½®èƒŽæ€»æ•°
        /// </summary>
        public int TyreTotal => TyreOK + TyreNG;
        /// <summary>
        /// è½®èƒŽOK计数
        /// </summary>
        public int TyreOK { get; set; }
        /// <summary>
        /// è½®èƒŽNG计数
        /// </summary>
        public int TyreNG { get; set; }
        /// <summary>
        /// å½“前轮胎ID(从1开始)
        /// </summary>
        public int CurrentTyreID { get; set; } = 1;
        /// <summary>
        /// å½“前轮胎的图像序号(0~ImagesPerTyre-1)
        /// </summary>
        public int CurrentImageIndex { get; set; } = 0;
        /// <summary>
        /// å½“前轮胎的各图像结果
        /// </summary>
        public List<bool> CurrentTyreResults { get; set; } = new List<bool>();
        /// <summary>
        /// å½“前轮胎的各图像SN
        /// </summary>
        public List<string> CurrentTyreImageSNs { get; set; } = new List<string>();
        /// <summary>
        /// è½®èƒŽè‰¯å“çއ
        /// </summary>
        public double TyreRateOK => TyreTotal > 0 ? (TyreOK / (double)TyreTotal) * 100 : 0;
        #endregion
        #region æž„造方法
        public TyreStatistics() { }
        public TyreStatistics(int imagesPerTyre, TyreJudgeRule judgeRule = TyreJudgeRule.AnyNG)
        {
            ImagesPerTyre = imagesPerTyre;
            JudgeRule = judgeRule;
        }
        #endregion
        #region æ ¸å¿ƒæ–¹æ³•
        /// <summary>
        /// æ·»åŠ å›¾åƒæ£€æµ‹ç»“æžœ
        /// </summary>
        /// <param name="isOK">图像检测结果</param>
        /// <param name="imageSN">图像序列号(可选)</param>
        /// <returns>轮胎计数结果</returns>
        public TyreCountResult AddImageResult(bool isOK, string imageSN = null)
        {
            // æ·»åŠ åˆ°å½“å‰è½®èƒŽç»“æžœåˆ—è¡¨
            CurrentTyreResults.Add(isOK);
            CurrentTyreImageSNs.Add(imageSN);
            CurrentImageIndex++;
            var result = new TyreCountResult
            {
                CurrentImageIndex = CurrentImageIndex,
                IsTyreComplete = false,
                Message = $"当前轮胎第 {CurrentImageIndex}/{ImagesPerTyre} å¼ å›¾åƒ"
            };
            // æ£€æŸ¥æ˜¯å¦å®Œæˆä¸€ä¸ªè½®èƒŽ
            if (CurrentImageIndex >= ImagesPerTyre)
            {
                // è®¡ç®—轮胎整体结果
                bool tyreResult = CalculateTyreResult();
                // æ›´æ–°ç»Ÿè®¡
                if (tyreResult)
                    TyreOK++;
                else
                    TyreNG++;
                // æž„建完成结果
                result.IsTyreComplete = true;
                result.TyreID = CurrentTyreID;
                result.TyreResult = tyreResult;
                result.ImageResults = new List<bool>(CurrentTyreResults);
                result.Message = $"完成轮胎 #{CurrentTyreID},结果: {(tyreResult ? "OK" : "NG")}";
                // é‡ç½®å½“前轮胎数据
                ResetCurrentTyre();
            }
            return result;
        }
        /// <summary>
        /// è®¡ç®—轮胎整体结果
        /// </summary>
        private bool CalculateTyreResult()
        {
            if (CurrentTyreResults.Count == 0)
                return true;
            switch (JudgeRule)
            {
                case TyreJudgeRule.AnyNG:
                    // n张中任一NG则整胎NG
                    return !CurrentTyreResults.Any(r => !r);
                case TyreJudgeRule.AllOK:
                    // å…¨éƒ¨OK才整胎OK(与AnyNG相同)
                    return CurrentTyreResults.All(r => r);
                case TyreJudgeRule.MajorityVote:
                    // å¤šæ•°è¡¨å†³ï¼šè¶…过半数OK则OK
                    int okCount = CurrentTyreResults.Count(r => r);
                    return okCount > (CurrentTyreResults.Count / 2.0);
                default:
                    return !CurrentTyreResults.Any(r => !r);
            }
        }
        /// <summary>
        /// é‡ç½®å½“前轮胎数据
        /// </summary>
        private void ResetCurrentTyre()
        {
            CurrentTyreID++;
            CurrentImageIndex = 0;
            CurrentTyreResults.Clear();
            CurrentTyreImageSNs.Clear();
        }
        /// <summary>
        /// é‡ç½®æ‰€æœ‰ç»Ÿè®¡
        /// </summary>
        public void Reset()
        {
            TyreOK = 0;
            TyreNG = 0;
            CurrentTyreID = 1;
            ResetCurrentTyre();
        }
        /// <summary>
        /// æ¸…空当前轮胎(用于异常情况)
        /// </summary>
        public void ClearCurrentTyre()
        {
            ResetCurrentTyre();
        }
        /// <summary>
        /// èŽ·å–å½“å‰è¿›åº¦ä¿¡æ¯
        /// </summary>
        public string GetProgressInfo()
        {
            if (ImagesPerTyre <= 1)
                return $"轮胎 #{CurrentTyreID} (3D模式)";
            return $"轮胎 #{CurrentTyreID} - ç¬¬ {CurrentImageIndex}/{ImagesPerTyre} å¼ ";
        }
        /// <summary>
        /// èŽ·å–ç»Ÿè®¡ä¿¡æ¯å­—ç¬¦ä¸²
        /// </summary>
        public string GetStatisticsInfo()
        {
            return $"轮胎总数: {TyreTotal}, OK: {TyreOK}, NG: {TyreNG}, è‰¯å“çއ: {TyreRateOK:F2}%";
        }
        #endregion
    }
}