实现温度数据处理功能:添加温度数据模型类、温度接收功能和相关集成
This commit is contained in:
319
Windows/CS/Framework4.0/Toprie/Toprie/TemperatureData.cs
Normal file
319
Windows/CS/Framework4.0/Toprie/Toprie/TemperatureData.cs
Normal file
@@ -0,0 +1,319 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Toprie
|
||||
{
|
||||
/// <summary>
|
||||
/// 温度数据模型类,用于存储和处理红外热像仪采集的温度数据
|
||||
/// </summary>
|
||||
public class TemperatureData
|
||||
{
|
||||
/// <summary>
|
||||
/// 温度数据矩阵
|
||||
/// 格式: [行][列]
|
||||
/// </summary>
|
||||
public float[,] TemperatureMatrix { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 温度数据的宽度(列数)
|
||||
/// </summary>
|
||||
public int Width { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 温度数据的高度(行数)
|
||||
/// </summary>
|
||||
public int Height { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 温度采集时间戳
|
||||
/// </summary>
|
||||
public DateTime Timestamp { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 最低温度值
|
||||
/// </summary>
|
||||
public float MinTemperature { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 最高温度值
|
||||
/// </summary>
|
||||
public float MaxTemperature { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 平均温度值
|
||||
/// </summary>
|
||||
public float AverageTemperature { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 根据原始数据创建温度数据实例
|
||||
/// </summary>
|
||||
/// <param name="rawData">原始温度数据(每个温度点为2字节)</param>
|
||||
/// <param name="width">温度矩阵宽度</param>
|
||||
/// <param name="height">温度矩阵高度</param>
|
||||
/// <param name="compensationValue">温度补偿值(从sdk_get_comp_temp获取)</param>
|
||||
public TemperatureData(byte[] rawData, int width, int height, float compensationValue = 0)
|
||||
{
|
||||
if (rawData == null)
|
||||
throw new ArgumentNullException(nameof(rawData));
|
||||
|
||||
if (width <= 0 || height <= 0)
|
||||
throw new ArgumentException("宽度和高度必须大于0");
|
||||
|
||||
Width = width;
|
||||
Height = height;
|
||||
TemperatureMatrix = new float[height, width];
|
||||
Timestamp = DateTime.Now;
|
||||
|
||||
ParseRawData(rawData, compensationValue);
|
||||
CalculateStatistics();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 解析原始温度数据
|
||||
/// </summary>
|
||||
/// <param name="rawData">原始温度数据</param>
|
||||
/// <param name="compensationValue">温度补偿值</param>
|
||||
private void ParseRawData(byte[] rawData, float compensationValue)
|
||||
{
|
||||
// 按照SDK文档,温度数据为每个点2字节,摄氏温度=(H*256+L)/10
|
||||
// 需要考虑数据分布逻辑:先发送第一行奇数列,再发送第一行偶数列,接着第二行奇数列,依此类推
|
||||
int dataIndex = 0;
|
||||
|
||||
// 处理奇数列
|
||||
for (int row = 0; row < Height; row++)
|
||||
{
|
||||
for (int col = 0; col < Width; col += 2)
|
||||
{
|
||||
if (dataIndex + 1 < rawData.Length)
|
||||
{
|
||||
// 按照SDK文档计算温度值:摄氏温度=(H*256+L)/10
|
||||
// 这里假设H是高位字节,L是低位字节
|
||||
int highByte = rawData[dataIndex];
|
||||
int lowByte = rawData[dataIndex + 1];
|
||||
float temperature = (highByte * 256 + lowByte) / 10.0f;
|
||||
|
||||
// 应用温度补偿值
|
||||
temperature += compensationValue;
|
||||
|
||||
TemperatureMatrix[row, col] = temperature;
|
||||
dataIndex += 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 处理偶数列
|
||||
dataIndex = 0; // 重置索引,重新遍历
|
||||
for (int row = 0; row < Height; row++)
|
||||
{
|
||||
for (int col = 1; col < Width; col += 2)
|
||||
{
|
||||
if (dataIndex + 1 < rawData.Length)
|
||||
{
|
||||
int highByte = rawData[dataIndex];
|
||||
int lowByte = rawData[dataIndex + 1];
|
||||
float temperature = (highByte * 256 + lowByte) / 10.0f;
|
||||
|
||||
// 应用温度补偿值
|
||||
temperature += compensationValue;
|
||||
|
||||
TemperatureMatrix[row, col] = temperature;
|
||||
dataIndex += 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 计算温度统计信息
|
||||
/// </summary>
|
||||
private void CalculateStatistics()
|
||||
{
|
||||
float sum = 0;
|
||||
float min = float.MaxValue;
|
||||
float max = float.MinValue;
|
||||
int count = 0;
|
||||
|
||||
for (int row = 0; row < Height; row++)
|
||||
{
|
||||
for (int col = 0; col < Width; col++)
|
||||
{
|
||||
float temp = TemperatureMatrix[row, col];
|
||||
sum += temp;
|
||||
min = Math.Min(min, temp);
|
||||
max = Math.Max(max, temp);
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
MinTemperature = min;
|
||||
MaxTemperature = max;
|
||||
AverageTemperature = count > 0 ? sum / count : 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取指定区域内的温度统计信息
|
||||
/// </summary>
|
||||
/// <param name="startRow">起始行</param>
|
||||
/// <param name="startCol">起始列</param>
|
||||
/// <param name="endRow">结束行</param>
|
||||
/// <param name="endCol">结束列</param>
|
||||
/// <returns>区域温度统计信息</returns>
|
||||
public RegionTemperatureStats GetRegionStatistics(int startRow, int startCol, int endRow, int endCol)
|
||||
{
|
||||
// 参数验证和边界检查
|
||||
startRow = Math.Max(0, startRow);
|
||||
startCol = Math.Max(0, startCol);
|
||||
endRow = Math.Min(Height - 1, endRow);
|
||||
endCol = Math.Min(Width - 1, endCol);
|
||||
|
||||
if (startRow > endRow || startCol > endCol)
|
||||
return new RegionTemperatureStats(0, 0, 0, 0);
|
||||
|
||||
float sum = 0;
|
||||
float min = float.MaxValue;
|
||||
float max = float.MinValue;
|
||||
int count = 0;
|
||||
|
||||
for (int row = startRow; row <= endRow; row++)
|
||||
{
|
||||
for (int col = startCol; col <= endCol; col++)
|
||||
{
|
||||
float temp = TemperatureMatrix[row, col];
|
||||
sum += temp;
|
||||
min = Math.Min(min, temp);
|
||||
max = Math.Max(max, temp);
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
float avg = count > 0 ? sum / count : 0;
|
||||
return new RegionTemperatureStats(min, max, avg, count);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 将温度矩阵转换为字节数组(用于保存或传输)
|
||||
/// </summary>
|
||||
/// <returns>温度数据的字节数组表示</returns>
|
||||
public byte[] ToByteArray()
|
||||
{
|
||||
// 创建一个包含所有必要信息的字节数组
|
||||
// 包括宽度、高度、时间戳和温度数据
|
||||
int headerSize = 4 + 4 + 8; // width(4) + height(4) + timestamp(8)
|
||||
int dataSize = Width * Height * 4; // 每个温度值使用4字节float
|
||||
byte[] result = new byte[headerSize + dataSize];
|
||||
|
||||
// 写入头信息
|
||||
Buffer.BlockCopy(BitConverter.GetBytes(Width), 0, result, 0, 4);
|
||||
Buffer.BlockCopy(BitConverter.GetBytes(Height), 0, result, 4, 4);
|
||||
Buffer.BlockCopy(BitConverter.GetBytes(Timestamp.Ticks), 0, result, 8, 8);
|
||||
|
||||
// 写入温度数据
|
||||
int dataIndex = headerSize;
|
||||
for (int row = 0; row < Height; row++)
|
||||
{
|
||||
for (int col = 0; col < Width; col++)
|
||||
{
|
||||
byte[] tempBytes = BitConverter.GetBytes(TemperatureMatrix[row, col]);
|
||||
Buffer.BlockCopy(tempBytes, 0, result, dataIndex, 4);
|
||||
dataIndex += 4;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 从字节数组创建TemperatureData实例
|
||||
/// </summary>
|
||||
/// <param name="data">包含温度数据的字节数组</param>
|
||||
/// <returns>TemperatureData实例</returns>
|
||||
public static TemperatureData FromByteArray(byte[] data)
|
||||
{
|
||||
if (data == null || data.Length < 16) // 至少需要头信息的长度
|
||||
throw new ArgumentException("无效的数据格式");
|
||||
|
||||
int width = BitConverter.ToInt32(data, 0);
|
||||
int height = BitConverter.ToInt32(data, 4);
|
||||
long ticks = BitConverter.ToInt64(data, 8);
|
||||
DateTime timestamp = new DateTime(ticks);
|
||||
|
||||
// 验证数据完整性
|
||||
int expectedSize = 16 + width * height * 4;
|
||||
if (data.Length != expectedSize)
|
||||
throw new ArgumentException("数据长度不匹配");
|
||||
|
||||
// 创建温度矩阵
|
||||
float[,] matrix = new float[height, width];
|
||||
int dataIndex = 16;
|
||||
|
||||
for (int row = 0; row < height; row++)
|
||||
{
|
||||
for (int col = 0; col < width; col++)
|
||||
{
|
||||
matrix[row, col] = BitConverter.ToSingle(data, dataIndex);
|
||||
dataIndex += 4;
|
||||
}
|
||||
}
|
||||
|
||||
// 创建TemperatureData实例
|
||||
TemperatureData tempData = new TemperatureData();
|
||||
tempData.Width = width;
|
||||
tempData.Height = height;
|
||||
tempData.TemperatureMatrix = matrix;
|
||||
tempData.Timestamp = timestamp;
|
||||
tempData.CalculateStatistics();
|
||||
|
||||
return tempData;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 私有构造函数,用于FromByteArray方法
|
||||
/// </summary>
|
||||
private TemperatureData()
|
||||
{ }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 区域温度统计信息
|
||||
/// </summary>
|
||||
public struct RegionTemperatureStats
|
||||
{
|
||||
/// <summary>
|
||||
/// 区域最低温度
|
||||
/// </summary>
|
||||
public float MinTemperature { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 区域最高温度
|
||||
/// </summary>
|
||||
public float MaxTemperature { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 区域平均温度
|
||||
/// </summary>
|
||||
public float AverageTemperature { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 统计的温度点数量
|
||||
/// </summary>
|
||||
public int PointCount { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="minTemp">最低温度</param>
|
||||
/// <param name="maxTemp">最高温度</param>
|
||||
/// <param name="avgTemp">平均温度</param>
|
||||
/// <param name="count">温度点数量</param>
|
||||
public RegionTemperatureStats(float minTemp, float maxTemp, float avgTemp, int count)
|
||||
{
|
||||
MinTemperature = minTemp;
|
||||
MaxTemperature = maxTemp;
|
||||
AverageTemperature = avgTemp;
|
||||
PointCount = count;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user