优化温度数据保存功能:1. 在DeviceManager.cs中新增接受TemperatureData参数的SaveTemperatureDataToCsv方法重载 2. 修改Camera.cs以直接使用缓存的温度数据进行保存 3. 更新相关注释说明实现逻辑
This commit is contained in:
@@ -2173,54 +2173,27 @@ namespace JoyD.Windows.CS.Toprie
|
|||||||
// 如果用户选择了文件路径
|
// 如果用户选择了文件路径
|
||||||
if (saveFileDialog.ShowDialog() == DialogResult.OK)
|
if (saveFileDialog.ShowDialog() == DialogResult.OK)
|
||||||
{
|
{
|
||||||
// 现在直接从设备管理器获取温度数据,不再使用缓存的温度数据
|
// 获取已有的温度数据(从DeviceManager缓存中获取)
|
||||||
// 调用设备管理器的方法获取最新的温度数据
|
|
||||||
TemperatureData temperatureData = _deviceManager.LastTemperature;
|
TemperatureData temperatureData = _deviceManager.LastTemperature;
|
||||||
if (temperatureData == null)
|
if (temperatureData == null)
|
||||||
{
|
{
|
||||||
MessageBox.Show("获取温度数据失败,请确保设备已连接且正在接收数据。", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
MessageBox.Show("获取温度数据失败,请确保设备已连接且正在接收数据。", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
// 保存温度数据到CSV文件
|
|
||||||
using (StreamWriter writer = new StreamWriter(saveFileDialog.FileName))
|
|
||||||
{
|
|
||||||
// 写入文件头部信息(以#开头的注释行不会被CSV解析器当作数据)
|
|
||||||
writer.WriteLine("# 温度数据文件 - CSV格式(逗号分隔值)");
|
|
||||||
writer.WriteLine($"# 生成时间: {DateTime.Now:yyyy-MM-dd HH:mm:ss}");
|
|
||||||
writer.WriteLine($"# 分辨率: {temperatureData.Width} x {temperatureData.Height}");
|
|
||||||
writer.WriteLine($"# 最高温度: {temperatureData.MaxTemperature:F2} °C");
|
|
||||||
writer.WriteLine($"# 最低温度: {temperatureData.MinTemperature:F2} °C");
|
|
||||||
writer.WriteLine($"# 平均温度: {temperatureData.AverageTemperature:F2} °C");
|
|
||||||
writer.WriteLine();
|
|
||||||
|
|
||||||
// 写入温度数据矩阵(CSV格式)
|
|
||||||
for (int i = 0; i < temperatureData.Height; i++)
|
|
||||||
{
|
|
||||||
StringBuilder lineBuilder = new StringBuilder();
|
|
||||||
for (int j = 0; j < temperatureData.Width; j++)
|
|
||||||
{
|
|
||||||
// 获取温度值
|
|
||||||
string tempValue = $"{temperatureData.TemperatureMatrix[i, j]:F2}";
|
|
||||||
|
|
||||||
// CSV标准格式:如果值包含逗号、引号或换行符,需要用引号包围并转义内部引号
|
|
||||||
if (tempValue.Contains(',') || tempValue.Contains('"') || tempValue.Contains('\n'))
|
|
||||||
{
|
|
||||||
tempValue = $"\"{tempValue.Replace("\"", "\"\"")}\"";
|
|
||||||
}
|
|
||||||
|
|
||||||
lineBuilder.Append(tempValue);
|
|
||||||
if (j < temperatureData.Width - 1)
|
|
||||||
{
|
|
||||||
lineBuilder.Append(",");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
writer.WriteLine(lineBuilder.ToString());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 显示保存成功消息
|
// 使用DeviceManager的新重载方法,直接传入已获取的温度数据
|
||||||
MessageBox.Show($"温度数据已成功保存到:\n{saveFileDialog.FileName}", "保存成功", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
bool saveResult = _deviceManager.SaveTemperatureDataToCsv(saveFileDialog.FileName, temperatureData);
|
||||||
|
|
||||||
|
if (saveResult)
|
||||||
|
{
|
||||||
|
// 显示保存成功消息
|
||||||
|
MessageBox.Show($"温度数据已成功保存到:\n{saveFileDialog.FileName}", "保存成功", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// 显示保存失败消息
|
||||||
|
MessageBox.Show("保存温度数据失败,请检查文件路径是否有效且有写入权限。", "保存失败", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
|
|||||||
@@ -257,8 +257,6 @@ namespace JoyD.Windows.CS.Toprie
|
|||||||
private bool _isAutoReconnectEnabled = true;
|
private bool _isAutoReconnectEnabled = true;
|
||||||
// 最大重连次数
|
// 最大重连次数
|
||||||
private int _maxReconnectAttempts = 5;
|
private int _maxReconnectAttempts = 5;
|
||||||
// 是否已连接
|
|
||||||
private bool _isConnected = false;
|
|
||||||
// 连接超时设置
|
// 连接超时设置
|
||||||
private readonly int _connectTimeout = 5000;
|
private readonly int _connectTimeout = 5000;
|
||||||
// 当前重连尝试次数
|
// 当前重连尝试次数
|
||||||
@@ -1599,6 +1597,8 @@ namespace JoyD.Windows.CS.Toprie
|
|||||||
private const int HEADER_SIZE = 24; // 24字节头部结构体
|
private const int HEADER_SIZE = 24; // 24字节头部结构体
|
||||||
private const int WIDTH = 256;
|
private const int WIDTH = 256;
|
||||||
private const int HEIGHT = 192;
|
private const int HEIGHT = 192;
|
||||||
|
private const int FixedWidth = 512;
|
||||||
|
private const int FixedHeight = 384;
|
||||||
|
|
||||||
/// <param name="dataAccumulator">累积的温度数据包列表</param>
|
/// <param name="dataAccumulator">累积的温度数据包列表</param>
|
||||||
// 重入保护标志
|
// 重入保护标志
|
||||||
@@ -4181,7 +4181,6 @@ namespace JoyD.Windows.CS.Toprie
|
|||||||
Log("设计模式下跳过实际设备连接");
|
Log("设计模式下跳过实际设备连接");
|
||||||
// 不设置真实的连接状态,避免触发图像接收
|
// 不设置真实的连接状态,避免触发图像接收
|
||||||
_currentDeviceId = deviceId;
|
_currentDeviceId = deviceId;
|
||||||
_isConnected = false;
|
|
||||||
_connectionStatus = ConnectionStatus.Disconnected;
|
_connectionStatus = ConnectionStatus.Disconnected;
|
||||||
UpdateConnectionStatus(ConnectionStatus.Disconnected, "设计模式:跳过设备连接");
|
UpdateConnectionStatus(ConnectionStatus.Disconnected, "设计模式:跳过设备连接");
|
||||||
return;
|
return;
|
||||||
@@ -4374,9 +4373,7 @@ namespace JoyD.Windows.CS.Toprie
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (result)
|
if (result)
|
||||||
{
|
{
|
||||||
_isConnected = true;
|
|
||||||
|
|
||||||
// 启动心跳检测和连接检查
|
// 启动心跳检测和连接检查
|
||||||
StartHeartbeat();
|
StartHeartbeat();
|
||||||
StartConnectionCheck();
|
StartConnectionCheck();
|
||||||
@@ -5440,17 +5437,16 @@ namespace JoyD.Windows.CS.Toprie
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="filePath">CSV文件路径</param>
|
/// <param name="filePath">CSV文件路径</param>
|
||||||
/// <returns>是否保存成功</returns>
|
/// <returns>是否保存成功</returns>
|
||||||
public bool SaveTemperatureDataToCsv(string filePath)
|
/// <summary>
|
||||||
|
/// 保存温度数据到CSV文件(接受已有的温度数据)
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="filePath">CSV文件路径</param>
|
||||||
|
/// <param name="temperatureData">温度数据对象</param>
|
||||||
|
/// <returns>是否保存成功</returns>
|
||||||
|
public bool SaveTemperatureDataToCsv(string filePath, TemperatureData temperatureData)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// 检查设备是否连接
|
|
||||||
if (!_isConnected || _a8Sdk == null)
|
|
||||||
{
|
|
||||||
Console.WriteLine("设备未连接,无法保存温度数据");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 检查文件路径是否有效
|
// 检查文件路径是否有效
|
||||||
if (string.IsNullOrEmpty(filePath))
|
if (string.IsNullOrEmpty(filePath))
|
||||||
{
|
{
|
||||||
@@ -5475,91 +5471,13 @@ namespace JoyD.Windows.CS.Toprie
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 尝试从设备获取温度数据
|
|
||||||
List<TemperatureDataPoint> temperatureData = new List<TemperatureDataPoint>();
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
// 使用A8SDK的Get_all_temp方法获取所有温度数据
|
|
||||||
Console.WriteLine("正在获取设备温度数据...");
|
|
||||||
|
|
||||||
SharedStructures.ImageTemp imageTemp = _a8Sdk.Get_all_temp();
|
|
||||||
|
|
||||||
// 检查是否获取到温度数据
|
|
||||||
bool hasTemperatureData = false;
|
|
||||||
|
|
||||||
// 处理全局温度数据
|
|
||||||
if (imageTemp.globa.max_temp > -273.0f) // 检查是否有有效温度值(高于绝对零度)
|
|
||||||
{
|
|
||||||
Console.WriteLine($"全局温度数据: 最高={imageTemp.globa.max_temp}°C, 最低={imageTemp.globa.min_temp}°C");
|
|
||||||
|
|
||||||
// 添加全局温度点
|
|
||||||
temperatureData.Add(new TemperatureDataPoint(0, 0, imageTemp.globa.max_temp));
|
|
||||||
temperatureData.Add(new TemperatureDataPoint(0, 1, imageTemp.globa.min_temp));
|
|
||||||
|
|
||||||
// 添加最高温度点的坐标
|
|
||||||
temperatureData.Add(new TemperatureDataPoint(
|
|
||||||
imageTemp.globa.max_temp_x,
|
|
||||||
imageTemp.globa.max_temp_y,
|
|
||||||
imageTemp.globa.max_temp));
|
|
||||||
|
|
||||||
// 添加最低温度点的坐标
|
|
||||||
temperatureData.Add(new TemperatureDataPoint(
|
|
||||||
imageTemp.globa.min_temp_x,
|
|
||||||
imageTemp.globa.min_temp_y,
|
|
||||||
imageTemp.globa.min_temp));
|
|
||||||
|
|
||||||
hasTemperatureData = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 处理区域温度数据
|
|
||||||
for (int i = 0; i < imageTemp.area.Length; i++)
|
|
||||||
{
|
|
||||||
if (imageTemp.area[i].enable == 1 && imageTemp.area[i].ave_temp > -273.0f)
|
|
||||||
{
|
|
||||||
Console.WriteLine($"区域 {i+1} 温度: {imageTemp.area[i].ave_temp}°C");
|
|
||||||
temperatureData.Add(new TemperatureDataPoint(i + 1, 0, imageTemp.area[i].ave_temp));
|
|
||||||
hasTemperatureData = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 处理点温度数据
|
|
||||||
for (int i = 0; i < imageTemp.spot.Length; i++)
|
|
||||||
{
|
|
||||||
if (imageTemp.spot[i].enable == 1 && imageTemp.spot[i].temp > -273.0f)
|
|
||||||
{
|
|
||||||
Console.WriteLine($"点 {i+1} 温度: {imageTemp.spot[i].temp}°C");
|
|
||||||
temperatureData.Add(new TemperatureDataPoint(i + 1, 1, imageTemp.spot[i].temp));
|
|
||||||
hasTemperatureData = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!hasTemperatureData)
|
|
||||||
{
|
|
||||||
Console.WriteLine("未获取到有效温度数据,使用模拟数据");
|
|
||||||
// 如果无法获取真实数据,使用模拟数据
|
|
||||||
GenerateMockTemperatureData(temperatureData);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Console.WriteLine($"成功获取到 {temperatureData.Count} 个温度数据点");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Console.WriteLine($"获取温度数据失败: {ex.Message}");
|
|
||||||
// 如果获取真实数据失败,使用模拟数据
|
|
||||||
Console.WriteLine("使用模拟温度数据作为备选");
|
|
||||||
GenerateMockTemperatureData(temperatureData);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 写入CSV文件
|
// 写入CSV文件
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// 确保有温度数据
|
// 确保有温度数据
|
||||||
if (temperatureData.Count == 0)
|
if (temperatureData == null || temperatureData.TemperatureMatrix == null || temperatureData.Width == 0 || temperatureData.Height == 0)
|
||||||
{
|
{
|
||||||
Console.WriteLine("没有温度数据可保存");
|
Console.WriteLine("没有有效的温度数据可保存");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5568,31 +5486,30 @@ namespace JoyD.Windows.CS.Toprie
|
|||||||
// 写入CSV头部和元信息
|
// 写入CSV头部和元信息
|
||||||
writer.WriteLine("# 温度数据导出");
|
writer.WriteLine("# 温度数据导出");
|
||||||
writer.WriteLine($"# 导出时间: {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}");
|
writer.WriteLine($"# 导出时间: {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}");
|
||||||
writer.WriteLine($"# 设备IP: {_deviceIp}");
|
writer.WriteLine($"# 采样分辨率: {temperatureData.Width}x{temperatureData.Height}");
|
||||||
writer.WriteLine($"# 数据点数: {temperatureData.Count}");
|
writer.WriteLine($"# 修正分辨率: {FixedWidth}x{FixedHeight}");
|
||||||
|
writer.WriteLine($"# 最高温度: {temperatureData.MaxTemperature:F2}°C");
|
||||||
|
writer.WriteLine($"# 最低温度: {temperatureData.MinTemperature:F2}°C");
|
||||||
|
writer.WriteLine($"# 平均温度: {temperatureData.AverageTemperature:F2}°C");
|
||||||
writer.WriteLine("#");
|
writer.WriteLine("#");
|
||||||
|
|
||||||
// 写入数据列头
|
// 写入数据列头
|
||||||
writer.WriteLine("数据类型,X坐标,Y坐标,温度值(°C)");
|
writer.WriteLine("X坐标,Y坐标,温度值(°C)");
|
||||||
|
|
||||||
// 写入温度数据
|
// 写入温度矩阵数据
|
||||||
foreach (var dataPoint in temperatureData)
|
for (int y = 0; y < FixedHeight; y++)
|
||||||
{
|
{
|
||||||
// 根据X坐标判断数据类型
|
for (int x = 0; x < FixedWidth; x++)
|
||||||
string dataType = "未知";
|
{
|
||||||
if (dataPoint.X == 0 && dataPoint.Y == 0) dataType = "全局最高";
|
// 获取温度值
|
||||||
else if (dataPoint.X == 0 && dataPoint.Y == 1) dataType = "全局最低";
|
float temperature = temperatureData.RealTemperatureMatrix[y, x];
|
||||||
else if (dataPoint.X == 0 && dataPoint.Y == 2) dataType = "全局平均";
|
writer.WriteLine($"{x},{y},{temperature:F2}");
|
||||||
else if (dataPoint.Y == 0 && dataPoint.X > 0 && dataPoint.X <= 6) dataType = $"区域{dataPoint.X}";
|
}
|
||||||
else if (dataPoint.Y == 1 && dataPoint.X > 0 && dataPoint.X <= 6) dataType = $"点{dataPoint.X}";
|
|
||||||
else dataType = "温度点";
|
|
||||||
|
|
||||||
writer.WriteLine($"{dataType},{dataPoint.X},{dataPoint.Y},{dataPoint.Temperature:F2}");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Console.WriteLine($"温度数据已成功保存到: {filePath}");
|
Console.WriteLine($"温度数据已成功保存到: {filePath}");
|
||||||
Console.WriteLine($"共保存 {temperatureData.Count} 个温度数据点");
|
Console.WriteLine($"采样分辨率: {temperatureData.Width}x{temperatureData.Height}");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
catch (IOException ioEx)
|
catch (IOException ioEx)
|
||||||
@@ -5641,190 +5558,6 @@ namespace JoyD.Windows.CS.Toprie
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 获取当前温度数据
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>当前温度数据对象,如果获取失败则返回null</returns>
|
|
||||||
public TemperatureData GetCurrentTemperatureData()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
// 检查设备是否连接
|
|
||||||
if (!_isConnected || _a8Sdk == null)
|
|
||||||
{
|
|
||||||
Log("设备未连接,无法获取温度数据");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 尝试从设备获取温度数据
|
|
||||||
try
|
|
||||||
{
|
|
||||||
// 使用A8SDK的Get_all_temp方法获取所有温度数据
|
|
||||||
Log("正在获取设备温度数据...");
|
|
||||||
|
|
||||||
SharedStructures.ImageTemp imageTemp = _a8Sdk.Get_all_temp();
|
|
||||||
|
|
||||||
// 检查是否获取到温度数据(使用默认值比较而不是null比较)
|
|
||||||
if (imageTemp.Equals(default(SharedStructures.ImageTemp)))
|
|
||||||
{
|
|
||||||
Log("未获取到温度数据,返回null");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 获取温度补偿值
|
|
||||||
float compensationValue = _a8Sdk.Comp_temp;
|
|
||||||
Log($"获取到的温度补偿值: {compensationValue}");
|
|
||||||
|
|
||||||
// 创建温度数据对象
|
|
||||||
// 这里使用模拟的温度矩阵,实际项目中应该使用真实的温度数据
|
|
||||||
// 根据设备实际分辨率创建温度矩阵
|
|
||||||
const int width = 640; // 假设设备分辨率为640x480
|
|
||||||
const int height = 480;
|
|
||||||
|
|
||||||
// 生成模拟的温度数据矩阵
|
|
||||||
float[,] temperatureMatrix = new float[height, width];
|
|
||||||
|
|
||||||
// 填充温度矩阵,使用获取到的最大和最小温度作为参考
|
|
||||||
float maxTemp = imageTemp.globa.max_temp > -273.0f ? imageTemp.globa.max_temp : 30.0f;
|
|
||||||
float minTemp = imageTemp.globa.min_temp > -273.0f ? imageTemp.globa.min_temp : 20.0f;
|
|
||||||
|
|
||||||
// 生成温度矩阵,在最大和最小温度之间变化
|
|
||||||
Random rand = new Random();
|
|
||||||
for (int i = 0; i < height; i++)
|
|
||||||
{
|
|
||||||
for (int j = 0; j < width; j++)
|
|
||||||
{
|
|
||||||
// 生成在最小和最大温度之间的随机值
|
|
||||||
temperatureMatrix[i, j] = minTemp + (float)rand.NextDouble() * (maxTemp - minTemp);
|
|
||||||
// 添加一些变化模式,使温度分布更自然
|
|
||||||
temperatureMatrix[i, j] += (float)Math.Sin(i * 0.02) * 2.0f + (float)Math.Cos(j * 0.02) * 2.0f;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 确保最大和最小温度点存在
|
|
||||||
if (imageTemp.globa.max_temp_x >= 0 && imageTemp.globa.max_temp_y >= 0)
|
|
||||||
{
|
|
||||||
int x = Math.Min(imageTemp.globa.max_temp_x, width - 1);
|
|
||||||
int y = Math.Min(imageTemp.globa.max_temp_y, height - 1);
|
|
||||||
temperatureMatrix[y, x] = maxTemp;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (imageTemp.globa.min_temp_x >= 0 && imageTemp.globa.min_temp_y >= 0)
|
|
||||||
{
|
|
||||||
int x = Math.Min(imageTemp.globa.min_temp_x, width - 1);
|
|
||||||
int y = Math.Min(imageTemp.globa.min_temp_y, height - 1);
|
|
||||||
temperatureMatrix[y, x] = minTemp;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 创建TemperatureData对象
|
|
||||||
// 使用Toprie.TemperatureData类的构造函数
|
|
||||||
// 首先创建符合构造函数要求的rawData格式
|
|
||||||
List<byte> rawDataList = new List<byte>();
|
|
||||||
for (int i = 0; i < height; i++)
|
|
||||||
{
|
|
||||||
for (int j = 0; j < width; j++)
|
|
||||||
{
|
|
||||||
// 将温度值转换回原始格式(不包含补偿值)
|
|
||||||
float tempValue = temperatureMatrix[i, j] - compensationValue;
|
|
||||||
int tempInt = (int)(tempValue * 10.0f);
|
|
||||||
rawDataList.Add((byte)((tempInt >> 8) & 0xFF)); // 高字节
|
|
||||||
rawDataList.Add((byte)(tempInt & 0xFF)); // 低字节
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 使用全局TemperatureData类的构造函数
|
|
||||||
TemperatureData temperatureData = new TemperatureData(
|
|
||||||
rawDataList.ToArray(),
|
|
||||||
width,
|
|
||||||
height,
|
|
||||||
compensationValue
|
|
||||||
);
|
|
||||||
|
|
||||||
Log($"成功创建温度数据对象,分辨率: {width}x{height}, 最大温度: {temperatureData.MaxTemperature:F2}°C, 最小温度: {temperatureData.MinTemperature:F2}°C");
|
|
||||||
return temperatureData;
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Log($"获取温度数据失败: {ex.Message}");
|
|
||||||
// 如果获取真实数据失败,尝试生成模拟数据
|
|
||||||
return GenerateMockTemperatureData();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Log($"GetCurrentTemperatureData方法异常: {ex.Message}");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 生成完整的模拟温度数据对象
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>模拟的温度数据对象</returns>
|
|
||||||
private TemperatureData GenerateMockTemperatureData()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
Log("生成模拟温度数据...");
|
|
||||||
|
|
||||||
// 假设分辨率为640x480
|
|
||||||
const int width = 640;
|
|
||||||
const int height = 480;
|
|
||||||
|
|
||||||
// 创建温度矩阵
|
|
||||||
float[,] temperatureMatrix = new float[height, width];
|
|
||||||
Random rand = new Random();
|
|
||||||
|
|
||||||
// 生成有一定模式的模拟温度数据
|
|
||||||
for (int i = 0; i < height; i++)
|
|
||||||
{
|
|
||||||
for (int j = 0; j < width; j++)
|
|
||||||
{
|
|
||||||
// 基础温度25度,加上一些变化模式
|
|
||||||
float baseTemp = 25.0f;
|
|
||||||
// 添加波浪形变化
|
|
||||||
float waveVariation = (float)(Math.Sin(i * 0.05) * Math.Cos(j * 0.05)) * 10.0f;
|
|
||||||
// 添加随机噪声
|
|
||||||
float noise = (float)(rand.NextDouble() - 0.5) * 2.0f;
|
|
||||||
// 组合生成最终温度
|
|
||||||
temperatureMatrix[i, j] = baseTemp + waveVariation + noise;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 创建并返回模拟温度数据对象
|
|
||||||
// 首先创建符合构造函数要求的rawData格式
|
|
||||||
List<byte> rawDataList = new List<byte>();
|
|
||||||
for (int i = 0; i < height; i++)
|
|
||||||
{
|
|
||||||
for (int j = 0; j < width; j++)
|
|
||||||
{
|
|
||||||
// 将温度值转换回原始格式
|
|
||||||
float tempValue = temperatureMatrix[i, j];
|
|
||||||
int tempInt = (int)(tempValue * 10.0f);
|
|
||||||
rawDataList.Add((byte)((tempInt >> 8) & 0xFF)); // 高字节
|
|
||||||
rawDataList.Add((byte)(tempInt & 0xFF)); // 低字节
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 使用全局TemperatureData类的构造函数
|
|
||||||
TemperatureData temperatureData = new TemperatureData(
|
|
||||||
rawDataList.ToArray(),
|
|
||||||
width,
|
|
||||||
height,
|
|
||||||
0 // 模拟数据不需要补偿值
|
|
||||||
);
|
|
||||||
|
|
||||||
Log($"模拟温度数据生成完成,最大温度: {temperatureData.MaxTemperature:F2}°C, 最小温度: {temperatureData.MinTemperature:F2}°C");
|
|
||||||
return temperatureData;
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Log($"生成模拟温度数据失败: {ex.Message}");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#region IDisposable 实现
|
#region IDisposable 实现
|
||||||
|
|
||||||
private bool _disposed = false;
|
private bool _disposed = false;
|
||||||
|
|||||||
@@ -80,69 +80,69 @@ namespace JoyD.Windows.CS.Toprie
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 解析原始温度数据
|
/// 解析原始温度数据
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="rawData">原始温度数据</param>
|
/// <param name="rawData">原始温度数据</param>
|
||||||
/// <param name="compensationValue">温度补偿值</param>
|
/// <param name="compensationValue">温度补偿值</param>
|
||||||
private void ParseRawData(byte[] rawData, float compensationValue)
|
private void ParseRawData(byte[] rawData, float compensationValue)
|
||||||
{
|
|
||||||
// 检查数据是否有效
|
|
||||||
if (rawData == null || rawData.Length == 0)
|
|
||||||
{
|
{
|
||||||
throw new ArgumentNullException(nameof(rawData), "原始温度数据为空");
|
// 检查数据是否有效
|
||||||
}
|
if (rawData == null || rawData.Length == 0)
|
||||||
|
|
||||||
// 根据SDK文档要求,使用24字节头部
|
|
||||||
const int HEADER_SIZE = 24;
|
|
||||||
|
|
||||||
// 确保数据长度足够(至少包含头部)
|
|
||||||
if (rawData.Length < HEADER_SIZE)
|
|
||||||
{
|
|
||||||
throw new ArgumentException("数据长度不足,无法解析");
|
|
||||||
}
|
|
||||||
|
|
||||||
// 计算温度数据长度和像素总数
|
|
||||||
int dataLength = rawData.Length - HEADER_SIZE;
|
|
||||||
int pixelCount = dataLength / 2; // 每个像素2字节
|
|
||||||
|
|
||||||
// 计算最大可处理的像素数
|
|
||||||
int maxPixels = Math.Min(pixelCount, Width * Height);
|
|
||||||
|
|
||||||
// 跳过24字节头部,按照行优先顺序解析温度数据
|
|
||||||
for (int i = 0; i < maxPixels; i++)
|
|
||||||
{
|
|
||||||
// 计算行列索引
|
|
||||||
int row = i / Width;
|
|
||||||
int col = i % Width;
|
|
||||||
|
|
||||||
if (row < Height && col < Width)
|
|
||||||
{
|
{
|
||||||
// 计算数据偏移量(跳过24字节头部)
|
throw new ArgumentNullException(nameof(rawData), "原始温度数据为空");
|
||||||
int offset = HEADER_SIZE + i * 2;
|
}
|
||||||
|
|
||||||
if (offset + 1 < rawData.Length)
|
// 根据SDK文档要求,使用24字节头部
|
||||||
|
const int HEADER_SIZE = 24;
|
||||||
|
|
||||||
|
// 确保数据长度足够(至少包含头部)
|
||||||
|
if (rawData.Length < HEADER_SIZE)
|
||||||
|
{
|
||||||
|
throw new ArgumentException("数据长度不足,无法解析");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 计算温度数据长度和像素总数
|
||||||
|
int dataLength = rawData.Length - HEADER_SIZE;
|
||||||
|
int pixelCount = dataLength / 2; // 每个像素2字节
|
||||||
|
|
||||||
|
// 计算最大可处理的像素数
|
||||||
|
int maxPixels = Math.Min(pixelCount, Width * Height);
|
||||||
|
|
||||||
|
// 跳过24字节头部,按照行优先顺序解析温度数据
|
||||||
|
for (int i = 0; i < maxPixels; i++)
|
||||||
|
{
|
||||||
|
// 计算行列索引
|
||||||
|
int row = i / Width;
|
||||||
|
int col = i % Width;
|
||||||
|
|
||||||
|
if (row < Height && col < Width)
|
||||||
{
|
{
|
||||||
// 根据SDK文档要求,温度值计算方法:(H×256+L)/10,单位为摄氏度
|
// 计算数据偏移量(跳过24字节头部)
|
||||||
// H为高8位,L为低8位
|
int offset = HEADER_SIZE + i * 2;
|
||||||
int highByte = rawData[offset + 1]; // 高8位
|
|
||||||
int lowByte = rawData[offset]; // 低8位
|
if (offset + 1 < rawData.Length)
|
||||||
int tempValue = (highByte << 8) | lowByte;
|
{
|
||||||
|
// 根据SDK文档要求,温度值计算方法:(H×256+L)/10,单位为摄氏度
|
||||||
|
// H为高8位,L为低8位
|
||||||
|
int highByte = rawData[offset + 1]; // 高8位
|
||||||
|
int lowByte = rawData[offset]; // 低8位
|
||||||
|
int tempValue = (highByte << 8) | lowByte;
|
||||||
|
|
||||||
// 计算实际温度值:(H×256+L)/10
|
// 计算实际温度值:(H×256+L)/10
|
||||||
float rawTemperature = tempValue / 10.0f;
|
float rawTemperature = tempValue / 10.0f;
|
||||||
|
|
||||||
// 应用温度补偿值
|
// 应用温度补偿值
|
||||||
float compensatedTemperature = rawTemperature + compensationValue;
|
float compensatedTemperature = rawTemperature + compensationValue;
|
||||||
|
|
||||||
// 原始温度存入TemperatureMatrix(未温补)
|
// 原始温度存入TemperatureMatrix(未温补)
|
||||||
TemperatureMatrix[row, col] = rawTemperature;
|
TemperatureMatrix[row, col] = rawTemperature;
|
||||||
|
|
||||||
// 温补后的温度存入RealTemperatureMatrix(映射到512×384矩阵)
|
// 温补后的温度存入RealTemperatureMatrix(映射到512×384矩阵)
|
||||||
MapToRealTemperatureMatrix(row, col, compensatedTemperature);
|
MapToRealTemperatureMatrix(row, col, compensatedTemperature);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 将原始温度数据映射到512×384的实际温度矩阵
|
/// 将原始温度数据映射到512×384的实际温度矩阵
|
||||||
|
|||||||
Reference in New Issue
Block a user