0

我正在使用带有 C# 的 mDCM 来查看 dicom 标签,但我正在尝试将像素数据转换为位图并最终转换为 JPG 文件。我已阅读 mDCM Google Group 上有关该主题的所有帖子,并且所有代码示例都不起作用或缺少重要的代码行。我正在使用的图像是 16 位单色 1(即提到的格式,但它实际上是 16 位灰度)。我曾尝试使用 LockBits、SetPixel 和不安全代码将像素数据转换为位图,但所有尝试都失败了。有没有人有任何代码可以使这项工作。

这是我使用 SetPixel 的最新尝试:

DcmElement pixelData = this.currentFileFormat.Dataset.GetElement(new DcmTag(DcmConstTags.PixelData));
ushort[] pixels = this.currentPixelData.GetFrameDataU16(0);
this.currentImage = new Bitmap(this.currentPixelData.ImageWidth, this.currentPixelData.ImageHeight, PixelFormat.Format16bppRgb555);
int resample = (int)Math.Pow(2, (this.currentPixelData.BitsStored - 8));

int pxCounter = 0;
int min = ushort.MaxValue;
int max = 0;

for (int c = 0; c < this.currentPixelData.ImageHeight; c++)
{
    for (int r = 0; r < this.currentPixelData.ImageWidth; r++)
    {
        ushort pxColor = pixels[pxCounter];
        int temp = 255 - (pxColor / resample);
        if (temp < min) min = temp;
        if (temp > max) max = temp;
        this.currentImage.SetPixel(r, c, Color.FromArgb(temp, temp, temp));
        pxCounter++;
    }
}

更新:通过使用 LockBits 和 Marshal.Copy,我已经更接近了,但是图像以彩虹色而不是灰度出现。所以我猜我需要一种将灰度数据转换为 RBG 格式的方法:

byte[] pixels = this.currentPixelData.GetFrameDataU8(frameIndex);
this.currentImage = new Bitmap(this.currentPixelData.ImageWidth, this.currentPixelData.ImageHeight, PixelFormat.Format16bppRgb555);
BitmapData bitmapData = this.currentImage.LockBits(new Rectangle(0, 0, this.currentImage.Width, this.currentImage.Height), ImageLockMode.ReadWrite, this.currentImage.PixelFormat);
System.Runtime.InteropServices.Marshal.Copy(pixels, 0, bitmapData.Scan0, this.currentImage.Width * this.currentImage.Height * 2);
this.currentImage.UnlockBits(bitmapData);

提前致谢

PS 在有人建议尝试像 ClearCanvas 这样的其他东西之前,要知道 mDCM 是唯一适合我需要的库,而 ClearCanvas 对于我需要做的事情来说太臃肿了。

4

3 回答 3

1

我最终想通了,所以如果其他人偶然发现这个问题,我可以使用 CodeProject 文章中的代码显示和保存 16 位灰度图像。这是该文章的链接:

http://www.codeproject.com/KB/graphics/Image16bit.aspx?msg=3210733

于 2010-04-07T12:04:23.587 回答
0

太糟糕了,您没有将 GDCM 与 C# 一起使用。这将是一段 5 行代码:

http://gdcm.sourceforge.net/html/ExtractEncapsulatedFile.cs-example.html

于 2010-04-06T14:47:40.440 回答
0

我在Atalasoft工作,我们有一个成像组件可以为您执行此操作:

DicomDecoder decoder = new DicomDecoder();
using (AtalaImage image = decoder.Read(stream, frameIndex, null)) {
    AtalaImage imageToSave = null;
    if (image.PixelFormat == PixelFormat.Pixel16bppGrayscale) {
        imageToSave = image.GetChangedPixelFormat(PixelFormat.Pixel8bppGrayscale);
    }
    else if (image.PixelFormat == PixelFormat.Pixel48bppBgr) {
        imageToSave = image.GetChangedPixelFormat(PixelFormat.Pixel24bppBgr);
    }
    else {
        imageToSave = image;
    }
    imageToSave.Save(outputStream, new JpegEncoder(), null);
    if (imageToSave != image)
        imageToSave.Dispose();
}

这比它严格需要的要冗长一些 - 我会分解出一个例程,以适合您要使用的编码器的格式返回图像。一般来说,JPEG 是它可以处理的相当有限的像素格式,而 dicom 可以封装一些相当宽的格式。TIFF 可能是输出文件格式的更好选择。

我提出这个是因为 DicomDecoder 对象会自动处理 dicom 更深奥的像素格式,允许您在图像的原始空间中进行窗口和调平(也就是亮度和对比度),以及获取标签,我们给您 win/用于显示 AtalaImages 的 Web 表单控件,这可能会大大减小您的应用程序大小。

当然,有一组合理的原因可能会限制您使用 mDCM,但我认为它可能会帮助您(或其他人)看到另一种选择。

于 2010-04-07T12:37:55.190 回答