93 lines
3.1 KiB
C#
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();
|
|
}
|
|
}
|