实现温度数据处理功能:添加温度数据模型类、温度接收功能和相关集成

This commit is contained in:
zqm
2025-10-30 16:46:57 +08:00
parent 4ab2ddf1f3
commit 3501e9c952
5 changed files with 1112 additions and 0 deletions

View 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;
}
}
}