运行效果:
重要知识点:
- 控件循环遍历操控;
- 队列数组的应用: 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);
}
}
}