- 原始码值 → 摄氏度
- 温度统计结果,对一帧 96×96 原始数据分析(一个结构体包含原始数据,温度数据,温度最高最低点坐标)
- 最高/最低/平均/中心温及其坐标
- 缩放原始测温矩阵
/*
* thermal.h — 热成像测温数据处理声明
*
* 原始值 → 摄氏度换算(由固件决定):
* TEMP_RAW_TO_C(raw) = raw/64.0 - 50.0
* raw = 16-bit 无符号原始值,范围约 3200~12800(0℃~150℃)
*
* 坐标系统:
* 原始测温矩阵 96×96(由传感器分辨率固定),
* compute_thermal_stats() 在该分辨率上搜索最高/最低温 x,y。
*/
#ifndef THERMAL_H
#define THERMAL_H
#include <stdint.h>
/* 原始码值 → 摄氏度 */
#define TEMP_RAW_TO_C(raw) ((raw) / 64.0f - 50.0f)
/* 温度统计结果(对一帧 96×96 原始数据分析得出) */
typedef struct {
uint16_t raw_min, raw_max, raw_center; /* 原始码值 */
float min_c, max_c, avg_c, center_c; /* 对应摄氏度 */
int min_x, min_y, max_x, max_y; /* 最高/最低温在 96×96 网格中的坐标 */
} thermal_stats_t;
/* 分析一帧原始测温数据。
* @param temp 96×96 uint16_t 原始数据
* @param w,h 宽度和高度(固定 96×96)
* @return thermal_stats_t 包含最高/最低/平均/中心温及其坐标
*/
thermal_stats_t compute_thermal_stats(const uint16_t *temp, int w, int h);
/* 缩放原始测温矩阵(最近邻插值)。
* @param src 输入矩阵 sw×sh
* @param dst 输出矩阵 dw×dh(调用者分配)
*/
void scale_thermal(const uint16_t *src, int sw, int sh,
uint16_t *dst, int dw, int dh);
#endif
/*
* thermal.c — 测温数据处理实现
*
* 提供两个核心函数:
* compute_thermal_stats — 遍历 96×96 原始数据,找最高温/最低温/中心温/平均温
* scale_thermal — 最近邻插值缩放原始矩阵
*
* 原始值 → 摄氏度换算(固件约定):
* °C = raw_value / 64 - 50
* 例如 raw=6400 → 50.0°C
*/
#include "thermal.h"
#include <limits.h>
/*
* 最近邻插值缩放原始测温矩阵。
*
* @param src 输入矩阵 sw×sh
* @param dst 输出矩阵 dw×dh(由调用者分配)
* @param sw,sh 输入尺寸
* @param dw,dh 输出尺寸
*/
void scale_thermal(const uint16_t *src, int sw, int sh,
uint16_t *dst, int dw, int dh)
{
for (int dy = 0; dy < dh; dy++) {
int sy = dy * sh / dh;
for (int dx = 0; dx < dw; dx++) {
int sx = dx * sw / dw;
dst[dy * dw + dx] = src[sy * sw + sx];
}
}
}
/*
* 计算一帧原始测温数据的统计信息。
*
* 遍历整个矩阵,同时找出最高温/最低温的原始值及其坐标,
* 计算平均温,读取中心点温度。
* 所有温度同时以原始值和摄氏度返回。
*
* @param temp 96×96 uint16_t 原始数据
* @param w,h 矩阵尺寸(固定 96×96)
* @return 填充好的 thermal_stats_t
*/
thermal_stats_t compute_thermal_stats(const uint16_t *temp, int w, int h)
{
thermal_stats_t stats;
int pixels = w * h;
uint16_t tmin = UINT16_MAX, tmax = 0;
double sum = 0.0;
int cx = w / 2, cy = h / 2;
int min_xi = 0, min_yi = 0, max_xi = 0, max_yi = 0;
for (int yi = 0; yi < h; yi++) {
for (int xi = 0; xi < w; xi++) {
uint16_t v = temp[yi * w + xi];
if (v < tmin) { tmin = v; min_xi = xi; min_yi = yi; }
if (v > tmax) { tmax = v; max_xi = xi; max_yi = yi; }
sum += v;
}
}
stats.raw_min = tmin;
stats.raw_max = tmax;
stats.raw_center = temp[cy * w + cx];
stats.min_c = TEMP_RAW_TO_C(tmin);
stats.max_c = TEMP_RAW_TO_C(tmax);
stats.avg_c = TEMP_RAW_TO_C(sum / pixels);
stats.center_c = TEMP_RAW_TO_C(stats.raw_center);
stats.min_x = min_xi;
stats.min_y = min_yi;
stats.max_x = max_xi;
stats.max_y = max_yi;
return stats;
}