背景:
在从零开始的二三维软件开发中, 需要加载CT的dicoms影像文件, 并将其序列化之后的数据,体素化
可惜..vtk的c#库,将其体素化的时候,竟然失败...
使用vtkDicomReader ,设置 Dicom文件夹读取,竟然不停的失败...从网上找了一些版本.也没啥可用的资料...
解决办法:
直接使用 fo-Dicoms库,读取每一张 Dicom影像后, 按照序列排序后, 然后一张张数据读取,接着将数据赋予VtkImageData后,创建vtkVolumActor.
关键代码分享:
// 根据DICOM数据类型分配适当的VTK数据类型var pixelData = DicomPixelData.Create(firstDataset);int bitsAllocated = pixelData.BitsAllocated;bool isSigned = pixelData.PixelRepresentation == PixelRepresentation.Signed;if (bitsAllocated == 16){imageData.AllocateScalars(isSigned ? 4 : 8, 1);//8}else if (bitsAllocated == 8){imageData.AllocateScalars(4, 1);//4}else{throw new NotSupportedException($"不支持的位深度: {bitsAllocated}");}// 获取数据范围以便正确映射int[] extent = imageData.GetExtent();// 遍历所有切片for (int z = 0; z < depth; z++){var dataset = dicomSeries[z].Dataset;var currentPixelData = DicomPixelData.Create(dataset);var frameData = currentPixelData.GetFrame(0);byte[] byteData = frameData.Data;// 根据数据类型处理像素数据if (bitsAllocated == 16){// 正确将byte[]转换为short[]short[] pixels = new short[byteData.Length / 2];Buffer.BlockCopy(byteData, 0, pixels, 0, byteData.Length);// 如果需要考虑字节顺序if (BitConverter.IsLittleEndian != dataset.TryGetSingleValue(DicomTag.HighBit, out ushort highBit) || highBit == 0){for (int i = 0; i < pixels.Length; i++){pixels[i] = IPAddress.NetworkToHostOrder(pixels[i]);}}// 遍历当前切片的所有像素for (int y = 0; y < height; y++){for (int x = 0; x < width; x++){int index = y * width + x;short pixelValue = pixels[index];imageData.SetScalarComponentFromDouble(x, height - 1 - y, z, 0, pixelValue);}}}else if (bitsAllocated == 8){// 直接使用byte数据for (int y = 0; y < height; y++){for (int x = 0; x < width; x++){int index = y * width + x;byte pixelValue = byteData[index];imageData.SetScalarComponentFromDouble(x, height - 1 - y, z, 0, pixelValue);}}}}