diff --git a/Windows/CS/Framework4.0/Toprie/Toprie.sln b/Windows/CS/Framework4.0/Toprie/Toprie.sln index 6ae5176..b09abf1 100644 --- a/Windows/CS/Framework4.0/Toprie/Toprie.sln +++ b/Windows/CS/Framework4.0/Toprie/Toprie.sln @@ -7,6 +7,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Toprie", "Toprie\Toprie.csp EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test", "Test\Test.csproj", "{C309F3A2-0E77-42E4-BE3D-1448E7DFA433}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "testDevice", "testDevice\testDevice.csproj", "{D1B84CE9-5103-41BD-AF95-2DA4CBA00EB0}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -21,6 +23,10 @@ Global {C309F3A2-0E77-42E4-BE3D-1448E7DFA433}.Debug|Any CPU.Build.0 = Debug|Any CPU {C309F3A2-0E77-42E4-BE3D-1448E7DFA433}.Release|Any CPU.ActiveCfg = Release|Any CPU {C309F3A2-0E77-42E4-BE3D-1448E7DFA433}.Release|Any CPU.Build.0 = Release|Any CPU + {D1B84CE9-5103-41BD-AF95-2DA4CBA00EB0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D1B84CE9-5103-41BD-AF95-2DA4CBA00EB0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D1B84CE9-5103-41BD-AF95-2DA4CBA00EB0}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D1B84CE9-5103-41BD-AF95-2DA4CBA00EB0}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs b/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs index 22904dc..ba3085c 100644 --- a/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs +++ b/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs @@ -14,6 +14,30 @@ namespace JoyD.Windows.CS.Toprie { public partial class Camera : UserControl { + // 测温区配置类 + private class TemperatureZone + { + public int Index { get; set; } + public int X { get; set; } + public int Y { get; set; } + public int Width { get; set; } + public int Height { get; set; } + public Color Color { get; set; } + } + + // 温差配置类 + private class TemperatureDiffConfig + { + public List> TemperatureLegend { get; set; } + public Dictionary PixelTemperatureData { get; set; } + + public TemperatureDiffConfig() + { + TemperatureLegend = new List>(); + PixelTemperatureData = new Dictionary(); + } + } + // 设备管理器实例 private DeviceManager _deviceManager; @@ -62,6 +86,12 @@ namespace JoyD.Windows.CS.Toprie // 项目路径,用于数据文件的存取 private string _projectPath = ""; + // 加载的测温区配置 + private List _loadedTemperatureZones = new List(); + + // 加载的温差配置 + private TemperatureDiffConfig _loadedTemperatureDiffConfig = new TemperatureDiffConfig(); + /// /// 获取或设置项目路径,控件所需的数据文件将在此目录中进行存取 /// @@ -82,10 +112,181 @@ namespace JoyD.Windows.CS.Toprie { _deviceManager.ProjectPath = _projectPath; } + // 加载配置文件 + LoadAllConfigs(); } } } + /// + /// 加载测温区配置文件 + /// + private void LoadZoneConfig() + { + try + { + if (string.IsNullOrEmpty(_projectPath)) + return; + + string configPath = Path.Combine(_projectPath, "测温区信息.csv"); + if (!File.Exists(configPath)) + return; + + // 清空已加载的测温区 + _loadedTemperatureZones.Clear(); + + // 读取CSV文件 + using (StreamReader reader = new StreamReader(configPath, Encoding.UTF8)) + { + // 跳过标题行 + reader.ReadLine(); + + // 读取数据行 + string line; + while ((line = reader.ReadLine()) != null) + { + if (string.IsNullOrWhiteSpace(line)) + continue; + + string[] parts = line.Split(','); + if (parts.Length < 6) + continue; + + try + { + TemperatureZone zone = new TemperatureZone + { + Index = int.Parse(parts[0]), + X = int.Parse(parts[1]), + Y = int.Parse(parts[2]), + Width = int.Parse(parts[3]), + Height = int.Parse(parts[4]) + }; + + // 解析颜色(支持HTML格式和十六进制格式) + zone.Color = ColorTranslator.FromHtml(parts[5]); + + _loadedTemperatureZones.Add(zone); + } + catch (Exception ex) + { + Console.WriteLine($"解析测温区配置行失败: {line}, 错误: {ex.Message}"); + } + } + } + + Console.WriteLine($"成功加载 {_loadedTemperatureZones.Count} 个测温区配置"); + } + catch (Exception ex) + { + Console.WriteLine($"加载测温区配置文件失败: {ex.Message}"); + } + } + + /// + /// 加载温差配置文件 + /// + private void LoadTemperatureDiffConfig() + { + try + { + if (string.IsNullOrEmpty(_projectPath)) + return; + + string configPath = Path.Combine(_projectPath, "温差数据.csv"); + if (!File.Exists(configPath)) + return; + + // 创建新的温差配置实例 + TemperatureDiffConfig config = new TemperatureDiffConfig(); + + // 读取CSV文件 + using (StreamReader reader = new StreamReader(configPath, Encoding.UTF8)) + { + string line; + bool readingLegend = false; + bool readingPixelData = false; + + while ((line = reader.ReadLine()) != null) + { + if (string.IsNullOrWhiteSpace(line)) + continue; + + // 检查部分标题 + if (line == "温差图例信息") + { + readingLegend = true; + readingPixelData = false; + reader.ReadLine(); // 跳过温度图例的标题行 + continue; + } + else if (line == "像素温度数据") + { + readingLegend = false; + readingPixelData = true; + reader.ReadLine(); // 跳过像素温度数据的标题行 + continue; + } + + if (readingLegend) + { + // 解析温差图例数据 + string[] parts = line.Split(','); + if (parts.Length >= 2) + { + try + { + double temperature = double.Parse(parts[0]); + Color color = ColorTranslator.FromHtml(parts[1]); + config.TemperatureLegend.Add(new Tuple(temperature, color)); + } + catch (Exception ex) + { + Console.WriteLine($"解析温差图例数据失败: {line}, 错误: {ex.Message}"); + } + } + } + else if (readingPixelData) + { + // 解析像素温度数据 + string[] parts = line.Split(','); + if (parts.Length >= 3) + { + try + { + int x = int.Parse(parts[0]); + int y = int.Parse(parts[1]); + double temperature = double.Parse(parts[2]); + config.PixelTemperatureData[new Point(x, y)] = temperature; + } + catch (Exception ex) + { + Console.WriteLine($"解析像素温度数据失败: {line}, 错误: {ex.Message}"); + } + } + } + } + } + + // 更新加载的温差配置 + _loadedTemperatureDiffConfig = config; + Console.WriteLine($"成功加载温差配置,包含 {_loadedTemperatureDiffConfig.TemperatureLegend.Count} 个图例项和 {_loadedTemperatureDiffConfig.PixelTemperatureData.Count} 个像素温度数据"); + } + catch (Exception ex) + { + Console.WriteLine($"加载温差配置文件失败: {ex.Message}"); + } + } + + /// + /// 加载所有配置文件 + /// + private void LoadAllConfigs() + { + LoadZoneConfig(); + LoadTemperatureDiffConfig(); + } + /// /// 更新设计模式状态到DeviceManager /// @@ -841,10 +1042,10 @@ namespace JoyD.Windows.CS.Toprie } } - if (lastImage != null) - { - Console.WriteLine($"图像更新成功: {lastImage.Width}x{lastImage.Height}"); - } + //if (lastImage != null) + //{ + // Console.WriteLine($"图像更新成功: {lastImage.Width}x{lastImage.Height}"); + //} } catch (ArgumentException ex) when (ex.Message.Contains("参数无效")) { diff --git a/Windows/CS/Framework4.0/Toprie/Toprie/DeviceManager.cs b/Windows/CS/Framework4.0/Toprie/Toprie/DeviceManager.cs index 8bdb95e..c556f37 100644 --- a/Windows/CS/Framework4.0/Toprie/Toprie/DeviceManager.cs +++ b/Windows/CS/Framework4.0/Toprie/Toprie/DeviceManager.cs @@ -168,6 +168,30 @@ namespace JoyD.Windows.CS.Toprie } } + // 测温区配置类 + public class TemperatureZone + { + public int Index { get; set; } + public int X { get; set; } + public int Y { get; set; } + public int Width { get; set; } + public int Height { get; set; } + public Color Color { get; set; } + } + + // 温差配置类 + public class TemperatureDiffConfig + { + public List> TemperatureLegend { get; set; } + public Dictionary PixelTemperatureData { get; set; } + + public TemperatureDiffConfig() + { + TemperatureLegend = new List>(); + PixelTemperatureData = new Dictionary(); + } + } + public class DeviceManager : IDisposable { // 设计模式标志,用于在设计模式下跳过实际的设备连接和初始化 @@ -199,6 +223,12 @@ namespace JoyD.Windows.CS.Toprie // 设备端口 private int _devicePort = 8080; + // 加载的测温区配置 + private List _loadedTemperatureZones = new List(); + + // 加载的温差配置 + private TemperatureDiffConfig _loadedTemperatureDiffConfig = new TemperatureDiffConfig(); + // 温度数据处理相关 private volatile byte[] _lastTemperatureFrame; // 存储最后一帧温度数据 private Thread _temperatureProcessingThread; // 温度数据处理线程 @@ -319,7 +349,154 @@ namespace JoyD.Windows.CS.Toprie public string ProjectPath { get { return _projectPath; } - set { _projectPath = value; } + set + { + _projectPath = value; + // 加载所有配置文件 + LoadAllConfigs(); + } + } + + /// + /// 加载所有配置文件 + /// + private void LoadAllConfigs() + { + LoadZoneConfig(); + LoadTemperatureDiffConfig(); + } + + /// + /// 加载测温区配置 + /// + private void LoadZoneConfig() + { + try + { + if (string.IsNullOrEmpty(_projectPath)) + return; + + string configPath = Path.Combine(_projectPath, "Config", "测温区信息.csv"); + if (!File.Exists(configPath)) + return; + + // 清空已加载的测温区 + _loadedTemperatureZones.Clear(); + + // 读取CSV文件 + using (StreamReader reader = new StreamReader(configPath, Encoding.UTF8)) + { + // 跳过标题行 + reader.ReadLine(); + + // 读取数据行 + string line; + while ((line = reader.ReadLine()) != null) + { + if (string.IsNullOrWhiteSpace(line)) + continue; + + string[] parts = line.Split(','); + if (parts.Length < 6) + continue; + + try + { + TemperatureZone zone = new TemperatureZone + { + Index = int.Parse(parts[0]), + X = int.Parse(parts[1]), + Y = int.Parse(parts[2]), + Width = int.Parse(parts[3]), + Height = int.Parse(parts[4]) + }; + + // 解析颜色(支持HTML格式和十六进制格式) + zone.Color = ColorTranslator.FromHtml(parts[5]); + + _loadedTemperatureZones.Add(zone); + } + catch (Exception ex) + { + Console.WriteLine($"解析测温区配置行失败: {line}, 错误: {ex.Message}"); + } + } + } + + Console.WriteLine($"成功加载 {_loadedTemperatureZones.Count} 个测温区配置"); + } + catch (Exception ex) + { + Console.WriteLine($"加载测温区配置文件失败: {ex.Message}"); + } + } + + /// + /// 加载温差配置 + /// + private void LoadTemperatureDiffConfig() + { + try + { + if (string.IsNullOrEmpty(_projectPath)) + return; + + string configPath = Path.Combine(_projectPath, "Config", "温差数据.csv"); + if (!File.Exists(configPath)) + return; + + // 清空已加载的温差配置 + _loadedTemperatureDiffConfig = new TemperatureDiffConfig(); + + // 读取CSV文件 + using (StreamReader reader = new StreamReader(configPath, Encoding.UTF8)) + { + // 跳过标题行 + reader.ReadLine(); + + // 读取数据行 + string line; + while ((line = reader.ReadLine()) != null) + { + if (string.IsNullOrWhiteSpace(line)) + continue; + + string[] parts = line.Split(','); + if (parts.Length < 4) + continue; + + try + { + Point pixel = new Point + { + X = int.Parse(parts[0]), + Y = int.Parse(parts[1]) + }; + double temperature = double.Parse(parts[2]); + Color color = ColorTranslator.FromHtml(parts[3]); + + // 添加到像素温度数据 + _loadedTemperatureDiffConfig.PixelTemperatureData[pixel] = temperature; + + // 如果温度图例中没有相同的温度值,则添加到图例 + if (!_loadedTemperatureDiffConfig.TemperatureLegend.Any(t => t.Item1 == temperature)) + { + _loadedTemperatureDiffConfig.TemperatureLegend.Add(new Tuple(temperature, color)); + } + } + catch (Exception ex) + { + Console.WriteLine($"解析温差配置行失败: {line}, 错误: {ex.Message}"); + } + } + } + + Console.WriteLine($"成功加载 {_loadedTemperatureDiffConfig.PixelTemperatureData.Count} 个温差配置数据点"); + } + catch (Exception ex) + { + Console.WriteLine($"加载温差配置文件失败: {ex.Message}"); + } } /// @@ -1272,7 +1449,7 @@ namespace JoyD.Windows.CS.Toprie // 定义常量 const int RECEIVE_TIMEOUT = 30000; // 30秒超时 const int SLEEP_MS = 1000; // 标准等待时间 - const int CONNECTION_CHECK_INTERVAL_MS = 5000; // 连接检查间隔5秒 + const int CONNECTION_CHECK_INTERVAL_MS = 15000; // 连接检查间隔5秒 const int LONG_SLEEP_MS = 5000; // 长等待时间 const int ERROR_SLEEP_MS = 3000; // 错误后等待时间 @@ -1829,6 +2006,9 @@ namespace JoyD.Windows.CS.Toprie TemperatureData temperatureData = new TemperatureData(frameData, width, height, compensationValue); Log($"温度数据对象创建成功,分辨率: {width}x{height}"); + // 进行温度比较 + CompareTemperatureData(temperatureData); + LastTemperature = temperatureData; Log($"温度数据处理完成,不再触发事件通知"); } @@ -1838,6 +2018,117 @@ namespace JoyD.Windows.CS.Toprie } } + /// + /// 比较温度数据 + /// + /// 温度数据对象 + private void CompareTemperatureData(TemperatureData temperatureData) + { + try + { + // 处理测温区温度数据 + if (_loadedTemperatureZones.Count > 0) + { + ProcessZoneTemperatures(temperatureData); + } + + // 处理温差数据 + if (_loadedTemperatureDiffConfig.PixelTemperatureData.Count > 0) + { + ProcessTemperatureDiffs(temperatureData); + } + } + catch (Exception ex) + { + Log($"比较温度数据时出错: {ex.Message}"); + } + } + + /// + /// 处理测温区温度数据 + /// + /// 温度数据对象 + private void ProcessZoneTemperatures(TemperatureData temperatureData) + { + foreach (var zone in _loadedTemperatureZones) + { + try + { + float minTemp = float.MaxValue; + float maxTemp = float.MinValue; + float sumTemp = 0; + int count = 0; + + // 计算测温区内的温度统计数据 + for (int y = zone.Y; y < zone.Y + zone.Height && y < temperatureData.RealTemperatureMatrix.GetLength(0); y++) + { + for (int x = zone.X; x < zone.X + zone.Width && x < temperatureData.RealTemperatureMatrix.GetLength(1); x++) + { + float temp = temperatureData.RealTemperatureMatrix[y, x]; + if (temp < minTemp) + minTemp = temp; + if (temp > maxTemp) + maxTemp = temp; + sumTemp += temp; + count++; + } + } + + if (count > 0) + { + // 创建测温区温度数据对象 + var zoneTempData = new TemperatureData.ZoneTemperatureData + { + MinTemperature = minTemp, + MaxTemperature = maxTemp, + AverageTemperature = sumTemp / count + }; + + // 添加到温度数据对象中 + temperatureData.ZoneTemperatures[zone.Index] = zoneTempData; + } + } + catch (Exception ex) + { + Log($"处理测温区 {zone.Index} 温度数据时出错: {ex.Message}"); + } + } + } + + /// + /// 处理温差数据 + /// + /// 温度数据对象 + private void ProcessTemperatureDiffs(TemperatureData temperatureData) + { + foreach (var pixelTemp in _loadedTemperatureDiffConfig.PixelTemperatureData) + { + try + { + Point pixel = pixelTemp.Key; + double configTemp = pixelTemp.Value; + + // 检查像素点是否在温度矩阵范围内 + if (pixel.Y >= 0 && pixel.Y < temperatureData.RealTemperatureMatrix.GetLength(0) && + pixel.X >= 0 && pixel.X < temperatureData.RealTemperatureMatrix.GetLength(1)) + { + // 获取当前温度 + float currentTemp = temperatureData.RealTemperatureMatrix[pixel.Y, pixel.X]; + + // 计算温差 + float diff = currentTemp - (float)configTemp; + + // 添加到温度数据对象中 + temperatureData.TemperatureDiffs[pixel] = diff; + } + } + catch (Exception ex) + { + Log($"处理像素点 ({pixelTemp.Key.X}, {pixelTemp.Key.Y}) 温差数据时出错: {ex.Message}"); + } + } + } + /// /// 检查是否为有效的头部标记 /// diff --git a/Windows/CS/Framework4.0/Toprie/Toprie/TemperatureData.cs b/Windows/CS/Framework4.0/Toprie/Toprie/TemperatureData.cs index 5fa135f..be57fbd 100644 --- a/Windows/CS/Framework4.0/Toprie/Toprie/TemperatureData.cs +++ b/Windows/CS/Framework4.0/Toprie/Toprie/TemperatureData.cs @@ -4,6 +4,7 @@ using System.Collections.Concurrent; using System.Linq; using System.Text; using System.Threading.Tasks; +using System.Drawing; namespace JoyD.Windows.CS.Toprie { @@ -60,6 +61,26 @@ namespace JoyD.Windows.CS.Toprie /// 平均温度值 /// public float AverageTemperature { get; private set; } + + /// + /// 测温区温度数据(键:测温区索引,值:该区域的温度数据) + /// + public Dictionary ZoneTemperatures { get; private set; } + + /// + /// 温差数据(键:像素点坐标,值:温差值) + /// + public Dictionary TemperatureDiffs { get; private set; } + + /// + /// 测温区温度数据类 + /// + public class ZoneTemperatureData + { + public float MinTemperature { get; set; } + public float MaxTemperature { get; set; } + public float AverageTemperature { get; set; } + } /// /// 根据原始数据创建温度数据实例 @@ -82,6 +103,9 @@ namespace JoyD.Windows.CS.Toprie // 创建512×384的实际温度矩阵 RealTemperatureMatrix = new float[384, 512]; Timestamp = DateTime.Now; + // 初始化测温区温度数据和温差数据 + ZoneTemperatures = new Dictionary(); + TemperatureDiffs = new Dictionary(); String key = $"{width}_{height}"; ConcurrentDictionary> map = _temperatureMap.GetOrAdd(key, new ConcurrentDictionary>()); if (map.IsEmpty)