简体   繁体   English

Fo-Dicom Window 变化缓慢

[英]Fo-Dicom Window Change is slow

I am using the following render code.我正在使用以下渲染代码。 This is a slightly modified code because, in the actual code, I am getting all the files from the FTP server.这是一个稍微修改过的代码,因为在实际代码中,我从 FTP 服务器获取所有文件。 CurrentWindowCenter and CurrentWindowWidth hold the current value of WL and WW. CurrentWindowCenter 和 CurrentWindowWidth 保存 WL 和 WW 的当前值。 This value can be changed from the UI.可以从 UI 更改此值。 I am showing the rendered WritableBitmap directly to the user using an image component inside a canvas. But the rendering of the image is very slow.我使用 canvas 中的图像组件直接向用户显示渲染的 WritableBitmap。但是图像的渲染速度非常慢。 Especially for images with large file sizes such as X-Ray.特别是对于 X 射线等文件较大的图像。 So, the WW and WL change is also very slow since it also uses the render function. I am not very knowledgeable about this.所以,WW 和 WL 的变化也很慢,因为它也使用渲染 function。我对此不是很了解。 But is there a way to make the rendering or WW/WL change faster?但是有没有办法让渲染或者WW/WL变化的更快呢? Is there a way to skip the rendering of the image every time a WW/WL change happens?有没有办法在每次 WW/WL 发生变化时跳过图像的渲染? Any advice in the right direction is appreciated.对正确方向的任何建议表示赞赏。 Thanks in advance.提前致谢。

// 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();

Environment环境

  • Fo-Dicom (4.0.8) Fo-Dicom (4.0.8)
  • .NET Framework 4.8 .NET 框架 4.8
  • WPF WPF

My guess is that fo-dicom is not really intended for high performance and more for compatibility.我的猜测是 fo-dicom 并不是真正为高性能而设计的,更多的是为了兼容性。 For best performance you should probably use the GPU via DirectX, OpenCL or similar.为了获得最佳性能,您应该通过 DirectX、OpenCL 或类似工具使用 GPU。 Second best should be some tightly optimized SIMD code, probably using c++.第二好的应该是一些紧密优化的 SIMD 代码,可能使用 c++。

But there might be some improvements to be had using just c#. From the looks of it fo-dicom creates a new image, copies pixels to this image, and then creates a writeableBitmap and does another copy.但仅使用 c# 可能会有一些改进。从外观上看,fo-dicom 创建了一个新图像,将像素复制到该图像,然后创建一个 writeableBitmap 并执行另一个副本。 These step will take some extra time.这些步骤将花费一些额外的时间。

My code for copying pixels and applying a lut/transfer function look like this:我复制像素和应用 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];
        }
    });
}

And the code to do the actual update of the writeable bitmap:以及对可写 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();
    }
}

This uses an internal IImage format, where source.Data is a ReadOnlySpan<byte> , but could just as well be a byte[] .这使用内部 IImage 格式,其中source.DataReadOnlySpan<byte> ,但也可以是byte[] I hope most of the other properties are self-explanatory.我希望大多数其他属性都是不言自明的。 I would expect this code to be a bit faster since it avoids both allocations and some copying steps.我希望这段代码会更快一些,因为它避免了分配和一些复制步骤。

All of this assumes the image is in 16-bit unsigned format, that is common for dicom, but not the only format.所有这些都假设图像是 16 位无符号格式,这在 dicom 中很常见,但不是唯一的格式。 It also assumes you can actually get a hold of a pointer to the actual pixel-buffer, and an array of the lut that maps each possible pixelvalue to a byte.它还假设您实际上可以获得指向实际像素缓冲区的指针,以及将每个可能的像素值映射到一个字节的 lut 数组。 It also assumes a writeablebitmap of the correct size and color space.它还假定具有正确大小和颜色空间的可写位图。

And as previously mentioned, if you want both high performance, and handle all possible image formats, you might need to invest time to build your own image rendering pipeline.如前所述,如果您既想要高性能,又想要处理所有可能的图像格式,您可能需要投入时间来构建自己的图像渲染管道。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM