一、Unity 生成带标注的红外图像序列

1.1 阴燃火粒子系统参数配置

基于真实阴燃火的物理特征,校准 Unity 粒子系统核心参数,确保仿真数据的物理合理性:

参数 设置值 模拟依据
温度范围 300-690℃(映射灰度 50-200) 阴燃峰值温度 500-690℃,复燃阶段 500-600℃
温度标准差 30-85(噪声控制) 阴燃区域温度标准差实测范围
面积变化率 缓慢扩张 / 收缩 阴燃面积随时间自然变化规律
圆形度 0.6-0.9 阴燃火焰形态规则程度实测值

1.2 导出帧级量化特征

在原有截图脚本基础上扩展,实现每帧图像的数值特征(温度、面积等)同步导出:

using System.IO;
using UnityEngine;

public class DatasetCapture : MonoBehaviour
{
    public string saveRoot = "experiments/exp_001";
    private string imageFolder;
    private string featureCsvPath;
    private int imageIndex = 0;

    void Start()
    {
       
        imageFolder = Path.Combine(saveRoot, "images");
        featureCsvPath = Path.Combine(saveRoot, "features.csv");
        
        Directory.CreateDirectory(imageFolder);
        
       
        if (!File.Exists(featureCsvPath))
        {
            File.WriteAllText(featureCsvPath, "frame,temperature,area,perimeter,circularity\n");
        }
    }

    // 带特征提取的截图方法
    public void CaptureWithFeatures(RenderTexture rt)
    {
        // 1. 保存红外图像
        Texture2D screenShot = new Texture2D(rt.width, rt.height, TextureFormat.RGB24, false);
        RenderTexture.active = rt;
        screenShot.ReadPixels(new Rect(0, 0, rt.width, rt.height), 0, 0);
        screenShot.Apply();
        RenderTexture.active = null;
        
        byte[] bytes = screenShot.EncodeToPNG();
        string imagePath = Path.Combine(imageFolder, $"frame_{imageIndex:D6}.png");
        File.WriteAllBytes(imagePath, bytes);
        Destroy(screenShot);
        
        // 2. 计算当前帧核心特征
        float avgTemp = CalculateAverageTemperature(rt);      // 平均温度
        float area = CalculateHotArea(rt);                    // 阴燃面积
        float perimeter = CalculatePerimeter(rt);             // 周长
        float circularity = CalculateCircularity(rt);         // 圆形度
        
       
        string featureLine = $"{imageIndex},{avgTemp:F1},{area:F1},{perimeter:F1},{circularity:F2}\n";
        File.AppendAllText(featureCsvPath, featureLine);
        
        imageIndex++;
    }

    // 温度计算(示例实现)
    private float CalculateAverageTemperature(RenderTexture rt)
    {
        // 实际项目中需根据灰度值映射到温度(50-200 → 300-690℃)
        return Random.Range(400f, 650f);
    }

    // 面积计算
    private float CalculateHotArea(RenderTexture rt)
    {
        return Random.Range(100f, 200f); 
    }

    // 周长计算
    private float CalculatePerimeter(RenderTexture rt)
    {
        return Random.Range(30f, 60f);
    }

    // 圆形度计算
    private float CalculateCircularity(RenderTexture rt)
    {
        return Random.Range(0.6f, 0.9f);
    }
}

二、tsfresh 时序特征提取与量化

2.1 环境搭建

安装核心依赖库:

pip install tsfresh pandas numpy matplotlib scikit-learn opencv-python

2.2构建 tsfresh 标准数据集

tsfresh 要求数据为 “长格式”(long format),需为每个实验添加唯一 ID:

import pandas as pd
import glob
import os

def build_tsfresh_dataframe(experiment_root):
    """
    从多实验features.csv构建tsfresh标准DataFrame
    :param experiment_root: 实验根目录
    :return: 包含id/time/特征列的长格式DataFrame
    """
    all_data = []
    
    # 遍历所有实验文件夹
    for exp_path in glob.glob(os.path.join(experiment_root, "exp_*")):
        exp_id = os.path.basename(exp_path)
        csv_path = os.path.join(exp_path, "features.csv")
        
        if not os.path.exists(csv_path):
            print(f"跳过缺失文件: {csv_path}")
            continue
            
        # 读取单实验时序数据
        df_exp = pd.read_csv(csv_path)
        
        # 添加实验ID
        df_exp['id'] = exp_id
        # 定义时间列(tsfresh必需)
        df_exp['time'] = df_exp['frame'].astype(int)
        
        all_data.append(df_exp)
    
    # 合并所有实验数据
    df_long = pd.concat(all_data, ignore_index=True)
    return df_long


if __name__ == "__main__":
    df = build_tsfresh_dataframe('experiments/')
    print("数据预览:")
    print(df.head())
    print(f"\n总记录数: {len(df)}")
    print(f"实验列表: {df['id'].unique()}")

2.3时序特征提取

针对阴燃火特性,提取温度波动、面积变化等方面的数据:

from tsfresh import extract_features
from tsfresh.feature_extraction import settings
from tsfresh.utilities.dataframe_functions import impute

# 阴燃火核心特征配置
smoldering_features = {
    # 温度特征(核心)
    "temperature": [
        "mean", "std", "minimum", "maximum",       # 基础统计
        "quantile", "change_quantiles",            # 分位数特征
        "fft_coefficient",                         # 频谱(温度波动周期)
        "autocorrelation",                         # 自相关(变化规律)
        "linear_trend",                            # 升温/降温速率
        "longest_strike_above_mean"                # 活跃期时长
    ],
    # 面积特征
    "area": [
        "mean", "std", "linear_trend",            
        "percentage_of_reoccurring_values"        
    ],
    # 形态特征
    "circularity": ["mean", "std", "skewness"],
    # 周长特征
    "perimeter": ["mean", "std", "linear_trend"]
}

# 提取特征
extracted_features = extract_features(
    df,
    column_id="id",
    column_sort="time",
    default_fc_parameters=smoldering_features,
    n_jobs=-1  
)

# 填补缺失值
impute(extracted_features)

# 输出结果统计
print(f"提取特征数: {extracted_features.shape[1]}")
print("特征示例:")
print(extracted_features.columns[:10].tolist())

结合物理阈值(如温度 500-690℃、圆形度 0.6-0.9)对 tsfresh 特征二次筛选,通过 Unity 生成带精准标注的红外图像序列,解决真实数据采集难的问题,基于 tsfresh 提取高维度时序特征,将特征统计规律反馈至 Unity,动态校准仿真参数,持续提升数据真实性。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐