Files
XplorePlane/XP.Calibration/Core/RawReader.cs
T
2026-04-23 19:38:44 +08:00

93 lines
3.1 KiB
C#

using System.Drawing;
using Emgu.CV;
using Emgu.CV.CvEnum;
namespace XP.Calibration.Core;
/// <summary>
/// RAW 投影数据读取器 | RAW projection data reader
/// </summary>
public static class RawReader
{
/// <summary>
/// 从 RAW 文件读取 float32 投影序列
/// </summary>
/// <param name="path">文件路径</param>
/// <param name="width">图像宽度</param>
/// <param name="height">图像高度</param>
/// <param name="count">投影帧数</param>
/// <returns>Mat 列表 (CV_32F)</returns>
public static List<Mat> ReadFloat32(string path, int width, int height, int count)
{
var projections = new List<Mat>(count);
int frameBytes = width * height * sizeof(float);
using var stream = new FileStream(path, FileMode.Open, FileAccess.Read);
byte[] buffer = new byte[frameBytes];
for (int i = 0; i < count; i++)
{
int bytesRead = stream.Read(buffer, 0, frameBytes);
if (bytesRead < frameBytes)
throw new EndOfStreamException(
$"帧 {i} 数据不足: 期望 {frameBytes} 字节, 实际 {bytesRead} 字节");
var mat = new Mat(height, width, DepthType.Cv32F, 1);
System.Runtime.InteropServices.Marshal.Copy(buffer, 0, mat.DataPointer, frameBytes);
projections.Add(mat);
}
return projections;
}
/// <summary>
/// 读取单张 TIFF 图像, 返回 CV_32F 灰度 Mat
/// </summary>
/// <param name="path">TIFF 文件路径</param>
/// <returns>Mat (CV_32F, 单通道)</returns>
public static Mat ReadTiff(string path)
{
if (!File.Exists(path))
throw new FileNotFoundException($"TIFF 文件不存在: {path}");
// 以原始深度读取 (支持 8/16/32bit TIFF)
var src = CvInvoke.Imread(path, ImreadModes.AnyDepth | ImreadModes.Grayscale);
if (src.IsEmpty)
throw new InvalidOperationException($"无法读取 TIFF: {path}");
// 统一转为 CV_32F
if (src.Depth != DepthType.Cv32F)
{
var dst = new Mat();
src.ConvertTo(dst, DepthType.Cv32F);
src.Dispose();
return dst;
}
return src;
}
/// <summary>
/// 批量读取多张 TIFF 图像 (按文件名排序)
/// </summary>
/// <param name="directory">TIFF 文件所在目录</param>
/// <param name="pattern">搜索模式, 默认 "*.tif"</param>
/// <returns>Mat 列表 (CV_32F)</returns>
public static List<Mat> ReadTiffSequence(string directory, string pattern = "*.tif")
{
if (!Directory.Exists(directory))
throw new DirectoryNotFoundException($"目录不存在: {directory}");
var files = Directory.GetFiles(directory, pattern)
.Concat(Directory.GetFiles(directory, pattern + "f")) // 同时匹配 .tif 和 .tiff
.Distinct()
.OrderBy(f => f)
.ToList();
if (files.Count == 0)
throw new FileNotFoundException($"目录中未找到 TIFF 文件: {directory}");
return files.Select(ReadTiff).ToList();
}
}