C# 探测器测试系统

2020-08-19 11:46:45 浏览数 (1)

运行效果:

重要知识点:

  1. 控件循环遍历操控;
  2. 队列数组的应用: private Queue<double>[] dataQueue = new Queue<double>[8]; //把Queue<double>看成一个类型 int[] a=new int [8]

3. 委托与线程,主要是为了界面实时刷新显示数据;

4. 窗体最大化而不遮挡任务栏;

5. 数据解码,标准差、均值等运算.

主窗体MainForm.cs

代码语言:javascript复制
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 System.IO;
using System.Xml;
using BLL;

using System.Threading;
using System.Net;
using System.Net.Sockets;
using System.Windows.Forms.DataVisualization.Charting;


namespace ThzDataProcess
{
    public partial class MainForm : DevComponents.DotNetBar.Office2007Form
    {
        private int frameRate = 8,channel=1;    
        bool isStart = false, isStart1 = false;
        const string stopIcon = @"iconstop.png";
        const string startIcon = @"iconstart.png";
        DataProcess DPBLL = null;
        object ThreadLock = new object();

        private Queue<double>[] dataQueue = new Queue<double>[8];//把Queue<double>看成一个类型 int[] a=new int [8]
        public MainForm()
{
            this.DoubleBuffered = true;//设置本窗体
            SetStyle(ControlStyles.UserPaint, true);
            SetStyle(ControlStyles.AllPaintingInWmPaint, true); // 禁止擦除背景.
            SetStyle(ControlStyles.DoubleBuffer, true); // 双缓冲


            this.EnableGlass = false;
            InitializeComponent();

            InitChart();
            string DeviceIP = "192.168.1.120";
            int LocalPort = 8009;
            DPBLL = new DataProcess(DeviceIP, LocalPort);

            DPBLL.ShowEvent_zyr1 = dataShow;
            DPBLL.ShowEvent_zyr2 = chartShow;
            DPBLL.Start();//启动线程

            radioButton1.Checked = true;
            radioButton2.Checked = false;

            dataQueue[0] = new Queue<double>(100);
            dataQueue[1] = new Queue<double>(100);
            dataQueue[2] = new Queue<double>(100);
            dataQueue[3] = new Queue<double>(100);
            dataQueue[4] = new Queue<double>(100);
            dataQueue[5] = new Queue<double>(100);
            dataQueue[6] = new Queue<double>(100);
            dataQueue[7] = new Queue<double>(100);


        }
        // 防止闪屏        
        protected override CreateParams CreateParams
        {
            get
            {
                CreateParams cp = base.CreateParams;
                cp.ExStyle |= 0x02000000;
                return cp;
            }
        }



        private void MainForm_Load(object sender, EventArgs e)
{
            this.WindowState = FormWindowState.Normal;
            this.FormBorderStyle = FormBorderStyle.Sizable;
            this.Top = 0;
            this.Left = 0;
            this.Width = Screen.PrimaryScreen.WorkingArea.Width;
            this.Height = Screen.PrimaryScreen.WorkingArea.Height;
        }

        private void InitChart()
{
            Chart[] ch = new Chart[8] { chart1, chart2 , chart3, chart4, chart5, chart6, chart7, chart8 };
            for (int i = 0; i < 8; i  )
            {
                ch[i].ChartAreas.Clear();
                ChartArea chartArea1 = new ChartArea("C1");
                ch[i].ChartAreas.Add(chartArea1);
                //定义存储和显示点的容器
                ch[i].Series.Clear();
                Series series1 = new Series("S1");
                series1.ChartArea = "C1";
                ch[i].Series.Add(series1);

                ch[i].ChartAreas[0].AxisY.IsStartedFromZero = false;
                ch[i].Legends[0].Enabled = false;

                ch[i].ChartAreas[0].AxisX.Interval = 5;
                ch[i].ChartAreas[0].AxisX.MajorGrid.LineColor = System.Drawing.Color.Silver;
                ch[i].ChartAreas[0].AxisY.MajorGrid.LineColor = System.Drawing.Color.Silver;
                //设置标题
                ch[i].Titles.Clear();
                ch[i].Titles.Add("S01");
                ch[i].Titles[0].Text = "通道"   (i   1)   " AD折线图显示";
                ch[i].Titles[0].ForeColor = Color.RoyalBlue;
                ch[i].Titles[0].Font = new System.Drawing.Font("Microsoft Sans Serif", 12F);
                //设置图表显示样式
                ch[i].Series[0].Color = Color.Red;
                //this.chart1.Titles[0].Text = string.Format("{0}折线图显示", );
                ch[i].Series[0].ChartType = SeriesChartType.Line;
                ch[i].Series[0].Points.Clear();
            }
        }
        public void chartShow( Double y,int ch)
{

            Chart[] chNum = new Chart[8] { chart1, chart2, chart3, chart4, chart5, chart6, chart7, chart8 };
            if(ch <= 8)
               chartDisplay(chNum[ch-1], ch, y);

        }
        delegate void ChartDelegate(Chart chart, int ch, Double y);
        private void chartDisplay(Chart chart, int ch, Double y)
{

            if (chart.InvokeRequired)
            {
                ChartDelegate chartDelegate = chartDisplay;
                chart.Invoke(chartDelegate, new object[] { chart, ch, y });
            }
            else
            {
                if ( isStart == true )
                    UpdateQueueValue(ch,y);
                chart.Series[0].Points.Clear();
                // for (int j = 0; j < 100; j  )
                //     chart1.Series[0].Points.AddXY(j, y);
                for (int i = 0; i < dataQueue[ch-1].Count; i  )
                    chart.Series[0].Points.AddXY((i   1), dataQueue[ch-1].ElementAt(i));
            }
        }

        private void btnStart_Click(object sender, EventArgs e)
{
            if (!isStart)
            {
                Command.CommandUp_v1(frameRate);
                btnStart.Text = @"停止采集";
                btnStart.DisabledImage = btnStart.Image;
                btnStart.Image = (Image)btnStart.PressedImage.Clone();
                isStart = !isStart;

            }
            else
            {
                Command.CommandUp_v1(0);
                btnStart.Text = @"开始采集";
                btnStart.Image = btnStart.DisabledImage;
                isStart = !isStart;
            }
        }

        private void UpdateQueueValue(int ch,Double y)
{

            if (dataQueue[ch-1].Count > 100)
                //先出列
                dataQueue[ch-1].Dequeue();
            dataQueue[ch-1].Enqueue(y);


        }
        private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
{
            Command.CommandUp_v1(0);
        }

        public void dataShow(string avg, string stdDev, string maxMin, int ch)
{
            double temperatureSensitivity = 0.0;
            double dValue = 0.0,temp1=0.0, temp2 = 0.0, tempV1 = 0.0, tempV2 = 0.0;

            //ShowMessage(dataGridViewX1, str, row, column);
            Label[] lb = new Label[48] { label_1,label_2,label_3,label_4,label_5, label_6, label_7, label_8, label_9, label_10 , label_11, label_12, label_13, label_14, label_15,label_16,
                                         label_17,label_18,label_19,label_20,label_21, label_22, label_23, label_24, label_25, label_26 , label_27, label_28, label_29, label_30, label_31,label_32,
                                         label_33,label_34,label_35,label_36,label_37, label_38, label_39, label_40, label_41, label_42 , label_43, label_44, label_45, label_46, label_47,label_48 };

            if (ch <= 8 && isStart == true)
            {
                if (radioButton1.Checked == true)
                {

                    ShowMessage(lb[(ch - 1) * 6], "V1 : "   avg);
                    ShowMessage(lb[(ch - 1) * 6   1], "σ1 : "   stdDev);
                    ShowMessage(lb[(ch - 1) * 6   2], "Max/Min :"   maxMin);
                
                }
                else
                {
                    ShowMessage(lb[(ch - 1) * 6   3], "V2 : "   avg);
                    ShowMessage(lb[(ch - 1) * 6   4], "σ2 : "   stdDev);
                    ShowMessage(lb[(ch - 1) * 6   2], "Max/Min :"   maxMin);
                }

                if (textBox1.Text != "" && textBox2.Text != "")
                {
                    dValue = Math.Abs(Convert.ToDouble(textBox1.Text) - Convert.ToDouble(textBox2.Text));
                    temp1 = Convert.ToDouble(lb[(ch - 1) * 6   1].Text.Substring(5, lb[(ch - 1) * 6   1].Text.Length - 5));
                    temp2 = Convert.ToDouble(lb[(ch - 1) * 6   4].Text.Substring(5, lb[(ch - 1) * 6   4].Text.Length - 5));
                    tempV1 = Convert.ToDouble(lb[(ch - 1) * 6].Text.Substring(5, lb[(ch - 1) * 6].Text.Length - 5));
                    tempV2 = Convert.ToDouble(lb[(ch - 1) * 6   3].Text.Substring(5, lb[(ch - 1) * 6   3].Text.Length - 5));
                    if (tempV1 - tempV2 != 0)
                        temperatureSensitivity = (temp1   temp2) * dValue / Math.Abs(tempV1 - tempV2) / 2.0;
                    ShowMessage(lb[(ch - 1) * 6   5], "ΔT :"   temperatureSensitivity.ToString("0.00"));
                }

            }
            else
            {
                ;
            }
        }

       

        delegate void ShowMessageDelegate(Label lbl, string message);
        private void ShowMessage(Label lbl, string message)
{
            if (lbl.InvokeRequired)
            {
                ShowMessageDelegate showMessageDelegate = ShowMessage;
                lbl.Invoke(showMessageDelegate, new object[] { lbl, message});
            }
            else
            {

                lbl.Text = message;
            }
        }

       
    }
}

类DataCalculate.cs:

代码语言:javascript复制
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ThzData;
using System.Threading.Tasks;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.IO;
using System.Diagnostics;
using System.Drawing;

using ThzDataProcess;
using System.Windows.Forms;


namespace BLL
{
    class DataCalculate
    {

       
        DataProcess dp = null;
        public  void tempartureData_zyr(List<byte[]> Zhendata, Action<string> ShowEvent_zyr2)
        {
            StringBuilder sNeed = new StringBuilder();
           
            foreach (Byte[] match in Zhendata)
                sNeed.Append(BitConverter.ToString(match).Replace("-", "").Substring(20).ToUpper());
            double[] temparture = GetTemparture_zyr(sNeed.ToString());
            // mf.ShowlbDevTem(string.Format("设备温度:nT1:{0:N}°nT2:{1:N}°nT3:{2:N}°nT4:{3:N}°", temparture[0], temparture[1], temparture[2], temparture[3]));
            ShowEvent_zyr2(string.Format("设备温度:nT1:{0:N}°nT2:{1:N}°nT3:{2:N}°nT4:{3:N}°", temparture[0], temparture[1], temparture[2], temparture[3]));
           // dp.callBack_zyr2(string.Format("设备温度:nT1:{0:N}°nT2:{1:N}°nT3:{2:N}°nT4:{3:N}°", temparture[0], temparture[1], temparture[2], temparture[3]));
            sNeed.Clear();
            foreach (var tem in temparture)
                sNeed.Append(tem   "***");
            strWrite_zyr(sNeed.ToString(), Environment.CurrentDirectory   "\bin", "tempartureData.txt");
            sNeed.Clear();


        }

        public double[] GetTemparture_zyr(string str)
        {
            string tepStr = str.Substring(20 * 2, 8 * 2);
            double[] Temparture = new double[4];
            if (tepStr == null)
                return Temparture;
            byte[] Wen = DataProcess.strToToHexByte(tepStr);
            if ((Wen[0] & 0xf0) >> 4 == 15)
                Temparture[0] = -(~Wen[1]   1   256.0 * ~Wen[0]) / 16;
            else
                Temparture[0] = (Wen[1]   256.0 * Wen[0]) / 16;

            if ((Wen[2] & 0xf0) >> 4 == 15)
                Temparture[1] = -(~Wen[3]   1   256.0 * ~Wen[2]) / 16;
            else
                Temparture[1] = (Wen[3]   256.0 * Wen[2]) / 16;

            if ((Wen[4] & 0xf0) >> 4 == 15)
                Temparture[2] = -(~Wen[5]   1   256.0 * ~Wen[4]) / 16;
            else
                Temparture[2] = (Wen[5]   256.0 * Wen[4]) / 16;

            if ((Wen[6] & 0xf0) >> 4 == 15)
                Temparture[3] = -(~Wen[7]   1   256.0 * ~Wen[6]) / 16;
            else
                Temparture[3] = (Wen[7]   256.0 * Wen[6]) / 16;
            return Temparture;
        }
        int zhenRows = 0;
        public void adDataCaculate_zyr(List<byte[]> Zhendata, Action<string, string, string,int> ShowEvent_zyr1, Action<double,int> ShowEvent_zyr2)
        {
            //byte[] byteData = new byte[35250];//1410*25
           
            int count1 = 0, count2 = 0,sampleCount=0;
            StringBuilder sNeed = new StringBuilder();
            StringBuilder sNeed1 = new StringBuilder();
            //MainForm mf = new MainForm();

            sampleCount = Zhendata[0][28] * 256   Zhendata[0][29];
            byte[] byteData = new byte[Zhendata.Count()* 1410];//1410*44
            foreach (Byte[] Package in Zhendata)
            {
                count1 = 0;
                foreach (byte byt in Package)
                {
                    if (count1 >= 10)   //跳过第一个数
                    {

                        byteData[count2] = byt;
                        count2  ;

                    }
                    count1  ;
                }
            }
            // Console.ReadKey();
            double[] channel = new double[sampleCount];//473、465
            double[] channel1 = new double[sampleCount];
            double variance = 0.0, average_original = 0.0 , average_converted = 0.0,stdDev = 0.0,maxNum= 0.0,minNum = 0.0;
            for (int i = 0; i < 36; i  )
            {
                for (int j = 0; j < sampleCount; j  )
                {
                    byte bigByte = Convert.ToByte(byteData[j * 74   i * 2   40].ToString("X"), 16);
                    if ((bigByte & 0xf0) >> 4 == 15)
                    {
                        channel[j] = -(~byteData[j * 74   i * 2   41]   1   256.0 * ~byteData[j * 74   i * 2   40]) / 8192.0 * 5;//2^12 =4096
                        channel1[j] = -(~byteData[j * 74   i * 2   41]   1   256.0 * ~byteData[j * 74   i * 2   40]);
                    }
                    else
                    {
                        channel[j] = (byteData[j * 74   i * 2   41]   256.0 * byteData[j * 74   i * 2   40]) / 8192.0 * 5;
                        channel1[j] = (byteData[j * 74   i * 2   41]   256.0 * byteData[j * 74   i * 2   40]) ;
                    }
                    sNeed.Append(channel[j]   ",");
                    sNeed1.Append(channel1[j]   ",");
                }

                Stopwatch elapsetime = new Stopwatch();
                elapsetime.Start();


                stdDev = CalculateStdDev(channel)*1000;//标准差
                average_converted = channel.Average()*1000;
                maxNum = channel.Max()*1000;
                minNum = channel.Min()*1000;
                average_original = channel.Average();

                ShowEvent_zyr1(average_converted.ToString("0.00"), stdDev.ToString("0.00") ,maxNum.ToString("0.00") "/" minNum.ToString("0.00"),i 1);
                ShowEvent_zyr2(average_original, i 1);

                elapsetime.Stop();
                Console.WriteLine(elapsetime.ElapsedMilliseconds.ToString("000"));

                //variance = Var_zyr(channel);//方差
                // ShowEvent_zyr1(zhenRows, 2 * i   1, variance.ToString());
                //sNeed.Append("***variance:"   variance   "***average:");

                //ShowEvent_zyr1(zhenRows, 2 * i, average.ToString());
                // ShowEvent_zyr3(i 1,average);
                //sNeed.Append(average);
                //strWrite_zyr(sNeed.ToString(), Environment.CurrentDirectory   "\bin", "channelData.txt");
                //sNeed.Clear();
            }
            zhenRows  ;
        }

       // private static double CalculateStdDev(IEnumerable<double> values)
             private static double CalculateStdDev(double[] values)
        {
            double ret = 0;
            if (values.Count() > 0)
            {
                //  计算平均数   
                double avg = values.Average();
                //  计算各数值与平均数的差值的平方,然后求和 
                double sum = values.Sum(d => Math.Pow(d - avg, 2));
                //  除以数量,然后开方
                ret = Math.Sqrt(sum / values.Count());
            }
            return ret;
        }

        public double Var_zyr(double[] v)
        {
            double sum1 = 0;
            for (int i = 0; i < v.Length; i  )
            {
                double temp = v[i] * v[i];
                sum1 = sum1   temp;
            }

            double sum = 0;
            foreach (double d in v)
            {
                sum = sum   d;
            }
            double var = sum1 / v.Length - (sum / v.Length) * (sum / v.Length);
            return var;
        }
        private int rowCount = 0;
        private void strWrite_zyr(string str, string filePath, string fileName)
        {

            if (!Directory.Exists(filePath))
                Directory.CreateDirectory(filePath);
            if (!File.Exists(filePath   "\"   fileName))
                File.Create(filePath   "\"   fileName).Close(); //.Close 很关键,不然会有问题
            if (rowCount < 3600)
            {
                StreamWriter sw = new StreamWriter(filePath   "\"   fileName, true);//true 追加数据
                sw.WriteLine(str);
                sw.Close();
                rowCount  ;
            }
            else
            {
                StreamWriter sw = new StreamWriter(filePath   "\"   fileName, false);
                sw.WriteLine(str);
                sw.Close();
                rowCount = 0;
            }
        }
    }
}

类DataProcess.cs:

代码语言:javascript复制
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ThzData;
using System.Threading.Tasks;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.IO;
using System.Diagnostics;
using System.Drawing;

using ThzDataProcess;
using System.Windows.Forms;


namespace BLL
{
    public class Command
    {
        public static void CommandUp(int frame)
        {
            //string sendString = null;//要发送的字符串 
            byte[] Data = new byte[8];
            switch (frame)
            {
                case 0:
                    Data = new byte[] { 22, 144, 87, 235, 00, 00, 00, 16 };//停止
                    break;
                case 6:
                    Data = new byte[] { 22, 144, 87, 235, 00, 00, 00, 32 };//6帧/s 启动
                    break;
                case 8:
                    Data = new byte[] { 22, 144, 87, 235, 00, 00, 00, 48 };//仅上传AD值
                    //Data = new byte[] { 22, 144, 87, 235, 00, 00, 00, 33 };//8帧/s 启动
                    break;
                case 10:
                    Data = new byte[] { 22, 144, 87, 235, 00, 00, 00, 34 };//10帧/s 启动
                    break;
                case 12:
                    Data = new byte[] { 22, 144, 87, 235, 00, 00, 00, 35 };//12帧/s 启动
                    break;
                case -1:
                    Data = new byte[] { 22, 144, 87, 235, 00, 00, 00, 48 };//仅上传AD值
                    break;
                default:
                    Data = new byte[] { 22, 144, 87, 235, 00, 00, 00, 33 };//8帧/s 启动
                    break;
            }
            UdpClient client = new UdpClient(new IPEndPoint(IPAddress.Any, 9001));
            //广播发送指令
            IPAddress remoteIP = IPAddress.Parse("255.255.255.255");
            int remotePort = 8010;
            //实例化广播
            IPEndPoint remotePoint = new IPEndPoint(remoteIP, remotePort);

            //sendString = Console.ReadLine();
            //sendData = Encoding.Default.GetBytes(sendString);

            //client = new UdpClient();
            //将数据发送到远程端点 
            client.Send(Data, Data.Length, remotePoint);
            //关闭连接
            client.Close();

        }

        public static void CommandUp_v1(int frame, byte tair = 00)                     //看不懂
        {
            //string sendString = null;//要发送的字符串 
            byte[] Data = new byte[8];
            switch (frame)
            {
                case 0:
                    Data = new byte[] { 22, 144, 87, 235, 00, 00, 16, tair };//停止
                    break;
                case 6:
                    Data = new byte[] { 22, 144, 87, 235, 00, 00, 32, tair };//6帧/s 启动
                    break;
                case 8:
                    Data = new byte[] { 22, 144, 87, 235, 00, 00, 48, tair };//仅上传AD值
                    //Data = new byte[] { 22, 144, 87, 235, 00, 00, 33, tair };//8帧/s 启动
                    break;
                case 10:
                    Data = new byte[] { 22, 144, 87, 235, 00, 00, 34, tair };//10帧/s 启动
                    break;
                case 12:
                    Data = new byte[] { 22, 144, 87, 235, 00, 00, 35, tair };//12帧/s 启动
                    break;
                case 1:
                    Data = new byte[] { 22, 144, 87, 235, 00, 00, 97, tair };//自动获取编码器值范围
                    break;
                case 60:
                    Data = new byte[] { 22, 144, 87, 235, 00, 00, 80, tair };//6帧/s 校准参数
                    break;
                case 80:
                    Data = new byte[] { 22, 144, 87, 235, 00, 00, 81, tair };//8帧/s 校准参数
                    break;
                case 100:
                    Data = new byte[] { 22, 144, 87, 235, 00, 00, 82, tair };//10帧/s 校准参数
                    break;
                case 120:
                    Data = new byte[] { 22, 144, 87, 235, 00, 00, 83, tair };//12帧/s 校准参数
                    break;
                case -1:
                    Data = new byte[] { 22, 144, 87, 235, 00, 00, 48, tair };//仅上传AD值
                    break;
                case 128:
                    Data = new byte[] { 22, 144, 87, 235, 00, 00, 128, tair };//仅上传AD值
                    break;
                default:
                    Data = new byte[] { 22, 144, 87, 235, 00, 00, 33, tair };//8帧/s 启动
                    break;
            }

            UdpClient client = new UdpClient(new IPEndPoint(IPAddress.Any, 9001));
           // IPAddress remoteIP = IPAddress.Parse("255.255.255.255");  //以广播方式发送
            IPAddress remoteIP = IPAddress.Parse("192.168.1.255");
            int remotePort = 8008;
            IPEndPoint remotePoint = new IPEndPoint(remoteIP, remotePort);



            //sendString = Console.ReadLine();
            //sendData = Encoding.Default.GetBytes(sendString);

            //client = new UdpClient();
            //将数据发送到远程端点 
            client.Send(Data, Data.Length, remotePoint);
            //关闭连接
            client.Close();
            

        }

        public static void CommandUp_v2(int frame)
        {
            //string sendString = null;//要发送的字符串 
            byte[] Data = new byte[8];

            switch (frame)
            {
                case 41:
                    Data = new byte[] { 22, 144, 87, 235, 00, 00, 65, 00 };//停止
                    break;
                case 42:
                    Data = new byte[] { 22, 144, 87, 235, 00, 00, 66, 00 };//6帧/s 启动
                    break;
                case 43:
                    Data = new byte[] { 22, 144, 87, 235, 00, 00, 67, 00 };//8帧/s 启动
                    break;
                default:
                    Data = new byte[] { 22, 144, 87, 235, 00, 00, 66, 00 };//8帧/s 启动
                    break;
            }

            UdpClient client = new UdpClient(new IPEndPoint(IPAddress.Any, 9001));
            //广播发送指令
            IPAddress remoteIP = IPAddress.Parse("255.255.255.255");
            int remotePort = 8008;
            //实例化广播
            IPEndPoint remotePoint = new IPEndPoint(remoteIP, remotePort);

            //sendString = Console.ReadLine();
            //sendData = Encoding.Default.GetBytes(sendString);

            //client = new UdpClient();
            //将数据发送到远程端点 
            client.Send(Data, Data.Length, remotePoint);
            //关闭连接
            client.Close();

        }
    }

    public class DataProcess
    {
        string deviceIp = "";                                       //太赫兹设备IP
        const int devicePort = 8008;                                //太赫兹设备发送端口
        int localPort = new int();                                  //本机接收端口

        Queue<List<Byte[]>> DataQueue = new Queue<List<Byte[]>>();  //数据缓存队列
        Semaphore TaskSemaphore = new Semaphore(0, 2560);           //数据缓存队列缓存区
        object ThreadLock = new object();                           //线程锁

        public Action<Bitmap, string[], double[], bool, bool> ShowEvent;
        public Action<string, string, string, int> ShowEvent_zyr1;
        public Action<double, int> ShowEvent_zyr2;
       // public Action<int,Double> ShowEvent_zyr3;
        //MainForm mf = new MainForm();


        DataCalculate dc = new DataCalculate();


        #region 线程开启
        /// <summary>
        /// 所有线程开启函数
        /// </summary>
        public void Start()
        {
            StartAllThread();
        }

        /// <summary>
        /// 开启子线程
        /// </summary>
        private void StartAllThread()
        {
            StartDataRevThread();
            StartDataProcessThread();
            StartShowThread();
        }

        private void StartShowThread()
        {
            Thread t = new Thread(new ThreadStart(ShowAllVariables));                  //开启DataRevThread
            t.Name = "ShowAllVariables";                                            //线程名字
            t.Start();
            t.IsBackground = true;
        }

        /// <summary>
        /// 开启数据接收线程
        /// </summary>
        private void StartDataRevThread()
        {

            Thread t = new Thread(new ThreadStart(DataRevThread));                  //开启DataRevThread
            t.Name = "DataRevThread";                                            //线程名字
            t.Start();
            t.IsBackground = true;                                                  //后台运行
        }

        /// <summary>
        /// 数据处理线程开启
        /// </summary>
        private void StartDataProcessThread()
        {
            Thread t = new Thread(new ThreadStart(DataDecodeImageProcessThread));  //开启DataDecode_ImageProcessThread
            t.Name = "DataDecode_ImageProcessThread";                                            //线程名字
            t.Start();
            t.IsBackground = true;                                                  //后台运行
        }
        #endregion

        /// <summary>
        /// 构造函数
        /// </summary>
        public DataProcess(string deviceip, int localport)
        {
            deviceIp = deviceip;//192.168.1.120
            localPort = localport;//8008
        }


        /*Thread t = new Thread(Start);
           t.Priority = ThreadPriority.Highest;
           t.Start();*/

        #region 数据接收线程
        /// <summary>
        /// 数据接收线程
        /// </summary>
        private void DataRevThread()
        {
            
            try
            {
                //IPAddress remoteIP = IPAddress.Parse("255.255.255.255");                                      //广播


                UdpClient client = new UdpClient(new IPEndPoint(IPAddress.Parse("192.168.1.119"), localPort));   //本机端口 一般UdpClient client = new UdpClient();
                IPAddress remoteIP = IPAddress.Parse(deviceIp);                                                   //远程IP
                int remotePort = devicePort;                                                                   //远程端口
                IPEndPoint endpoint = new IPEndPoint(remoteIP, remotePort);                                 //远程IP和端口
                client.Client.ReceiveBufferSize = 40960;//40960 默认值是8192
                //ARP触发
                client.Send(new byte[] { 00, 11 }, 2, endpoint);   //发送 00 ,11有何作用??



                while (true)
                    {
                      // MainForm f1 = new MainForm();
                      //f1.ShowThread("123");
                      List<Byte[]> Taskbuff = new List<Byte[]>();
                          for (int i = 0; i < 25; i  )                             //为什么是21?
                        {

                            Byte[] recv = client.Receive(ref endpoint);
                            // MainForm f1 = new MainForm();
                            // f1.ShowThread();
                            Taskbuff.Add(recv);


                       
                        DataShow_v1(recv, Environment.CurrentDirectory   "\bin", "mydata.bin");



                        // writerFile(recv, Environment.CurrentDirectory   "\bin\mydata.bin");

                    }
                    // 任务队列为临界资源,需要锁 
                    lock (ThreadLock)
                        {
                            DataQueue.Enqueue(Taskbuff); //Queue<List<Byte[]>> DataQueue = new Queue<List<Byte[]>>();  在队列的末端添加元素

                        }
                        // 每添加一个任务,信号量加1
                        TaskSemaphore.Release(1);

                        //ChangeProducerText(String.Format("Consumer 1 take Task {0}rn", a));


                    }
                

                //client.Close();
            }
            catch (Exception ex)
            {
                string fileName = "Log\debug"   localPort   "_DataDecode.txt";
                string content = DateTime.Now.ToLocalTime()   ex.Message   "n"   ex.StackTrace   "rn";
                Logger(fileName, content);
            }

        }
        #endregion


        #region 数据显示
        private void DataShow_v1(Byte[] recv,string filePath,string fileName)
        {
            if (!Directory.Exists(filePath))
                Directory.CreateDirectory(filePath);
            if (!File.Exists(filePath  "\" fileName))
                File.Create(filePath   "\" fileName).Close(); //.Close 很关键,不然会有问题
            FileStream fs = new FileStream(filePath   "\" fileName, FileMode.Append, FileAccess.Write);
            fs.Write(recv, 0, recv.Length);
            fs.Close();
            fs.Dispose();
        }
            private void DataShow(Byte[] recv)
        {
            //MainForm f1 = new MainForm();
            // ShowMessage(f1.richTextBox1, "开始显示数据");
            //  MainForm f1 = new MainForm();
            //f1.ShowThread("123");
            /*  int nLength = recv.Length;//字节数组长度
              string sByte = "";
              if (nLength > 0)
              {
                  sByte = Convert.ToString(recv[0], 16);//转换成16进制
                  if (nLength > 1)
                  {
                      for (int k = 1; k < recv.Length; k  )
                      {
                          sByte  = ",";//用逗号隔开
                          sByte  = Convert.ToString(recv[k], 16);//转换成16进制

                      }
                  }
              }
              if (!Directory.Exists(Environment.CurrentDirectory   "\bin"))
                  Directory.CreateDirectory(Environment.CurrentDirectory   "\bin");

              //Environment.CurrentDirectory   "\"   DateTime.Now.ToString("HHmmssfff")   "bin.txt"
              // writerFile(strToToHexByte(sNeed.ToString().Substring(0)), "ZHEN\Port"   localPort   "_Frame"   (CountNum) % 10000   ".bin");
              using (StreamWriter file = new StreamWriter(Environment.CurrentDirectory   "\bin\"   DateTime.Now.ToString("HHmmss")   ".txt", true))
              {
                  file.WriteLine(sByte);
                  file.WriteLine("rn");

              }*/

            //if (!Directory.Exists(Environment.CurrentDirectory   "\bin"))
            //    Directory.CreateDirectory(Environment.CurrentDirectory   "\bin");

            //Stream flstr = new FileStream(Path.GetDirectoryName(Application.ExecutablePath))
            // BinaryWriter sw = new  BinaryWriter(new FileStream(Environment.CurrentDirectory   "\bin\mydata.bin", FileMode.Append, FileAccess.ReadWrite)); //创建文件  bin目录下
            //  sw.Write(recv);
            //  sw.Close();

            //writerFile(recv, Environment.CurrentDirectory   "\bin\mydata.bin");
            int nLength = recv.Length;//字节数组长度
             string sByte = "";
             if (nLength > 0)
             {
                 sByte = Convert.ToString(recv[0], 16);//转换成16进制
                 if (nLength > 1)
                 {
                     for (int i = 1; i < recv.Length; i  )
                     {
                         sByte  = ",";//用逗号隔开
                         sByte  = Convert.ToString(recv[i], 16);//转换成16进制

                     }
                 }
             }
            if (!File.Exists(Environment.CurrentDirectory  "\bin.txt"))
                File.Create(Environment.CurrentDirectory   "\bin.txt");
            //Environment.CurrentDirectory   "\"   DateTime.Now.ToString("HHmmssfff")   "bin.txt"
            using (StreamWriter file = new StreamWriter(Environment.CurrentDirectory   "\bin.txt", true))
            {
                file.WriteLine(DateTime.Now.ToString("HHmmssfff") sByte);

            }

            //File.WriteAllBytes(Environment.CurrentDirectory "bin.txt", recv);
            //ShowMessage(f1.richTextBox1, sByte);

        }
        // 向RichTextBox中添加文本
        delegate void ShowMessageDelegate(RichTextBox txtbox, string message);
        private void ShowMessage(RichTextBox txtbox, string message)
        {
            if (txtbox.InvokeRequired)
            {
                ShowMessageDelegate showMessageDelegate = ShowMessage;
                txtbox.Invoke(showMessageDelegate, new object[] { txtbox, message });
            }
            else
            {
                txtbox.Text  = message   "rn";
            }
        }
        #endregion

        #region 数据解码图像处理线程
        private int CountNum = 0;
        //private int ErrorNum = 0;
        public bool getMeanMatFlag;
        //private string WenduC = "";
        //private string str2 = "";
        Stopwatch elapsetime = new Stopwatch();


        /// <summary>
        /// 数据解码图像处理
        /// </summary>
        private void DataDecodeImageProcessThread()
        {
            try
            {
                List<Byte[]> GetTask = new List<Byte[]>();  //数据缓存队列
                List<Byte[]> listBuff = new List<Byte[]>(); //多余数据缓存区
                THZData thzdata = new THZData();               //Thz数据

                while (true)
                {
                    //接收数据
                    TaskSemaphore.WaitOne();                //等待接收队列


                    lock (ThreadLock)                       //锁线程  
                    {
                        GetTask = DataQueue.Dequeue();   //Queue<List<Byte[]>> DataQueue = new Queue<List<Byte[]>>();
                    }

                    string[] duration = new string[3] { "", "", "" };
                    elapsetime.Restart();//计时开始
                    //数据解析解码
                    //DataDecode(GetTask, ref listBuff, ref thzdata);
                    

                    DataDecode_v1(GetTask, ref listBuff, ref thzdata);
                    //Console.WriteLine("123");


                    elapsetime.Stop();//计时结束
                    duration[0] = elapsetime.ElapsedMilliseconds.ToString("000");
                    //背景校准
                    //if (getMeanMatFlag)
                    //{
                    //    if (frame.UserData != null)
                    //        MeanMatList.Add(frame);

                    //    if (MeanMatList.Count == 10)
                    //    {
                    //        MeanMat = getMeanMat(MeanMatList);
                    //        MeanMatList.Clear();
                    //        getMeanMatFlag = false;
                    //    }
                    //    ImageClass.MeanMat = MeanMat;
                    //}
                    elapsetime.Restart();//计时开始


                    thzdata.StartImageProcess();
                    if (thzdata.FilterImage != null)   ///FilterImage滤波后图像
                    {
                        if (!Directory.Exists("ZHEN"))
                            Directory.CreateDirectory("ZHEN");

                        thzdata.FilterImage.Mat.Bitmap.Save("ZHEN\"   DateTime.Now.ToString("HHmmssfff")   ".bmp");
                    }

                    elapsetime.Stop();//计时结束
                    duration[1] = elapsetime.ElapsedMilliseconds.ToString("0000");
                    duration[2] = (Convert.ToInt32(duration[0])   Convert.ToInt32(duration[1])).ToString("0000");
                    //温度显示
                    double[] temparture = thzdata.GetTemparture();
                    if (thzdata.FinalImage != null)
                    {
                        ShowData SD = new ShowData(thzdata.FinalImage.Bitmap, temparture, duration, thzdata.isPeople, thzdata.isHidden);//thzdata.isPeople

                        // 任务队列为临界资源,需要锁 
                        lock (ThreadLock1)
                        {
                            ShowQueue.Enqueue(SD);

                        }
                        // 每添加一个任务,信号量加1
                        TaskSemaphore1.Release(1);
                    }
                    //if (ShowEvent != null && thzdata.FinalImage != null)
                    //    ShowEvent(thzdata.FinalImage.Bitmap, duration, Temparture, thzdata.isPeople);
                    //ShowEvent(PB1Image, ImageClass.lImage, ImageClass.isPeople, elapsetime.ElapsedMilliseconds.ToString(), ImageClass.HideGoods, "错帧数:"   ErrorNum);
                    //ShowTextEvent.Invoke(ImageClass.OutArray.Bitmap);


                }
            }
            catch (Exception ex)
            {
                string fileName = "Log\debug"   localPort   "_DataDecode.txt";
                string content = DateTime.Now.ToLocalTime()   ex.Message   "n"   ex.StackTrace   "rn";
                Logger(fileName, content);
            }

        }

        Queue<ShowData> ShowQueue = new Queue<ShowData>();  //数据缓存队列
        Semaphore TaskSemaphore1 = new Semaphore(0, 2560);  //数据缓存队列缓存区 
                                                           //第一个就是信号量的内部整数初始值,也就是初始请求数,第二个参数就是最大请求数。

        object ThreadLock1 = new object();
        private void ShowAllVariables()
        {
            ShowData GetTask = new ShowData();  //数据缓存队列
            while (true)
            {
                //接收数据
                TaskSemaphore1.WaitOne();                //等待接收队列
                lock (ThreadLock1)                       //锁线程  
                {
                    GetTask = ShowQueue.Dequeue();
                }

                if (GetTask.ThzImage != null)
                {
                    if (!Directory.Exists("ZHEN"))
                        Directory.CreateDirectory("ZHEN");


                }

                if (ShowEvent != null && GetTask.ThzImage != null)
                    ShowEvent(GetTask.ThzImage, GetTask.Duration, GetTask.Temparture, GetTask.IsPeople, GetTask.IsHidden);

            }
        }

        public void Correct()
        {
            THZData.Recorrect = true;
        }

        //public void SetMirror(bool mirrorFlag)
        //{
        //    thzdata.MirrirFlag = mirrorFlag;
        //}
        #endregion

        /// <summary>
        /// 数据解码
        /// </summary>
        /// <param name="GetTask">List</param>
        /// <param name="listBuff">List</param>
        /// <param name="frame">输出PartData</param>
        /// <param name="FrameLength">FrameLength</param>
        /// <param name="PackageNum">PackageNum</param>
        void DataDecode(List<Byte[]> GetTask, ref List<Byte[]> listBuff, ref THZData frame)
        {
            int PackageNum = 25;
            //if (listBuff.Count >= 100)
            //{
            //    listBuff.Clear();
            //    return;
            //}
            //排除异常项
            listBuff.RemoveAll(s => s.Count() < 1000);

            StringBuilder sNeed = new StringBuilder();

            GetTask.AddRange(listBuff);
            listBuff.Clear();

            foreach (var item in GetTask.OrderBy(s => 256 * s[6]   s[7]).GroupBy(s => 256 * 256 * 256 * s[2]   256 * 256 * s[3]   256 * s[4]   s[5]))
            {
                //PackageNum = 256 * item.ToList()[0][0]   item.ToList()[0][1];
                if (item.Count() == PackageNum)
                {

                    var Zhendata = item.OrderBy(s => s[6] * 256   s[7]).ToList();

                    if (Zhendata[0].Count() != 1420)
                        continue;

                    foreach (Byte[] match in Zhendata)
                        sNeed.Append(BitConverter.ToString(match).Replace("-", "").Substring(20).ToUpper());
                    //if (!Directory.Exists("ZHEN"))
                    //    Directory.CreateDirectory("ZHEN");
                    //writerFile(strToToHexByte(sNeed.ToString().Substring(0)), "ZHEN\Port"   localPort   "_Frame"   (CountNum) % 10000   ".bin");
                    CountNum  ;
                    frame.Init(sNeed.ToString());//???
                    //DecodeFrame(sNeed, ref frame, indexHead, indexTair); 

                    sNeed.Clear();
                }
                else
                {
                    listBuff.AddRange(item.ToList());
                }
            }

        }
        /// <summary>
        /// 数据解码
        /// </summary>
        /// <param name="GetTask">List</param>
        /// <param name="listBuff">List</param>
        /// <param name="frame">输出PartData</param>
        /// <param name="FrameLength">FrameLength</param>
        /// <param name="PackageNum">PackageNum</param>
        void DataDecode_v1(List<Byte[]> GetTask, ref List<Byte[]> listBuff, ref THZData frame)   //ref作用?
        {
            int PackageNum = 25;
            //if (listBuff.Count >= 100)
            //{
            //    listBuff.Clear();
            //    return;
            //}
            //排除异常项
            listBuff.RemoveAll(s => s.Count() < 1000);

            StringBuilder sNeed = new StringBuilder();

            GetTask.AddRange(listBuff);
            listBuff.Clear();
           

            foreach (var item in GetTask.OrderBy(s => 256 * s[6]   s[7]).GroupBy(s => 256 * 256 * 256 * s[2]   256 * 256 * s[3]   256 * s[4]   s[5])) //按照包排序、按照帧分组,每次取出一帧
            {

                PackageNum = 256 * item.ToList()[0][0]   item.ToList()[0][1];//获取一帧前两个字节的值,即单帧包数
                if (item.Count() == PackageNum)//如果一帧的包数量和PackageNum相等则是一个完整的包
                {

                    var Zhendata = item.OrderBy(s => s[6] * 256   s[7]).ToList();//一帧数据按照包排序后存放到Zhendata

                    if (Zhendata[0].Count() != 1420)//第一包不是1420则退出
                        continue;

                    //dc.tempartureData_zyr(Zhendata, ShowEvent_zyr2);
                    dc.adDataCaculate_zyr(Zhendata, ShowEvent_zyr1,ShowEvent_zyr2);

                    foreach (Byte[] match in Zhendata)  //每次取出一个包也就是1420字节,取一帧的数据
                        sNeed.Append(BitConverter.ToString(match).Replace("-", "").Substring(20).ToUpper());
                    //if (!Directory.Exists("ZHEN"))
                    //    Directory.CreateDirectory("ZHEN");
                    writerFile(strToToHexByte(sNeed.ToString().Substring(0)), "ZHEN\Port"   localPort   "_Frame"   (CountNum) % 10000   ".bin");
                    CountNum  ;
                    frame.Init(sNeed.ToString());
                    //DecodeFrame(sNeed, ref frame, indexHead, indexTair); 

                    sNeed.Clear();
                }
                else
                {
                    listBuff.AddRange(item.ToList());
                }
            }

        }
        void DataDecode_v2(List<Byte[]> GetTask, ref List<Byte[]> listBuff, ref THZData frame)
        {
            int PackageNum = 25;
            //int ChannelCount = 36;
            //int SampleCount = 473;
     
            listBuff.RemoveAll(s => s.Count() < 1000);

            StringBuilder sNeed = new StringBuilder();

            GetTask.AddRange(listBuff);
            listBuff.Clear();

            foreach (var item in GetTask.OrderBy(s => 256 * s[6]   s[7]).GroupBy(s => 256 * 256 * 256 * s[2]   256 * 256 * s[3]   256 * s[4]   s[5])) //按照包排序、按照帧分组
            {
                PackageNum = 256 * item.ToList()[0][0]   item.ToList()[0][1];
                if (item.Count() == PackageNum)
                {

                    var Zhendata = item.OrderBy(s => s[6] * 256   s[7]).ToList();

                    if (Zhendata[0].Count() != 1420)
                        continue;

                    /*mycode*/
                    /* List<Byte> frameByteData = new List<Byte>();
                     double[] ChannelData = new double[438] ;
                     double avg = 0, Variance;
                     foreach (Byte[] Package in Zhendata)
                         foreach (Byte byt in Package)
                             frameByteData.Add(byt);
                     MessageBox.Show(frameByteData.Count().ToString());
                     ChannelCount = 256 * item.ToList()[0][26]   item.ToList()[0][27];
                     SampleCount = 256 * item.ToList()[0][28]   item.ToList()[0][29];
                     for (int i = 0; i < ChannelCount; i  )    // 36
                     {
                         for (int j = 0; j < SampleCount; j  )  // 438
                             ChannelData[j]= frameByteData[j * 74   51 i] * 256   frameByteData[j * 74   52 i];
                         avg = Var(ChannelData);
                         Variance=ChannelData.Average();
                         strWrite(ChannelData "--" avg "--" Variance, Environment.CurrentDirectory   "\bin","ad.txt");

                     }*/

                    


                    foreach (Byte[] match in Zhendata)
                        sNeed.Append(BitConverter.ToString(match).Replace("-", "").Substring(20).ToUpper());

                    strToToHexByte(sNeed.ToString().Substring(0));


                    //if (!Directory.Exists("ZHEN"))
                    //    Directory.CreateDirectory("ZHEN");
                    writerFile(strToToHexByte(sNeed.ToString().Substring(0)), "ZHEN\Port"   localPort   "_Frame"   (CountNum) % 10000   ".bin");
                    CountNum  ;
                    frame.Init(sNeed.ToString());
                    //DecodeFrame(sNeed, ref frame, indexHead, indexTair); 

                    sNeed.Clear();
                }
                else
                {
                    listBuff.AddRange(item.ToList());
                }
            }

        }


        /* public void callBack_zyr1(int row, int column, string str)
         {

            ShowEvent_zyr1(row, column, str);
          }
     public void callBack_zyr2(string str)
     {

         ShowEvent_zyr2(str);
     }*/
        #region mycode_zyr
        // DataProcess dp = null;
        //public void tempartureData_zyr(List<byte[]> Zhendata)
        //{
        //    StringBuilder sNeed = new StringBuilder();

        //    foreach (Byte[] match in Zhendata)
        //        sNeed.Append(BitConverter.ToString(match).Replace("-", "").Substring(20).ToUpper());
        //    double[] temparture = GetTemparture_zyr(sNeed.ToString());
        //    // mf.ShowlbDevTem(string.Format("设备温度:nT1:{0:N}°nT2:{1:N}°nT3:{2:N}°nT4:{3:N}°", temparture[0], temparture[1], temparture[2], temparture[3]));
        //    ShowEvent_zyr2(string.Format("设备温度:nT1:{0:N}°nT2:{1:N}°nT3:{2:N}°nT4:{3:N}°", temparture[0], temparture[1], temparture[2], temparture[3]));
        //   // dp.callBack_zyr2(string.Format("设备温度:nT1:{0:N}°nT2:{1:N}°nT3:{2:N}°nT4:{3:N}°", temparture[0], temparture[1], temparture[2], temparture[3]));
        //    sNeed.Clear();
        //    foreach (var tem in temparture)
        //        sNeed.Append(tem   "***");
        //    strWrite_zyr(sNeed.ToString(), Environment.CurrentDirectory   "\bin", "tempartureData.txt");
        //    sNeed.Clear();


        //}

        public double[] GetTemparture_zyr(string str)
        {
            string tepStr = str.Substring(20 * 2, 8 * 2);
            double[] Temparture = new double[4];
            if (tepStr == null)
                return Temparture;
            byte[] Wen = DataProcess.strToToHexByte(tepStr);
            if ((Wen[0] & 0xf0) >> 4 == 15)
                Temparture[0] = -(~Wen[1]   1   256.0 * ~Wen[0]) / 16;
            else
                Temparture[0] = (Wen[1]   256.0 * Wen[0]) / 16;

            if ((Wen[2] & 0xf0) >> 4 == 15)
                Temparture[1] = -(~Wen[3]   1   256.0 * ~Wen[2]) / 16;
            else
                Temparture[1] = (Wen[3]   256.0 * Wen[2]) / 16;

            if ((Wen[4] & 0xf0) >> 4 == 15)
                Temparture[2] = -(~Wen[5]   1   256.0 * ~Wen[4]) / 16;
            else
                Temparture[2] = (Wen[5]   256.0 * Wen[4]) / 16;

            if ((Wen[6] & 0xf0) >> 4 == 15)
                Temparture[3] = -(~Wen[7]   1   256.0 * ~Wen[6]) / 16;
            else
                Temparture[3] = (Wen[7]   256.0 * Wen[6]) / 16;
            return Temparture;
        }
        int zhenRows = 0;
       /* public void adDataCaculate_zyr(List<byte[]> Zhendata)
        {
            byte[] byteData = new byte[35250];//1410*25
            int count1 = 0, count2 = 0;
            StringBuilder sNeed = new StringBuilder();
            MainForm mf = new MainForm();

            foreach (Byte[] Package in Zhendata)
            {
                count1 = 0;
                foreach (byte byt in Package)
                {
                    if (count1 >= 20)   //跳过第一个数
                    {

                        byteData[count2] = byt;
                        count2  ;

                    }
                    count1  ;
                }
            }
            // Console.ReadKey();
            double[] channel = new double[473];
            double variance = 0.0, average = 0.0;
            for (int i = 0; i < 36; i  )
            {
                for (int j = 0; j < 473; j  )
                {
                    byte bigByte = Convert.ToByte(byteData[j * 74   i * 2].ToString("X"), 16);
                    if ((bigByte & 0xf0) >> 4 == 15)
                        channel[j] = -(~byteData[j * 74   i * 2   30]   1   256.0 * ~byteData[j * 74   i * 2   31]) / 8192.0 * 10.0;//2^12 =4096
                    else
                        channel[j] = (byteData[j * 74   i * 2   30]   256.0 * ~byteData[j * 74   i * 2   31]) / 8192.0 * 10.0;
                    sNeed.Append(channel[j]   ",");
                }
                variance = Var_zyr(channel);
                //mf.dataShow(zhenRows, 2 * i   1, variance.ToString());
                ShowEvent_zyr1(zhenRows, 2 * i   1, variance.ToString());
                //dp.callBack_zyr1(zhenRows, 2 * i   1, variance.ToString());
                sNeed.Append("***variance:"   variance   "***average:");
                average = channel.Average();
                // mf.dataShow(zhenRows, 2 * i , average.ToString());
                 ShowEvent_zyr1(zhenRows, 2 * i, average.ToString());
                //dp.callBack_zyr1(zhenRows, 2 * i, average.ToString());
                sNeed.Append(average);
                strWrite_zyr(sNeed.ToString(), Environment.CurrentDirectory   "\bin", "channelData.txt");
                sNeed.Clear();
            }
            zhenRows  ;
        }*/

        public double Var_zyr(double[] v)
        {
            double sum1 = 0;
            for (int i = 0; i < v.Length; i  )
            {
                double temp = v[i] * v[i];
                sum1 = sum1   temp;
            }

            double sum = 0;
            foreach (double d in v)
            {
                sum = sum   d;
            }
            double var = sum1 / v.Length - (sum / v.Length) * (sum / v.Length);
            return var;
        }
        private int rowCount = 0;
        private void strWrite_zyr(string str, string filePath, string fileName)
        {

            if (!Directory.Exists(filePath))
                Directory.CreateDirectory(filePath);
            if (!File.Exists(filePath   "\"   fileName))
                File.Create(filePath   "\"   fileName).Close(); //.Close 很关键,不然会有问题
            if (rowCount < 3600)
            {
                StreamWriter sw = new StreamWriter(filePath   "\"   fileName, true);//true 追加数据
                sw.WriteLine(str);
                sw.Close();
                rowCount  ;
            }
            else
            {
                StreamWriter sw = new StreamWriter(filePath   "\"   fileName, false);
                sw.WriteLine(str);
                sw.Close();
                rowCount = 0;
            }
        }
        #endregion 
        private void strWrite(string str, string filePath, string fileName)
        {
            if (!Directory.Exists(filePath))
                Directory.CreateDirectory(filePath);
            if (!File.Exists(filePath   "\"   fileName))
                File.Create(filePath   "\"   fileName).Close(); //.Close 很关键,不然会有问题

            //方法一
            StreamWriter sw = new StreamWriter(filePath   "\"   fileName, true);
            sw.WriteLine(str);
            sw.Close();

            //方法2
           /* string path = "D1.txt";//文件的路径,保证文件存在。
            FileStream fs = new FileStream(path, FileMode.Append);
            SteamWriter sw = new StreamWriter(fs);
            sw.WriteLine(要追加的内容);
            sw.Close();
            fs.Close();*/
        }

       
        /// <summary>
        /// 字符串转16进制Byte字节
        /// </summary>
        /// <param name="hexString">输入字符串</param>
        /// <returns>转化的Byte字节</returns>
        public static byte[] strToToHexByte(string hexString)
        {
            hexString = hexString.Replace("-", "");
            if ((hexString.Length % 2) != 0)
                hexString  = "20";
            byte[] returnBytes = new byte[hexString.Length / 2];
            for (int i = 0; i < returnBytes.Length; i  )
                returnBytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16);
            return returnBytes;
        }

        /// <summary>
        /// 帧数据读取,存放
        /// </summary>
        /// <param name="array">帧数据数组</param>
        /// <param name="strPath">存放文件</param>
        private void writerFile(byte[] array, string strPath)
        {
            //string content = this.txtContent.Text.ToString();

            if (string.IsNullOrEmpty(strPath))
            {
                return;
            }

            //将string转为byte数组
            //byte[] array = Encoding.UTF8.GetBytes(content);

            //string path = Server.MapPath("/test.txt");
            //创建一个文件流
            FileStream fs = new FileStream(strPath, FileMode.Create);

            //将byte数组写入文件中
            fs.Write(array, 0, array.Length);
            //所有流类型都要关闭流,否则会出现内存泄露问题
            fs.Close();
            //Response.Write("保存文件成功");
        }

        private void Logger(string fileName, string content)
        {
            //StreamWriter sw = new StreamWriter(fileName, true);
            //sw.Write(content);
           // sw.Close(); sw.Dispose();

        }
    }

    class ShowData
    {
        public Bitmap ThzImage;
        public string[] Duration;
        public double[] Temparture;
        public bool IsPeople;
        public bool IsHidden;
        public ShowData() { }
        public ShowData(Bitmap bitmap, double[] temparture, string[] duration, bool peopleFlag, bool hidFlag)
        {
            ThzImage = bitmap;
            IsPeople = peopleFlag;
            IsHidden = hidFlag;
            Duration = duration;
            Temparture = temparture;
        }
    }
}

类THZData.cs:

代码语言:javascript复制
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Emgu.CV;
using Emgu.CV.CvEnum;
using Emgu.CV.Structure;
using Emgu.CV.UI;
using Emgu.Util;
using System.Drawing;
using System.Threading.Tasks;

namespace ThzData
{
    public class THZData
    {
        private FrameMsg frameMsg;
        private Byte[] frameData;
        private int frameLength;
        private int ImageHeight;
        private int oriImageWidth;

        public bool isPeople;                   //人物判断
        public bool isHidden;
        private Matrix<int> backgroundframe;    //判定中间背景帧
        private List<Matrix<double>> multiImageList;//多帧平均列表
        public Matrix<double> PreProcessImage;  //预处理后图像
        public Matrix<byte> AlignImage;         //校准后图像
        public Matrix<int> MeanMat;             //输入的背景均值矩阵
        public Matrix<byte> FilterImage;        //滤波后图像
        public Mat FinalImage;                  //最终图像
        //public Dictionary<Rectangle, string> dictRects;//可疑块目标框架
        //public Dictionary<Mat, Rectangle> dictCoutours;//可疑轮廓内部信息
        public List<Rectangle> listRects;
        public bool MirrirFlag;
        public static bool Recorrect = false;
        int count = 0;

        const int JBianNum = 13;
        const int iHumanThreshold = 35;
        const int resizeImageWidth = 183;


        public THZData()
        {
            this.frameMsg = new FrameMsg();
            this.isPeople = false;
            this.isHidden = false;
            this.multiImageList = new List<Matrix<double>>();

        }

        public void Init(string allMsg)
        {
            if (allMsg.Count() > 0 && frameMsg != null)
            {
                //this.frameMsg.Init(allMsg.Substring(8, 36 * 2));
                this.frameMsg.Init_v1(allMsg.Substring(8, 36 * 2));
                this.ImageHeight = Convert.ToInt32(frameMsg.SampNum, 16); //BitConverter.ToInt32(Encoding.Default.GetBytes(frameMsg.SampNum), 0);
                this.oriImageWidth = Convert.ToInt32(frameMsg.ChannelNum, 16);//16进制str转int
                this.frameLength = Convert.ToInt32(frameMsg.DataLength, 16);// BitConverter.ToInt32(Encoding.Default.GetBytes(frameMsg.DataLength), 0);
                this.frameData = strToToHexByte(allMsg.Substring(80, frameLength * 2));//frameLength,28860

                if (MeanMat == null)
                    this.MeanMat = new Matrix<int>(new Size(1, ImageHeight * oriImageWidth));

                this.backgroundframe = new Matrix<int>(new Size(1, ImageHeight * oriImageWidth));
                this.PreProcessImage = new Matrix<double>(new Size(1, (ImageHeight - JBianNum) * oriImageWidth));
                this.AlignImage = new Matrix<byte>(new Size(resizeImageWidth * 2, (ImageHeight - JBianNum) * 2));
                this.FinalImage = new Mat();
                this.FilterImage = new Matrix<byte>(new Size(resizeImageWidth * 2, (ImageHeight - JBianNum) * 2));
                //this.dictRects = new Dictionary<Rectangle, string>();
                //this.dictCoutours = new Dictionary<Mat, Rectangle>();
                this.listRects = new List<Rectangle>();

            }
        }

        /// <summary>
        /// 开始处理数据
        /// </summary>
        /// <param name="frame">PartData</param>
        public void StartImageProcess()
        {
            if (this.frameData == null)
                return;

            this.isHidden = false;
            //获取畸变矫正后初始矩阵
            getInitMatrix();

            //加权归一化
            Normalization();

            if (isPeople)
            {
                //滤波,分割,识别
                Filter();
                Seg_Reg();
            }
            else
            {
                CvInvoke.CvtColor(AlignImage, this.FinalImage, ColorConversion.Gray2Bgr);//Outputtemp,BoxArray
            }
            //CvInvoke.CvtColor(AlignImage, this.FinalImage, ColorConversion.Gray2Bgr);//Outputtemp,BoxArray
        }

        /// <summary>
        /// 获取畸变矫正后初始矩阵
        /// </summary>
        /// <param name="Data">Matrix<Byte></param>
        private void getInitMatrix()
        {
            Matrix<Byte> Data = new Matrix<Byte>(this.frameData);    //Byte转Matrix
            //临时变量temp1,temp2和temp3
            int Height = this.ImageHeight;
            int Width = this.oriImageWidth;
            Matrix<int> temp1 = new Matrix<int>(new Size(1, Height * Width));
            Matrix<double> temp2 = new Matrix<double>(new Size(1, Height * Width));
            //Matrix<double> temp3 = new Matrix<double>(new Size(1, Height * Width));

            //获取矩阵,temp1
            for (int i = 0; i < Height; i  )
            {
                for (int j = 0; j < Width; j  )
                {
                    //temp[i * n   j, 0] = (256 * msImg[i * 2 * (n   1)   2*j, 0]   msImg[i * 2 * (n   1)   2*j   1, 0])/16;
                    temp1[i   j * Height, 0] = (256 * Data[i * 2 * (Width   1)   2 * j, 0]   Data[i * 2 * (Width   1)   2 * j   1, 0]);
                }
            }

            //判断是否有人
            double MMMAX = 0;
            for (int j = 0; j < Width; j  )
            {
                Matrix<int> temptemp = new Matrix<int>(new Size(1, Height));
                for (int i = 0; i < Height; i  )
                {
                    temptemp[i, 0] = temp1[i   j * Height, 0];
                }
                //屏蔽某列
                //if (j == 35)
                //    continue;
                double Maxnum, Minnum;
                Point a, b;
                temptemp.MinMax(out Minnum, out Maxnum, out a, out b);

                MMMAX = (Maxnum - Minnum) > MMMAX ? (Maxnum - Minnum) : MMMAX;
            }
            isPeople = MMMAX > iHumanThreshold;                             //MMMax 行峰峰值

            //奇偶翻转,temp2
            if (this.frameMsg.Isodd)
            {
                for (int i = 0; i < Height; i  )
                {
                    for (int j = 0; j < Width; j  )
                    {
                        backgroundframe[j * Height   (Height - 1 - i), 0] = temp1[j * Height   i, 0];
                    }
                }
            }
            else
            {
                backgroundframe = temp1;
            }

            //背景校准
            if (!isPeople)
            {
                //自动背景校准
                MeanMat = MeanMat * 3 / 4   backgroundframe / 4;
            }
            else if (Recorrect)
            {
                count  ;
                //手动背景校准
                MeanMat = MeanMat * 3 / 4   backgroundframe / 4;
                if (count > 15)
                    Recorrect = true;
            }

            //减背景均值,temp3
            //修改人 於景瞵 2018.6.1 列均值
            Matrix<double> MeanRow = new Matrix<double>(new Size(1, Width));
            for (int i = 0; i < Width; i  )
            {
                for (int j = 0; j < Height; j  )
                {
                    MeanRow[i, 0]  = MeanMat[j   i * Height, 0];

                }
                MeanRow[i, 0] = MeanRow[i, 0] / Height;
            }
            for (int i = 0; i < Height; i  )
            {
                for (int j = 0; j < Width; j  )
                {
                    temp2[i   j * Height, 0] = (backgroundframe[i   j * Height, 0] - MeanRow[j, 0]); // 通道均匀系数* Mean_p[j, 0];
                    //屏蔽某列
                    //if (j == 35) //j == 33 || j == 34 ||
                    //    temp2[i   j * Height, 0] = 0;
                }
            }
            //修改人 於景瞵 2018.6.1 点均值
            //for (int i = 0; i < Height; i  )
            //{
            //    for (int j = 0; j < Width; j  )
            //    {
            //        temp2[i   j * Height, 0] = (backgroundframe[i   j * Height, 0] - MeanMat[i   j * Height, 0]) * Mean_p[j, 0];
            //        //屏蔽某列
            //        //if (j == 35) //j == 33 || j == 34 ||
            //        //    temp2[i   j * Height, 0] = 0;
            //    }
            //}

            //奇偶抖动矫正
            //if (this.frameMsg.Isodd)
            //{
            //    for (int i = 0; i < Height; i  )
            //    {
            //        for (int j = 0; j < Width; j  )
            //        {
            //            temp3[j * (Height)   i, 0] = temp2[j * Height   i, 0];
            //        }
            //    }
            //}
            //else
            //{
            //    for (int i = 0; i < Height ; i  )
            //    {
            //        for (int j = 0; j < Width; j  )
            //        {
            //            temp3[j * (Height)   i, 0] = temp2[j * Height   i, 0];
            //        }
            //    }
            //}

            //畸变矫正InitMatrix


            for (int i = 0; i < (Height) - JBianNum; i  )
            {
                for (int j = 0; j < Width / 2; j  )
                {
                    //PreProcessImage = InitMatrix;
                    if (MirrirFlag)
                    {
                        PreProcessImage[(2 * j) * (Height - JBianNum)   i, 0] = temp2[(2 * j) * (Height)   (i   0), 0];
                        PreProcessImage[(2 * j   1) * (Height - JBianNum)   i, 0] = temp2[(2 * j   1) * (Height)   (i   JBianNum), 0];
                    }
                    //镜像
                    else
                    {
                        PreProcessImage[(Width - 2 * j - 1) * (Height - JBianNum)   i, 0] = temp2[(2 * j) * (Height)   (i   0), 0];
                        PreProcessImage[(Width - 2 * j - 2) * (Height - JBianNum)   i, 0] = temp2[(2 * j   1) * (Height)   (i   JBianNum), 0];
                    }
                }
            }


        }

        /// <summary>
        /// 加权归一化,和插值
        /// </summary>
        private void Normalization()
        {
            int height = this.ImageHeight - JBianNum;     //矫正后图像高度
            int width = this.oriImageWidth;                          //可以屏蔽一些列


            Matrix<double> temp = new Matrix<double>(new Size(1, width * height));
            Matrix<Byte> temp2 = new Matrix<Byte>(new Size(width, height));
            //Matrix<Byte> temp3 = new Matrix<Byte>(new Size(183 * 2, height * 2));

            //加多帧平均算法
            multiImageList.Add(PreProcessImage);
            //加权系数
            double p1 = 0.0;
            double p2 = 0.0;
            double p3 = 1 - p1 - p2;
            if (multiImageList != null && multiImageList.Count > 3)
            {
                multiImageList.RemoveAt(0);
                temp = p1 * multiImageList[0]   p2 * multiImageList[1]   p3 * multiImageList[2];
            }
            else
            {
                temp = PreProcessImage;
            }

            //最大值最小值
            double Maxnum, Minnum;
            Point a, b;
            temp.MinMax(out Minnum, out Maxnum, out a, out b);
            //isPeople = (Maxnum - Minnum) > 70;

            //归一化
            if (isPeople)
            {
                //Parallel.For(0, height, i =>
                //{
                //    for (int j = 0; j < width; j  )
                //    {
                //        //temp2[i, j] = (Byte)(255 - (int)(Math.Pow(((temp[i   j * height, 0] - Minnum) / (Maxnum - Minnum)), 0.75) * 255));
                //        //temp2[i, j] = (Byte)(int)(Math.Pow(((temp[i   j * height, 0] - Minnum) / (Maxnum - Minnum)), 1.2) * 255);
                //        //镜像
                //        temp2[i, width - 1 - j] = (Byte)(int)(Math.Pow(((temp[i   j * height, 0] - Minnum) / (Maxnum - Minnum)), 1.2) * 255);
                //        //CvInvoke.Normalize(temp2,temp2,255);
                //    }
                //});

                for (int i = 0; i < height; i  )
                {
                    for (int j = 0; j < width; j  )
                    {
                        //temp2[i, j] = (Byte)(255 - (int)(Math.Pow(((temp[i   j * height, 0] - Minnum) / (Maxnum - Minnum)), 0.75) * 255));
                        //temp2[i, j] = (Byte)(int)(Math.Pow(((temp[i   j * height, 0] - Minnum) / (Maxnum - Minnum)), 1.2) * 255);
                        //镜像
                        //temp2[i, width - 1 - j] = (Byte)(int)(Math.Pow(((temp[i   j * height, 0] - Minnum) / (Maxnum - Minnum)), 1.2) * 255);
                        temp2[i, width - 1 - j] = (Byte)(int)((temp[i   j * height, 0] - Minnum) / (Maxnum - Minnum) * 255);

                    }
                }
                //CvInvoke.Normalize(temp, temp2,255);
            }
            else
            {
                //Parallel.For(0, height, i =>
                //{
                //    for (int j = 0; j < width; j  )
                //    {
                //        //temp2[i, j] = (Byte)(50 - (int)(Math.Pow(((temp[i   j * height, 0] - Minnum) / (Maxnum - Minnum)), 0.75) * 50));
                //        //temp2[i, j] = (Byte)(int)(Math.Pow(((temp[i   j * height, 0] - Minnum) / (Maxnum - Minnum)), 1.0) * 30);
                //        //镜像
                //        //temp2[i, width - 1 - j] = (Byte)(int)(Math.Pow(((temp[i   j * height, 0] - Minnum) / (Maxnum - Minnum)), 1.0) * 30);
                //        CvInvoke.Normalize(temp2, temp2, 30);
                //    }
                //});

                for (int i = 0; i < height; i  )
                {
                    for (int j = 0; j < width; j  )
                    {
                        //temp2[i, j] = (Byte)(50 - (int)(Math.Pow(((temp[i   j * height, 0] - Minnum) / (Maxnum - Minnum)), 0.75) * 50));
                        //temp2[i, j] = (Byte)(int)(Math.Pow(((temp[i   j * height, 0] - Minnum) / (Maxnum - Minnum)), 1.0) * 30);
                        //镜像
                        //temp2[i, width - 1 - j] = (Byte)(int)(Math.Pow(((temp[i   j * height, 0] - Minnum) / (Maxnum - Minnum)), 1.0) * 30);
                        temp2[i, width - 1 - j] = (Byte)(int)((temp[i   j * height, 0] - Minnum) / (Maxnum - Minnum) * 30);

                    }
                }
                //CvInvoke.Normalize(temp, temp2);


            }

            //插值Resize
            CvInvoke.Resize(temp2, this.AlignImage, new Size(resizeImageWidth * 2, height * 2), 0, 0, Inter.Lanczos4);//183 * 2, height * 2

            //InitMiddleImage = temp3.Mat;
            //this.AlignImage = temp3;

        }

        /// <summary>
        /// filter滤波 
        /// </summary>
        private void Filter()
        {
            //isWarningImage = false;
            Matrix<byte> BoxArray = this.AlignImage.Clone();           //滤波矩阵
            //Mat MedianMat = InitMiddleImage.Clone();
            //Matrix<byte> MedianMat = this.AlignImage.Clone();
            //Mat Outputtemp = new Mat();
            //BoxArray._Mul(MedianMat);

            //中值滤波
            CvInvoke.MedianBlur(BoxArray, BoxArray, 9);
            //Boxfilter
            CvInvoke.BoxFilter(BoxArray, BoxArray, DepthType.Cv8U, new Size(9, 9), new Point(-1, -1), true, BorderType.Reflect101);
            //CvInvoke.FastNlMeansDenoising(MedianMat,BoxArray);

            //背景归0
            //Matrix<byte> tempArray = new Matrix<byte>(new Size(BoxArray.Width, BoxArray.Height));
            //CvInvoke.Threshold(BoxArray, tempArray, 100, 1, ThresholdType.Binary);
            //BoxArray._Mul(tempArray);

            //ACE图像增强
            BoxArray = ACE(BoxArray);
            //CvInvoke.MedianBlur(BoxArray, BoxArray, 9);
            CvInvoke.BoxFilter(BoxArray, BoxArray, DepthType.Cv8U, new Size(9, 9), new Point(-1, -1), true, BorderType.Reflect101);

            //输出图像为滤波后图像转三通道
            //CvInvoke.Threshold(BoxArray, Outputtemp, Th>50?Th:50, 255, ThresholdType.ToZero);
            CvInvoke.CvtColor(BoxArray, this.FinalImage, ColorConversion.Gray2Bgr);//Outputtemp,BoxArray
            this.FilterImage = BoxArray;
        }
        /// <summary>
        /// 自适应阈值分割   目标区域方块提取
        /// </summary>
        private void Seg_Reg()
        {
            ///分割
            //手动阈值

            double Th = graythresh(FilterImage.Mat.GetData());//* 1.10    

            //阈值分割矩阵
            //Matrix<byte> ThreArray = InitMiddleImage.Clone();
            //自动阈值分割。。。自适应阈值分割,使用工具包
            //CvInvoke.Threshold(BoxArray, ThreArray, 80, 1, ThresholdType.Otsu);
            //BoxArray._Mul(ThreArray);

            //手动阈值分割。。。手动阈值分割,自写函数
            //double Th = graythresh(BoxArray.Mat.GetData())*1.10;
            CvInvoke.Threshold(FilterImage, FilterImage, Th * 1.10, 255, ThresholdType.ToZero);//InputArray,BoxArray,ThresholdType.ToZero,ThresholdType.Binary

            ///识别            
            regCoutour();

            ///画图
            drawCoutours();
        }

        bool matchCoutours(Mat roi)
        {
            //中心区域为黑
            if (CvInvoke.Mean(roi).V0 > 60)
                return false;
            else
                return true;
        }

        void drawCoutours()
        {
            var color = new MCvScalar(0, 0, 255);
            //if (isPeople)
            {

                //if (CountNum % 3 == 0)  //修改人 於景瞵 2018.4.23   
                {
                    //if (rects != null && rects.Count != 0 && rects.Count <= 10)
                    if (listRects != null && listRects.Count != 0 && listRects.Count <= 10) //修改时间18.4.16
                    {
                        ////isWarningImage = true;
                        ////HideGoods = "到"   dictRects.Count   "个危险品";
                        //foreach (var rect in dictRects)
                        //{
                        //    if (rect.Value == "一类")
                        //    {
                        //        HideGoods = "到"   rect.Value   "危险品";
                        //        break;
                        //    }
                        //    HideGoods = "到"   rect.Value   "危险品";
                        //}
                    }
                }

                if (listRects.Count <= 10 && listRects.Count > 0)
                {
                    this.isHidden = true;
                    foreach (var rect in listRects)
                    {
                        //Mat roi = new Mat(rect,new Rectangle(new Point(rect.Value.Width/2-1,rect.Value.Height/2-1),new Size(3,3)));
                        //中心区域为黑
                        //if (CvInvoke.Mean(roi).V0 > 60)
                        //    continue;
                        //if (matchCoutours(roi))
                        {
                            CvInvoke.Rectangle(FinalImage, rect, color);
                            //CvInvoke.PutText(FinalImage, "Hidden", rect.Value.Location, FontFace.HersheyComplex, 0.4, color);
                        }
                    }
                }
                //CountNum  ; //修改人 於景瞵 2018.4.23 
            }

        }

        /// <summary>
        /// 轮廓提取函数
        /// 20180416 修改人 於景瞵 
        /// </summary>
        /// <param name="srcimage"> 原始图像</param>
        /// <param name="OutImage"> 存放轮廓图像</param>
        /// <returns> 返回目标图像</returns>
        private void regCoutour()
        {
            Mat srcimage = this.FilterImage.Mat.Clone();
            Mat hierarchy = new Mat();
            Emgu.CV.Util.VectorOfVectorOfPoint Coutours = new Emgu.CV.Util.VectorOfVectorOfPoint();
            CvInvoke.FindContours(srcimage, Coutours, hierarchy, RetrType.List, ChainApproxMethod.LinkRuns, new Point(0, 0));
            //imageBox1.Image = b2;

            //List<Rectangle> rects = new List<Rectangle>();
            //开始遍历
            for (int i = 0; i < Coutours.Size; i  )
            {
                //得到这个连通区域的外接矩形
                var rect = CvInvoke.BoundingRectangle(Coutours[i]);
                //var Rect = CvInvoke.MinAreaRect(Coutours[i]);
                //var Area = CvInvoke.ContourArea(Coutours[i]);
                //如果高度不足,或者长宽比太小,认为是无效数据,否则把矩形画到原图上
                if ((rect.Height > 13 && rect.Width > 13) && (rect.Height < srcimage.Rows / 4 || rect.Width < srcimage.Cols / 4)
                    && rect.Height < srcimage.Rows * 3 / 5 && rect.Left > srcimage.Cols / 6 && rect.Right < srcimage.Cols * 5 / 6
                    && rect.Top > srcimage.Rows / 4 && rect.Bottom < srcimage.Rows * 3 / 4)
                {

                    //int a = srcimage.Bitmap.GetPixel(rect.X   rect.Width / 2, rect.Y   rect.Height / 2).B;
                    var Rect = CvInvoke.MinAreaRect(Coutours[i]);
                    var Area = CvInvoke.ContourArea(Coutours[i]);
                    listRects.Add(rect);
                    //if (Area / (Rect.Size.Height * Rect.Size.Width) < 0.8)
                    //    dictRects.Add(rect, "一类");
                    //else if (Rect.Size.Height / Rect.Size.Width < 1.0 / 3.0 || Rect.Size.Height / Rect.Size.Width > 3.0)
                    //    dictRects.Add(rect, "一类");
                    //else if (Area > 2000)
                    //    dictRects.Add(rect, "一类");
                    //else
                    //    dictRects.Add(rect, "二类");
                    //CvInvoke.DrawContours(b1, b3, i, color);
                }
            }

            //foreach (var rect in listRects)
            //{
            //    Mat roiMat = new Mat(FilterImage.Mat,rect.Key);
            //    this.dictCoutours.Add(roiMat, rect.Key);
            //}
        }

        /// <summary>
        /// 20180323 修改人 於景瞵 
        /// ACE图像增强算法
        /// </summary>
        /// <param name="src"></param>
        /// <param name="MaxCG"></param>
        /// <param name="C"></param>
        /// <param name="n"></param>
        /// <returns></returns>
        Matrix<byte> ACE(Matrix<byte> src, double MaxCG = 2.0, int Amount = 140, int Radius = 40)
        {
            //图像高宽
            int rows = src.Width;
            int cols = src.Height;

            //背景归0化
            //Matrix<byte> ThreArray = new Matrix<byte>(new Size(rows, cols));
            //CvInvoke.Threshold(src, ThreArray, 60, 1, ThresholdType.Otsu);
            //src._Mul(ThreArray);

            //源图像double初始化
            Matrix<double> Src = src.Convert<double>() / 255.0;
            //全局和局部均值标准差矩阵初始化
            Matrix<double> meanLocal = new Matrix<double>(new Size(rows, cols)); //图像局部均值  
            Matrix<double> varLocal = new Matrix<double>(new Size(rows, cols));  //图像局部方差  
            Matrix<double> meanGlobal = new Matrix<double>(new Size(rows, cols));//全局均值
            Matrix<double> varGlobal = new Matrix<double>(new Size(rows, cols)); //全局标准差  

            //局部均值和高频成分计算
            CvInvoke.Blur(Src, meanLocal, new Size(Radius, Radius), new Point(-1, -1));
            Matrix<double> highFreq = Src - meanLocal;//高频成分 

            //局部标准差计算
            varLocal = highFreq.Clone();
            varLocal._Mul(highFreq);
            CvInvoke.Blur(varLocal, varLocal, new Size(Radius, Radius), new Point(-1, -1));
            CvInvoke.Sqrt(varLocal, varLocal);

            //CGArr初始化
            Matrix<double> cGArr = new Matrix<double>(new Size(rows, cols));

            //全局均值与标准差计算
            MCvScalar meanGloble = new MCvScalar();
            MCvScalar stdGloble = new MCvScalar();
            CvInvoke.MeanStdDev(Src, ref meanGloble, ref stdGloble);

            //求取CGArr
            double D = Amount * stdGloble.V0 / 100;                             //CGArr系数
            Matrix<double> temp = new Matrix<double>(new Size(rows, cols))   1;
            CvInvoke.Divide(D * temp, varLocal, cGArr);
            //cGArr = Amount * varLocal / stdGloble.V0;

            //封顶CGArr
            Matrix<byte> tempArr = cGArr.Convert<byte>();                       //cgArr转byte
            Matrix<byte> hFArr = tempArr.Clone();                               //封顶高频系数
            CvInvoke.Threshold(tempArr, hFArr, MaxCG, 1, ThresholdType.Binary);
            cGArr._Mul(1.0 - hFArr.Convert<double>());
            cGArr = (MaxCG * hFArr.Convert<double>())   cGArr;
            cGArr._Mul(highFreq);

            //返回值Byte化
            Matrix<byte> dst1 = ((meanLocal   cGArr) * 255).Convert<byte>();     //变增益方法
            //Mat dst2 = (meanLocal   Amount * highFreq).Convert<byte>().Mat;//恒增益方法

            return dst1;
        }

        #region graythresh灰度阈值子函数
        private static double[] getHist(byte[] img1)
        {
            int gray = 0;
            //int Width = img.GetLength(1);
            //int Height = img.GetLength(0);
            int length = img1.Length;
            double[] Hist = new double[256];
            double[] p = new double[256];
            double dSumHist = 0.0;

            Parallel.For(0, length, i =>
            {

                gray = img1[i];
                Hist[gray]  = 1.0;

            });

            //不统计0项
            //Hist[0] = 0;

            dSumHist = Hist.Sum();

            for (int i = 0; i < 256; i  )
            {
                p[i] = Hist[i] / dSumHist;

            }

            return p;
        }

        private static int iGetMaxidFromSigma_b_squared(double[] p)
        {
            int iMaxid = 0;
            int Length = p.GetLength(0);
            double[] dOmege = new double[Length];
            double[] dMu = new double[Length];
            double dMuMax = 0.0;
            double[] dSigma_b_squared = new double[Length];
            double dMaxSigma = 0.0;

            for (int i = 0; i < Length; i  )
            {
                if (i == 0)
                    dOmege[i] = p[i];
                else
                    dOmege[i] = dOmege[i - 1]   p[i];
            }//get Omege


            for (int i = 0; i < Length; i  )
            {
                if (i == 0)
                    dMu[i] = p[i];
                else
                    dMu[i] = dMu[i - 1]   p[i] * (i   1);
            }//get Mu
            dMuMax = dMu[Length - 1];//get MuMax


            for (int i = 0; i < Length; i  )
            {
                dSigma_b_squared[i] = (dMuMax * dOmege[i] - dMu[i]) * (dMuMax * dOmege[i] - dMu[i]) / (dOmege[i] * (1 - dOmege[i]));
                if (dMaxSigma < dSigma_b_squared[i])
                {
                    dMaxSigma = dSigma_b_squared[i];
                    iMaxid = i;
                }

            }//get dSigma_b_squared

            return iMaxid;
        }


        private static double graythresh(byte[] Input1)
        {
            double Th = new double();
            //int Length = Input.GetLength(0);
            //int Width = Input.GetLength(1);

            double[] p = getHist(Input1);
            Th = iGetMaxidFromSigma_b_squared(p);


            return Th;
        }
        #endregion

        /// <summary>
        /// 字符串转16进制Byte字节
        /// </summary>
        /// <param name="hexString">输入字符串</param>
        /// <returns>转化的Byte字节</returns>
        private byte[] strToToHexByte(string hexString)
        {
            hexString = hexString.Replace("-", "");
            if ((hexString.Length % 2) != 0)
                hexString  = "20";
            byte[] returnBytes = new byte[hexString.Length / 2];
            for (int i = 0; i < returnBytes.Length; i  )
                returnBytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16);
            return returnBytes;
        }

        public double[] GetTemparture()
        {
            double[] Temparture = new double[4];
            if (this.frameMsg.TempData == null)
                return Temparture;
            byte[] Wen = strToToHexByte(this.frameMsg.TempData);
            if ((Wen[0] & 0xf0) >> 4 == 15)
                Temparture[0] = -(~Wen[1]   1   256.0 * ~Wen[0]) / 16;
            else
                Temparture[0] = (Wen[1]   256.0 * Wen[0]) / 16;

            if ((Wen[2] & 0xf0) >> 4 == 15)
                Temparture[1] = -(~Wen[3]   1   256.0 * ~Wen[2]) / 16;
            else
                Temparture[1] = (Wen[3]   256.0 * Wen[2]) / 16;

            if ((Wen[4] & 0xf0) >> 4 == 15)
                Temparture[2] = -(~Wen[5]   1   256.0 * ~Wen[4]) / 16;
            else
                Temparture[2] = (Wen[5]   256.0 * Wen[4]) / 16;

            if ((Wen[6] & 0xf0) >> 4 == 15)
                Temparture[3] = -(~Wen[7]   1   256.0 * ~Wen[6]) / 16;
            else
                Temparture[3] = (Wen[7]   256.0 * Wen[6]) / 16;
            return Temparture;
        }
    }

    public class FrameMsg
    {
        //public string Head;
        public string HeadLength;
        public string TairLength;
        public string DataLength;
        public string ImageNum;
        public string ChannelNum;
        public string SampNum;
        public string EncodedData;
        public string TempData;
        public string DigSmall;
        public string DianjiState;
        public string VerDefe;
        public string HorDefe;
        public string Kuozhan;
        public string Tair;
        public bool Isodd;

        public void Init(string msg)
        {
            this.HeadLength = msg.Substring(0, 2 * 2);
            this.TairLength = msg.Substring(2 * 2, 2 * 2);
            this.DataLength = msg.Substring(4 * 2, 4 * 2);
            this.ImageNum = msg.Substring(8 * 2, 4 * 2);
            this.ChannelNum = msg.Substring(12 * 2, 2 * 2);
            this.SampNum = msg.Substring(14 * 2, 2 * 2);
            this.EncodedData = msg.Substring(16 * 2, 4 * 2);
            this.TempData = msg.Substring(20 * 2, 8 * 2);
            this.DigSmall = msg.Substring(28 * 2, 1 * 2);
            this.DianjiState = msg.Substring(29 * 2, 1 * 2);
            this.Kuozhan = msg.Substring(30 * 2, 6 * 2);

            this.Isodd = ((Convert.ToInt32(this.ImageNum, 16) & 0x01) == 1);
        }

        public void Init_v1(string msg)
        {
            this.HeadLength = msg.Substring(0, 2 * 2);
            this.TairLength = msg.Substring(2 * 2, 2 * 2);
            this.DataLength = msg.Substring(4 * 2, 4 * 2);
            this.ImageNum = msg.Substring(8 * 2, 4 * 2);
            this.ChannelNum = msg.Substring(12 * 2, 2 * 2);
            this.SampNum = msg.Substring(14 * 2, 2 * 2);
            //this.EncodedData = msg.Substring(16 * 2, 4 * 2);
            this.TempData = msg.Substring(16 * 2, 8 * 2);
            this.DigSmall = msg.Substring(24 * 2, 1 * 2);
            this.DianjiState = msg.Substring(25 * 2, 1 * 2);
            this.VerDefe = msg.Substring(26 * 2, 2 * 2);
            this.HorDefe = msg.Substring(28 * 2, 2 * 2);
            this.Kuozhan = msg.Substring(30 * 2, 6 * 2);

            this.Isodd = ((Convert.ToInt32(this.ImageNum, 16) & 0x01) == 1);
        }
    }
}

0 人点赞