我正在使用带有C#的mDCM来查看dicom标签,但我正在尝试将像素数据转换为Bitmap并最终转换为JPG文件。我已经阅读了mDCM Google Group上有关该主题的所有帖子,并且所有代码示例都不起作用或缺少重要的代码行。我正在使用的图像是16位单色1(这是所提到的格式,但它实际上是16位灰度)。我尝试使用LockBits,SetPixel和不安全的代码,以便将像素数据转换为Bitmap,但所有尝试都失败了。有没有人有任何可以使这项工作的代码。
以下是我使用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);
提前致谢
P.S。在任何人建议尝试像ClearCanvas这样的其他东西之前,要知道mDCM是唯一适合我需要的库,而ClearCanvas对于我需要做的事情来说太过臃肿了。
答案 0 :(得分:1)
我最终弄明白了,所以如果有其他人偶然发现这个问题,我可以使用CodeProject文章中的代码显示和保存16位灰度图像。这是该文章的链接:
http://www.codeproject.com/KB/graphics/Image16bit.aspx?msg=3210733
答案 1 :(得分:0)
太糟糕了,你没有在C#中使用GDCM。这将是一行5行代码:
http://gdcm.sourceforge.net/html/ExtractEncapsulatedFile.cs-example.html
答案 2 :(得分: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更深奥的像素格式,允许你在图像的原始空间中进行窗口和调平(也就是亮度和对比度),以及获取标签,我们给出你赢得/网页表单控件来显示AtalaImages,这可能会缩小你的应用程序大小。
当然,有一些合理的理由可能会限制您使用mDCM,但我认为它可能会帮助您(或其他人)看到其他选项。