using System; using System.Collections.Generic; using System.IO; using AI.Reconstruction; using AI.Common; namespace Tools { public class FileCreator { /// /// 注意:颈动脉三维重建的代码中extendedData是由左右颈的Enum值、VinnoImageData里读到的Probe和Visual组成的VinnoCarotid3DPhysicalData /// 考虑到要兼容甲状腺三维重建(以及其他部位),这里未给extendedData赋值(extendedData应该由界面上希望呈现哪些额外的内容来决定要写入什么信息), /// 因此在写入surface文件里时,extendedData的长度为0 /// 另,physicalLength 的单位由调用者决定,重建时不关心单位是mm还是cm还是m,(如果在界面上呈现病灶尺寸时需要单位,可以作为extendedData写入) /// /// /// /// /// /// public static RawVolumeData VidToRawVolumeData(string vidFilePath, EnumVolumeDataScanType scanType, int physicalLength) { var vinnoImgData = new VinnoImageData(vidFilePath, OperationMode.Open); int imgWidth = 0; int imgDepth = 0; float physicalWidth = 0; float physicalDepth = 0; RectF logicalRegion = RectF.Empty; List dataBuffers = new List(); for (int ni = 0; ni < vinnoImgData.ImageCount; ni++) { var vinnoImg = vinnoImgData.GetImage(ni); var imgBuffer = vinnoImg.ImageData; dataBuffers.Add(imgBuffer); if (ni == 0) { imgWidth = vinnoImg.Width; imgDepth = vinnoImg.Height; if (vinnoImg.Visuals.Count != 0) { if (vinnoImg.Visuals[0] is Vinno2DVisual visual) { if (visual.PhysicalCoordinates.ContainsKey(VinnoVisualAreaType.Tissue)) { var physicalCoordinate = visual.PhysicalCoordinates[VinnoVisualAreaType.Tissue]; if (physicalCoordinate is VinnoTissuePhysicalCoordinate pCoordinate) { physicalDepth = (float)(pCoordinate.DepthEnd - pCoordinate.DepthStart); physicalWidth = (float)pCoordinate.Width; } var logicalCoordinate = visual.LogicalCoordinates[VinnoVisualAreaType.Tissue]; var region = logicalCoordinate.Region; logicalRegion = new RectF((float)region.Left, (float)region.Top, (float)region.Width, (float)region.Height); } } } } } // 从vinnoImgData.ExtendedData中好像可以解析出 scanDistance、carotidType、carotidDirection // scanDistance 即扫查距离,等同于这里的physicalLength // carotidType 可以区分左右颈 // carotidDirection 是扫查方向,从上到下,还是从下到上 var extendedData = vinnoImgData.ExtendedData; if (extendedData.Length != 0) { using (var stream = new MemoryStream(extendedData)) { stream.Position = 0; var reader = new AI.Common.Tools.AIStreamReader(stream); var count = reader.ReadInt(); if (count > 0 && count <= extendedData.Length) { // ToDo 补充完整(用读出的值替换现在的physicalLength和scanType么?) } } } var volumeData = new RawVolumeData(); volumeData.ReadFromVinnoImageDatas(dataBuffers, imgWidth, imgDepth, logicalRegion, physicalWidth, physicalDepth, physicalLength, scanType,extendedData); return volumeData; } } }