[英]Fo-Dicom Window Change is slow
我正在使用以下渲染代码。 这是一个稍微修改过的代码,因为在实际代码中,我从 FTP 服务器获取所有文件。 CurrentWindowCenter 和 CurrentWindowWidth 保存 WL 和 WW 的当前值。 可以从 UI 更改此值。 我使用 canvas 中的图像组件直接向用户显示渲染的 WritableBitmap。但是图像的渲染速度非常慢。 特别是对于 X 射线等文件较大的图像。 所以,WW 和 WL 的变化也很慢,因为它也使用渲染 function。我对此不是很了解。 但是有没有办法让渲染或者WW/WL变化的更快呢? 有没有办法在每次 WW/WL 发生变化时跳过图像的渲染? 对正确方向的任何建议表示赞赏。 提前致谢。
// assume filePath holds an actual file location.
var filePath = "";
var dicomFile = new DicomFile.Open(filePath);
var dicomImage = new DicomImage(dicomFile.DataSet);
if (CurrentWindowCenter.HasValue && CurrentWindowWidth.HasValue)
{
dicomImage.WindowCenter = Convert.ToDouble(CurrentWindowCenter.Value);
dicomImage.WindowWidth = Convert.ToDouble(CurrentWindowWidth.Value);
}
dicomImage.RenderImage().AsWriteableBitmap();
环境
我的猜测是 fo-dicom 并不是真正为高性能而设计的,更多的是为了兼容性。 为了获得最佳性能,您应该通过 DirectX、OpenCL 或类似工具使用 GPU。 第二好的应该是一些紧密优化的 SIMD 代码,可能使用 c++。
但仅使用 c# 可能会有一些改进。从外观上看,fo-dicom 创建了一个新图像,将像素复制到该图像,然后创建一个 writeableBitmap 并执行另一个副本。 这些步骤将花费一些额外的时间。
我复制像素和应用 lut/transfer function 的代码如下所示:
public static unsafe void Mono16ToMono8(
byte* source,
byte* target,
int sourceStride,
int targetStride,
int width,
int height,
byte[] lut)
{
Parallel.For(0, height, y =>
{
var ySource = source + y * sourceStride;
var yTarget = target + y * targetStride;
var srcUshort = (ushort*)ySource;
for (int x = 0; x < width; x++)
{
var sample = srcUshort[x];
yTarget[x] = lut[sample];
}
});
}
以及对可写 bitmap 进行实际更新的代码:
public static unsafe void Update(
this WriteableBitmap self,
IImage source,
byte[] lut)
{
self.Lock();
try
{
var targetPtr = (byte*)self.BackBuffer;
fixed (byte* sourcePtr = source.Data)
{
if (source.PixelFormat == PixelType.Mono16)
{
Mono16ToMono8(
sourcePtr,
targetPtr,
source.Stride,
self.BackBufferStride,
source.Width,
source.Height,
lut);
}
}
self.AddDirtyRect(new Int32Rect(0, 0, (int)self.Width, (int)self.Height));
}
finally
{
self.Unlock();
}
}
这使用内部 IImage 格式,其中source.Data
是ReadOnlySpan<byte>
,但也可以是byte[]
。 我希望大多数其他属性都是不言自明的。 我希望这段代码会更快一些,因为它避免了分配和一些复制步骤。
所有这些都假设图像是 16 位无符号格式,这在 dicom 中很常见,但不是唯一的格式。 它还假设您实际上可以获得指向实际像素缓冲区的指针,以及将每个可能的像素值映射到一个字节的 lut 数组。 它还假定具有正确大小和颜色空间的可写位图。
如前所述,如果您既想要高性能,又想要处理所有可能的图像格式,您可能需要投入时间来构建自己的图像渲染管道。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.