Unity+Python 构建阴燃火红外仿真①
·
一、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,动态校准仿真参数,持续提升数据真实性。
更多推荐


所有评论(0)