C# 探测器测试系统 委托多线程

运行效果:

图片

重要知识点:

  1. 控件循环遍历操控;

  2. 队列数组的应用:

     private Queue<double>[] dataQueue = new Queue<double>[8]; //把Queue<double>看成一个类型 int[] a=new int [8]

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

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

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

主窗体MainForm.cs

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 = @"icon\stop.png";        const string startIcon = @"icon\start.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:

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:

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}\r\n", a));

                    }                
                //client.Close();            }            catch (Exception ex)            {                string fileName = "Log\\debug" + localPort + "_DataDecode.txt";                string content = DateTime.Now.ToLocalTime() + ex.Message + "\n" + ex.StackTrace + "\r\n";                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("\r\n");
              }*/
            //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 + "\r\n";            }        }        #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 + "\r\n";                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 = "D\1.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:

​​​​​​​

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
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值