计算位图的窗口宽度和窗口中心

时间:2015-10-09 10:33:44

标签: dicom fo-dicom


我正在尝试实现一个dicom查看器。对于dicom文件,我可以通过fo-dicom framework设置窗口宽度和窗口中心。但有时我需要设置位图的参数。我找到了如何can do it,但它不能正常工作。

private Bitmap setWinWidthAndCenter(Bitmap bmp)
{ 
    int center = (int)vsWindowCenter.Value; 
    int width = (int)vsWindowWidth.Value;
    var wyMin = center - 0.5 - (width - 1) / 2;
    var wMax = center - 0.5 + (width - 1) / 2;
    System.Drawing.Color color;
    for (int i = 0; i < bmp.Width; i++)
    {
        for (int j = 0; j < bmp.Height; j++)
        {
            color = bmp.GetPixel(i, j);
            if (color.R <= wyMin)
                color = System.Drawing.Color.FromArgb(0, 0, 0);
            else if (color.R > wMax)
                color = System.Drawing.Color.FromArgb(255, 255, 255);
            else
            {
                var val = (int)(((color.R - (center - 0.5)) / (width - 1) + 0.5) * 255);
                color = System.Drawing.Color.FromArgb(val, val, val);
            }
            bmp.SetPixel(i, j, color);
        }
    }
    return bmp;
}

可能有人知道出了什么问题。

编辑1:
左图是通过fo-dicom库接收的预期结果。右图是经过我的函数处理后的结果。
enter image description here enter image description here

3 个答案:

答案 0 :(得分:4)

查看您的中心和宽度值。它们可能特定于12或16位单色图像。这将使它们与您正在使用的限制0-255 RGB位图明显不同。

您必须正确缩放中心和宽度值或使用原始单色数据。

答案 1 :(得分:2)

我认为你的行

var val =(int)(((color.R - (center - 0.5))/(width - 1)+ 0.5)* 255);

不太正确。我想你想要

var val =(int)(((color.R - wyMin)/(width - 1)+ 0.5)* 255);

您正在尝试设置映射的分段线性变换 x值小于wyMin为0,值大于wMax为255,中间x值为0到255之间的中间值。

答案 2 :(得分:0)

我找到了解决问题的方法 该算法是正确的,但有一点:位图具有窗口宽度和中心的初始值,窗口中心:127和窗口宽度255。 我们需要做的就是计算dicom文件中的初始值与我们想要设置的值之间的差异。然后我们可以将获得的值添加到初始位图值 正确的代码如下所示。

public Bitmap setWinWidthAndCenterForBitmap(Bitmap bmp, double defaultCenter, double defaultWidth, double currentCenter, double currentWidth)
{
    double difCenter = currentCenter - defaultCenter;
    double difWidth = currentWidth - defaultWidth;
    int WinCenter = 127 + (int)difCenter;
    int WinWidth = 255 + (int)difWidth;
    var wMin = WinCenter - 0.5 - (WinWidth - 1) / 2;
    var wMax = WinCenter - 0.5 + (WinWidth - 1) / 2;
    System.Drawing.Color color;
    for (int i = 0; i < bmp.Width; i++)
    {
        for (int j = 0; j < bmp.Height; j++)
        {
            color = bmp.GetPixel(i, j);
            color = System.Drawing.Color.FromArgb(
                calculateColor(color.R, wMin, wMax, WinCenter, WinWidth),
                calculateColor(color.G, wMin, wMax, WinCenter, WinWidth),
                calculateColor(color.B, wMin, wMax, WinCenter, WinWidth));
            bmp.SetPixel(i, j, color);
        }
    }
    return bmp;
}
private byte calculateColor(byte c, double wMin, double wMax, double WinCenter, double WinWidth)
{
    if (c <= wMin)
        return 0;
    else if (c > wMax)
        return 255;
    else
        return (byte)(((c - (WinCenter - 0.5)) / (WinWidth - 1) + 0.5) * 255);
}