将todolist.md重命名为TodoList.md以保持大小写一致
This commit is contained in:
220
Windows/CS/Framework4.0/Toprie/Toprie/TodoList.md
Normal file
220
Windows/CS/Framework4.0/Toprie/Toprie/TodoList.md
Normal file
@@ -0,0 +1,220 @@
|
||||
# JoyD
|
||||
|
||||
## 图像处理相关
|
||||
|
||||
### InfoImage, ImageBuffer, 图像框的bitmap, LastImage, DisplayImage
|
||||
1. 初始化时,都创建成512x384的透明bitmap
|
||||
2. 中途不进行Dispose和设置为null,只在上面进行绘制
|
||||
3. 仅当控件被Dispose时,才进行Dispose和设置为null
|
||||
|
||||
## 操作流程
|
||||
|
||||
### 修改流程
|
||||
1. 暂停或恢复时,设置暂停状态,调用更新Info
|
||||
2. 断开或连接时,设置连接状态,调用更新Info
|
||||
3. Ping通状态变化时,修改Ping状态,调用更新Info
|
||||
4. 图像更新时,保存LastImage,调用更新UI
|
||||
5. 2-4 只在非暂停状态下调用更新,暂停状态下不更新Info和UI
|
||||
6. 数据显示菜单勾选变化时,只在非暂停状态下调用更新实时信息
|
||||
|
||||
### 更新Info
|
||||
1. 以透明色清空Info
|
||||
2. 如果暂停,显示暂停信息,否则如果Ping不通或断开,显示重连信息,否则就绪
|
||||
3. 如果未就绪,调用更新UI
|
||||
|
||||
### 更新UI
|
||||
1. 先将LastImage绘制到全局缓冲
|
||||
2. 再将InfoImage绘制到缓冲
|
||||
3. 在就绪条件下,调用更新实时信息,并将DisplayImage绘制到缓冲
|
||||
4. 最后一次性绘制到图像框的bitmap
|
||||
5. 同步更新检测配置窗口的实时图像属性
|
||||
|
||||
### 更新实时信息
|
||||
1. 以透明色清空DisplayImage
|
||||
2. 如果没有温度数据或温度数据的时间3秒之前,返回
|
||||
3. 温度显示菜单下如果未勾选区域温度和全局温度,则不显示任何温度信息
|
||||
4. 如果勾选了全局温度,则显示全局温度(居中显示),否则显示区域温度(居中显示)
|
||||
5. 如果勾选了区域温度,则显示区域框,否则不显示区域框
|
||||
6. 如果勾选了平均温度,显示平均温度(居中显示)
|
||||
7. 如果勾选了最低温度,显示最低温度(居中显示)
|
||||
8. 如果勾选了最高温度,显示最高温度(居中显示)
|
||||
9. 如果是全局温度时,最低温度和最高温度、平均温度,显示三行(左对齐),整体水平和垂直相对于图像框居中显示
|
||||
10. 如果是区域温度时,最低温度和最高温度、平均温度,显示三行(左对齐),整体水平和垂直相对于区域框居中显示
|
||||
|
||||
## TCP温度数据接收
|
||||
|
||||
1. 系统初始化时,创建后台线程
|
||||
2. 然后线程循环执行
|
||||
3. 判断是否存在tcp连接实例
|
||||
4. 如果不存在连接实例,则判断是否暂停。如果暂停,则Sleep 1秒后继续执行。否则创建一个新的连接实例。
|
||||
5. 如果存在连接实例,则判断是否连接。如果未连接,则重新连接
|
||||
6. 同步接收和处理数据
|
||||
7. 收到数据后,如果暂停,接收后丢弃,Sleep 1秒。否则同步将收到的数组复制放到待处理列表(线程安全列表)。
|
||||
8. 通知处理线程,有新数据到达
|
||||
9. 跳转到6
|
||||
10. Dispose时,关闭后台线程
|
||||
|
||||
### 温度数据接收时的补充说明
|
||||
|
||||
总之就是不主动断开连接:
|
||||
|
||||
1. 同步机制简单,不用考虑阻塞,因为在后台线程里
|
||||
2. 不用心跳机制,协议约定是每秒1帧数据
|
||||
3. 异常情况处理,出现异常就跳转到第3步
|
||||
4. 不用考虑波动问题,这是在一个循环中,它会下次重试
|
||||
5. 在异常出现且需要重新创建对象前,先释放旧的资源
|
||||
6. 数据完整性验证放在了数据处理环节
|
||||
7. 连接失败,会跳转到第3步。下一循环会自动重试
|
||||
|
||||
### 温度数据处理逻辑
|
||||
|
||||
1. 收到的数组放到待处理列表中
|
||||
2. 开始循环处理列表
|
||||
3. 如果列表为空,退出循环
|
||||
4. 从列表中读取第一个数组,查看是否有头信息
|
||||
5. 如果没有头信息,将数组从列表中移除,跳转到3
|
||||
6. 如果有头信息,查看头信息中数据长度信息
|
||||
7. 检查数组中是否有足够的数据长度
|
||||
8. 如果没有足够的数据长度,看列表中是否有下一个数组
|
||||
9. 如果没有,则退出循环,否则将下一个数组合并到当前数组中尾部,将下一个数组从列表中移除,然后跳转到7
|
||||
10. 如果有足够的数据长度,则检查数据长度范围内是否又出现了头信息
|
||||
11. 如果有,则将数组中第二个头信息之前的数据移除,然后跳转到6
|
||||
12. 如果没有,则将数据长度范围内的数据从数组取出进行解析处理,剩余部分保留到数组中,跳转到4
|
||||
13. 处理完毕后,跳转到3
|
||||
14. 循环完成,进入等待状态
|
||||
|
||||
### 温度数据解析处理逻辑
|
||||
|
||||
根据热像仪SDK文档,原始温度数据的解析处理需遵循以下逻辑:
|
||||
|
||||
#### 原始温度数据格式说明
|
||||
- 通过TCP端口8081获取温度数据
|
||||
- 数据包含24字节头部和温度数据两部分
|
||||
- 头部结构体(header)包含:
|
||||
- mark[5]: 固定标识"+TEMP"
|
||||
- payload_length: 温度数据长度
|
||||
- timestamp: 时间戳(前4字节为秒级时间,后2字节为毫秒级时间)
|
||||
- 温度数据长度计算:宽×高×2字节,例如240×180分辨率时为240×180×2字节
|
||||
- 数据按字节低位在前读取,如读取为80 51 01 00时实际值为00 01 51 80的16进制值
|
||||
|
||||
#### 原始温度数据解析方法
|
||||
1. **单像素温度计算**:
|
||||
- 每个像素点温度由两个字节组成(L为低8位,H为高8位)
|
||||
- 公式:摄氏温度×10 = H×256 + L
|
||||
- 实际温度:摄氏温度 = (H×256 + L)/10
|
||||
|
||||
2. **温度数据布局**:
|
||||
- 数据按行优先顺序排列
|
||||
- 例如分辨率为4×3时,数据顺序为:L1 H1 L2 H2 L3 H3 L4 H4 L5 H5 ...
|
||||
|
||||
#### 温补值处理
|
||||
1. **温补值获取**:
|
||||
- 通过SDK函数`sdk_get_comp_temp`获取温补值
|
||||
- 函数原型:`sdk_get_comp_temp(const char* ip, int* comp_temp)`
|
||||
- 返回值为0表示获取成功
|
||||
|
||||
2. **温补值应用**:
|
||||
- 温补值也是摄氏度乘以10的结果
|
||||
- 最终温度计算公式:
|
||||
```
|
||||
最终温度 = 原始温度 + 温补值
|
||||
```
|
||||
- 示例:原始温度为243(24.3°C),温补值为5(0.5°C),则最终温度为248(24.8°C)
|
||||
|
||||
#### 温度数据解析处理流程
|
||||
1. 接收TCP数据并解析头部信息
|
||||
2. 验证mark标识是否为"+TEMP"
|
||||
3. 根据payload_length确定温度数据长度
|
||||
4. 按像素点顺序解析每个像素的温度值
|
||||
5. 获取温补值并应用到每个像素的温度上
|
||||
6. 计算得到最终的温度数据
|
||||
|
||||
#### 注意事项
|
||||
1. 时间戳转换时需注意低字节在前、高字节在后的顺序
|
||||
2. 温补值是设备补偿值,必须应用到原始温度上才能得到与网页计算结果一致的温度
|
||||
3. 分辨率不同时,温度数据长度会相应变化,解析时需根据实际分辨率计算
|
||||
4. 原始温度数据更新频率约为每秒一条
|
||||
|
||||
### 温度显示菜单
|
||||
1. 在右键菜单中增加温度显示菜单
|
||||
2. 温度显示菜单下显示全局温度(可勾选)
|
||||
3. 温度显示菜单下显示区域温度(可勾选)
|
||||
4. 区域温度和全局温度只能二选一显示
|
||||
5. 温度显示菜单下显示最高温度、平均温度和最低温度(可勾选)
|
||||
|
||||
### 检测配置
|
||||
#### 区域绘制逻辑
|
||||
1. 创建独立的叠加层图像 :专门维护一个与显示图像同尺寸的Image对象作为矩形框的叠加层
|
||||
2. 分离绘制逻辑 :将临时绘制和最终绘制分离,临时矩形仍通过Paint事件显示,完成的矩形绘制到叠加层
|
||||
3. 图像合并机制 :在Paint事件中先绘制叠加层,再绘制临时矩形。
|
||||
4. 保存的矩形框位置和大小信息应该是相对于图像的,而不是相对于控件的。
|
||||
5. 当btnDrawRegion按下后,处于绘制状态, btnSelectColor才显示出来
|
||||
6. 当绘制状态时,右击鼠标,退出绘制状态,且清除所有临时绘制。
|
||||
7. 当绘制状态时,双击鼠标,随机生成一个颜色,用于绘制矩形框。
|
||||
8. 当就绪状态时,鼠标移到区域内,该区域内填充半透明色,当有多个重叠时,填充索引号最大的区域
|
||||
9. 当鼠标在半透明区域内单击时,该区域填充半透明色,且显示八个句柄,表示选中该区域。
|
||||
10. 选中区域时,工具栏显示按钮btnDeleteRegion和btnSelectColor;隐藏btnDrawRegion。
|
||||
11. 当选中区域时,btnSelectColor用于改变选中区域的颜色。
|
||||
12. 当选中区域时,btnDeleteRegion用于删除该区域,删除后btnSelectColor隐藏,btnDrawRegion显示。
|
||||
13. 当选中区域时,鼠标移动到八个句柄上,显示对应的光标,用于调整区域大小。
|
||||
14. 当选中区域时,鼠标可以移动区域,用于调整区域位置。
|
||||
15. 当选中区域时,右击鼠标,退出选中状态,转为就绪状态
|
||||
16. 当就绪状态时,工具栏显示绘制温差图按钮(btnDrawTempDiff)
|
||||
17. 当绘制温差图按钮按下时,进入绘制温差图状态,显示添加和删除温差图例按钮(btnAddTempDiff、btnDeleteTempDiff),显示温差图例列表(dataGridViewTempDiff)
|
||||
18. 当绘制温差图状态时,右击鼠标进入就绪状态
|
||||
19. 初始状态/就绪状态,显示dataGridViewTempDiff,但只允许查看
|
||||
|
||||
### btnNewTempRegion(新建测温区)
|
||||
1. 移除所有已有的测温区列表
|
||||
2. 用透明色清空叠加层图像
|
||||
### btnLoadTempRegion(加载测温区)
|
||||
1. 弹出用户打开文件对话框,用户选择要加载的csv文件
|
||||
2. 移除所有已有的测温区列表,用透明色清空叠加层图像
|
||||
3. 从csv文件中读取所有测温区位置大小和颜色信息,添加到测温区列表中
|
||||
4. 用读取的颜色填充叠加层图像对应的区域
|
||||
### btnSaveTempRegion(保存测温区)
|
||||
1. 弹出用户保存文件对话框,用户选择保存路径和文件名
|
||||
2. 保存测温区列表中的所有测温区位置大小和颜色信息为csv文件
|
||||
### btnNewTempDiff(新建温差图)
|
||||
1. 用透明色清空温差层图像
|
||||
2. 移除所有已有的温差图例列表
|
||||
### btnLoadTempDiff(加载温差图)
|
||||
1. 弹出用户打开文件对话框,用户选择要加载的csv文件
|
||||
2. 用透明色清空温差层图像
|
||||
3. 移除所有已有的温差图例列表
|
||||
4. 从csv文件中读取所有温差图例信息,添加到温差图例列表中
|
||||
5. 从csv文件中读取所有像素的温度值,绘制温差层图像对应的像素
|
||||
### btnSaveTempDiff(保存温差图)
|
||||
1. 弹出用户保存文件对话框,用户选择保存路径和文件名
|
||||
2. 保存温差图例列表中的所有温差图例信息到csv文件
|
||||
3. 每个温差图例信息占一行,格式为:
|
||||
- 温度(如20°C)
|
||||
- 颜色(如#FF0000表示红色)
|
||||
4. 保存温差图每个像素的温度值到csv文件
|
||||
- 每个像素温度值占一行,格式为:
|
||||
- X坐标(如100)
|
||||
- Y坐标(如300)
|
||||
- 温度值(°C)(如25.5)
|
||||
|
||||
|
||||
|
||||
#### 配置状态说明
|
||||
1. 初始状态/就绪状态:
|
||||
- 显示btnDrawRegion和btnDrawTempDiff按钮、dataGridViewTempDiff
|
||||
- 显示btnNewTempRegion按钮、btnLoadTempRegion按钮、btnSaveTempRegion按钮、btnNewTempDiff按钮、btnLoadTempDiff按钮、btnSaveTempDiff按钮
|
||||
- 隐藏btnSelectColor、btnDeleteRegion按钮、btnAddTempDiff、btnDeleteTempDiff、btnBrushSize1、btnBrushSize3、btnBrushSize5、btnBrushSize10、btnBrushSize15、btnBrushSize25、txtRegionNumber
|
||||
2. 选中区域状态:
|
||||
- 显示btnDeleteRegion和btnSelectColor按钮、txtRegionNumber
|
||||
- 隐藏btnDrawRegion和btnDrawTempDiff按钮、dataGridViewTempDiff、btnAddTempDiff、btnDeleteTempDiff、btnBrushSize1、btnBrushSize3、btnBrushSize5、btnBrushSize10、btnBrushSize15、btnBrushSize25
|
||||
- 隐藏btnNewTempRegion按钮、btnLoadTempRegion按钮、btnSaveTempRegion按钮、btnNewTempDiff按钮、btnLoadTempDiff按钮、btnSaveTempDiff按钮
|
||||
3. 绘制状态:
|
||||
- 显示btnSelectColor按钮
|
||||
- 显示btnDrawRegion按钮、txtRegionNumber
|
||||
- 隐藏btnDeleteRegion按钮
|
||||
- 隐藏btnDrawTempDiff按钮、dataGridViewTempDiff、btnAddTempDiff、btnDeleteTempDiff、btnBrushSize1、btnBrushSize3、btnBrushSize5、btnBrushSize10、btnBrushSize15、btnBrushSize25
|
||||
- 隐藏btnNewTempRegion按钮、btnLoadTempRegion按钮、btnSaveTempRegion按钮、btnNewTempDiff按钮、btnLoadTempDiff按钮、btnSaveTempDiff按钮
|
||||
4. 绘制温差图状态:
|
||||
- 显示btnDrawTempDiff按钮,显示dataGridViewTempDiff、btnAddTempDiff、btnDeleteTempDiff
|
||||
- 当选定温差图例后,显示btnBrushSize1、btnBrushSize3、btnBrushSize5、btnBrushSize10、btnBrushSize15、btnBrushSize25
|
||||
- 隐藏btnSelectColor、btnDeleteRegion、btnDrawRegion按钮
|
||||
- 隐藏btnNewTempRegion按钮、btnLoadTempRegion按钮、btnSaveTempRegion按钮、btnNewTempDiff按钮、btnLoadTempDiff按钮、btnSaveTempDiff按钮
|
||||
Reference in New Issue
Block a user