我正在尝试实现一个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;
}
可能有人知道出了什么问题。
答案 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);
}