做热像仪开发、工业在线测温或者移动设备巡检的朋友,大概率都遇到过同一个需求:画面里有个热源在动,你要把它的“移动热源坐标参数”实时交给下一级系统。可能是云台要跟着它转,可能是机械臂要定位它,也可能是后台要画它的运动轨迹。很多人一开始觉得简单——不就是把图上最亮的那个点找出来吗?真做起来才发现,从“找亮点”到输出一套稳定可靠的坐标参数,中间隔着图像分割、坐标系换算、时间戳同步、滤波预测整整一长串问题。
这篇文章我就想把我这些年做移动热源坐标参数提取的经验整理干净,从参数定义讲到标定换算,再到卡尔曼滤波和工程调优,把那些常规文档里不会写的内容一并放出来。适合正在做红外热像仪二次开发、智慧巡检、焊接自动化、传送带高温工件定位的工程师参考,也适合刚接触热成像定位、想了解这套体系该怎么搭的初学者。
1. 移动热源坐标参数:先搞清你输出的到底是一组什么数
很多人拿到需求第一反应是“输出热源的x、y坐标”。但“移动热源坐标参数”这件事,远比两个数字复杂。如果一开始不把参数的定义、层级和坐标系统搞清楚,后面写出来的程序越往后越难改。
1.1 从帧级参数到目标级参数的分层
热像仪是一帧一帧出图的,每一帧上都有完整的温度矩阵。移动热源坐标参数最原始的形式,是在某一帧上记录下来的瞬时测量值。我习惯把这组参数拆成四个层级。
- 帧级参数:图像帧号、采集时间戳、热源像素坐标、热源温度值。这是最底层的测量结果,也是后续所有计算的输入。
- 目标级参数:热源识别框、轮廓、面积、质心坐标、峰值温度、平均温度。这一步把“点”扩展成了“目标”,能表达热源的空间范围。
- 运动级参数:当前速度、加速度、运动方向、历史轨迹。这是随时间累积之后得到的动态特征,用于预测下一帧热源位置。
- 场景级参数:经过坐标转换后得到的设备坐标、平面物理坐标或地理坐标,可以和机械臂、云台、电子地图对接。
这个分层不是我硬造的,而是实际项目中各系统对坐标参数的需求完全不同。比如云台联动只需要图像坐标或角度偏差,但机械臂抓取就必须要物理坐标,消防监测则可能要求经纬度。如果一开始就只输出一个二维像素坐标,到后期接设备时往往要返工。
1.2 多个坐标系同时存在,必须命名清楚
移动热源坐标参数最容易出乱子的地方,是坐标系归属不明确。我给一个典型的热成像定位项目梳理过,现场至少会涉及四套坐标。
| 坐标系 | 说明 | 典型单位 |
|---|---|---|
| 像素坐标系 | 图像左上角为原点,横纵以像素计 | pixel |
| 图像物理坐标系 | 图像中心为原点,以物理尺寸计 | mm |
| 相机坐标系 | 以镜头光心为原点,Z轴指向场景 | mm |
| 世界/设备坐标系 | 以现场设备或地面某点为原点 | mm 或 m |
很多误动作并不是算法算错了,而是把像素坐标当成物理坐标直接用。比如我用热像仪检测一条传送带上的高温工件,目标在图像里的x坐标移动了30个像素,但这30个像素对应多少毫米,取决于传送带在画面中的深度位置。没有坐标系转换,后面的机械臂根本没法对准。
1.3 一个完整的坐标参数结构示例
为了不让讨论停在概念层面,我放一个在实际项目中用过的JSON结构。这套结构的目的很简单:让下游系统拿到这一帧之后,不需要再猜测任何东西。
json复制{
"frame_id": 1024,
"timestamp": 1714000000.832,
"target_id": 7,
"category": "hot_spot",
"bbox_pixel": [586, 402, 84, 63],
"centroid_pixel": [628, 433],
"centroid_physical": [1.208, 0.541, 0.012],
"temperature_max": 186.5,
"temperature_avg": 143.2,
"area_pix
