• 原始码值 → 摄氏度
  • 温度统计结果,对一帧 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;
}