190 lines
6.4 KiB
C#
190 lines
6.4 KiB
C#
using System.Collections.Concurrent;
|
||
using ThreatSource.Utils;
|
||
|
||
namespace ThreatSource.Guidance
|
||
{
|
||
/// <summary>
|
||
/// 红外图像类,表示简化的红外图像数据
|
||
/// </summary>
|
||
/// <remarks>
|
||
/// 该类存储红外图像的基本信息:
|
||
/// - 图像尺寸
|
||
/// - 像素物理大小
|
||
/// - 红外强度矩阵
|
||
/// 用于目标探测和识别
|
||
/// </remarks>
|
||
/// <remarks>
|
||
/// 初始化红外图像的新实例
|
||
/// </remarks>
|
||
public class InfraredImage
|
||
{
|
||
/// <summary>
|
||
/// 强度数据数组池,用于重用大型double数组
|
||
/// </summary>
|
||
private static readonly ConcurrentQueue<double[,]> IntensityArrayPool = new();
|
||
|
||
/// <summary>
|
||
/// 池中数组的最大数量(避免内存无限增长)
|
||
/// </summary>
|
||
private const int MAX_POOL_SIZE = 50;
|
||
|
||
/// <summary>
|
||
/// 图像宽度,单位:像素
|
||
/// </summary>
|
||
public int Width { get; private set; }
|
||
|
||
/// <summary>
|
||
/// 图像高度,单位:像素
|
||
/// </summary>
|
||
public int Height { get; private set; }
|
||
|
||
/// <summary>
|
||
/// 像素物理尺寸,单位:弧度/像素
|
||
/// </summary>
|
||
public double PixelSize { get; private set; }
|
||
|
||
/// <summary>
|
||
/// 红外强度矩阵
|
||
/// 单位:W/sr
|
||
/// </summary>
|
||
private double[,] intensityData;
|
||
|
||
/// <summary>
|
||
/// 图像中心视线方向
|
||
/// </summary>
|
||
public Vector3D LineOfSight { get; private set; }
|
||
|
||
/// <summary>
|
||
/// 烟幕覆盖掩码 (true 表示被遮蔽烟幕覆盖)
|
||
/// </summary>
|
||
public bool[,] SmokeCoverageMask { get; private set; }
|
||
|
||
/// <summary>
|
||
/// 从池中获取或创建强度数据数组
|
||
/// </summary>
|
||
private static double[,] GetIntensityArray(int height, int width)
|
||
{
|
||
if (IntensityArrayPool.TryDequeue(out var array) &&
|
||
array.GetLength(0) == height && array.GetLength(1) == width)
|
||
{
|
||
// 清零重用的数组
|
||
Array.Clear(array, 0, array.Length);
|
||
return array;
|
||
}
|
||
// 池中没有合适尺寸的数组,创建新的
|
||
return new double[height, width];
|
||
}
|
||
|
||
/// <summary>
|
||
/// 将强度数据数组归还到池中
|
||
/// </summary>
|
||
private static void ReturnIntensityArray(double[,] array)
|
||
{
|
||
if (IntensityArrayPool.Count < MAX_POOL_SIZE)
|
||
{
|
||
IntensityArrayPool.Enqueue(array);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 初始化红外图像的新实例
|
||
/// </summary>
|
||
/// <param name="width">图像宽度</param>
|
||
/// <param name="height">图像高度</param>
|
||
/// <param name="pixelSize">像素物理尺寸</param>
|
||
/// <param name="lineOfSight">视线方向</param>
|
||
/// <param name="smokeCoverageMask">烟幕覆盖掩码 (可选,可为null)</param>
|
||
public InfraredImage(int width, int height, double pixelSize, Vector3D lineOfSight, bool[,]? smokeCoverageMask = null)
|
||
{
|
||
Width = width;
|
||
Height = height;
|
||
PixelSize = pixelSize;
|
||
LineOfSight = lineOfSight;
|
||
intensityData = GetIntensityArray(height, width);
|
||
SmokeCoverageMask = smokeCoverageMask ?? new bool[height, width];
|
||
}
|
||
|
||
/// <summary>
|
||
/// 重置图像参数(用于对象池重用)
|
||
/// </summary>
|
||
/// <param name="width">图像宽度</param>
|
||
/// <param name="height">图像高度</param>
|
||
/// <param name="pixelSize">像素物理尺寸</param>
|
||
/// <param name="lineOfSight">视线方向</param>
|
||
/// <param name="smokeCoverageMask">烟幕覆盖掩码(可为null)</param>
|
||
public void Reset(int width, int height, double pixelSize, Vector3D lineOfSight, bool[,]? smokeCoverageMask)
|
||
{
|
||
Width = width;
|
||
Height = height;
|
||
PixelSize = pixelSize;
|
||
LineOfSight = lineOfSight;
|
||
SmokeCoverageMask = smokeCoverageMask ?? new bool[height, width];
|
||
|
||
// 归还旧数组到池中,获取新数组
|
||
if (intensityData != null &&
|
||
(intensityData.GetLength(0) != height || intensityData.GetLength(1) != width))
|
||
{
|
||
ReturnIntensityArray(intensityData);
|
||
intensityData = GetIntensityArray(height, width);
|
||
}
|
||
else if (intensityData == null)
|
||
{
|
||
intensityData = GetIntensityArray(height, width);
|
||
}
|
||
else
|
||
{
|
||
// 尺寸匹配,直接清零现有数组
|
||
Array.Clear(intensityData, 0, intensityData.Length);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 设置像素强度值
|
||
/// </summary>
|
||
/// <param name="row">行索引</param>
|
||
/// <param name="col">列索引</param>
|
||
/// <param name="value">强度值,单位:W/sr</param>
|
||
public void SetIntensity(int row, int col, double value)
|
||
{
|
||
if (row >= 0 && row < Height && col >= 0 && col < Width)
|
||
{
|
||
intensityData[row, col] = value;
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取像素强度值
|
||
/// </summary>
|
||
/// <param name="row">行索引</param>
|
||
/// <param name="col">列索引</param>
|
||
/// <returns>强度值,单位:W/sr</returns>
|
||
public double GetIntensity(int row, int col)
|
||
{
|
||
if (row >= 0 && row < Height && col >= 0 && col < Width)
|
||
{
|
||
return intensityData[row, col];
|
||
}
|
||
return 0.0;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取内存占用信息(用于性能监控)
|
||
/// </summary>
|
||
/// <returns>内存占用字节数</returns>
|
||
public long GetMemoryUsage()
|
||
{
|
||
return sizeof(double) * Width * Height; // double数组
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取图像信息(用于调试)
|
||
/// </summary>
|
||
/// <returns>图像的调试信息</returns>
|
||
public string GetImageInfo()
|
||
{
|
||
return $"图像尺寸: {Width}x{Height}, " +
|
||
$"像素大小: {PixelSize:E3} 弧度/像素, " +
|
||
$"内存占用: {GetMemoryUsage():N0} bytes";
|
||
}
|
||
}
|
||
} |