【问题标题】:Encode JPG image file as DICOM PixelData using ClearCanvas使用 ClearCanvas 将 JPG 图像文件编码为 DICOM PixelData
【发布时间】:2014-08-26 04:48:28
【问题描述】:

我有一组 JPG 图像,它们实际上是 CT 扫描的切片,我想将其重建为 DICOM 图像文件并导入 PACS。

我正在使用 ClearCanvas,并设置了所有必要的标签(并通过使用专有应用程序将我的一个 JPG 文件转换为 DICOM 来确认它们,以确保它们相同)。我只是不确定应该如何处理我的 JPG 文件以将其放入 PixelData 标记中?

目前我正在根据 ClearCanvas 论坛的建议将其转换为字节数组,但图像在 DICOM 查看器中只是乱码。我应该如何处理图像数据以使其成为可读格式?

    public DicomFile CreateFileFromImage(Image image)
    {
        int height = image.Height;
        int width = image.Width;
        short bitsPerPixel = (short)Image.GetPixelFormatSize(image.PixelFormat);

        byte[] imageBuffer = ImageToByteArray(image);
        DicomFile dicomFile = new DicomFile();
        dicomFile.DataSet[DicomTags.Columns].SetInt32(0, width);
        dicomFile.DataSet[DicomTags.Rows].SetInt32(0, height);
        dicomFile.DataSet[DicomTags.BitsStored].SetInt16(0, bitsPerPixel);
        dicomFile.DataSet[DicomTags.BitsAllocated].SetInt16(0, bitsPerPixel);
        dicomFile.DataSet[DicomTags.HighBit].SetInt16(0, 7);
        //other tags not shown
        dicomFile.DataSet[DicomTags.PixelData].Values = imageBuffer;
        return dicomFile;
    }
    public static byte[] ImageToByteArray(Image imageIn)
    {
        MemoryStream ms = new MemoryStream();

        imageIn.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
        return ms.ToArray();
    }

【问题讨论】:

  • 您是否设置了更多的 DicomTags 来识别像素数据?您还应该设置以下标签:PhotometricInterpretation = "RGB", SamplesPerPixel = 3, PlanarConfiguration = 0

标签: c# dicom clearcanvas


【解决方案1】:

ClearCanvas 库作为两个帮助类,可以更轻松地在 DicomFile 中编码和解码像素数据。它们是DicomCompressedPixelData 类和DicomUncompressedPixelData 类。您可以使用这些设置图像的参数,并将它们编码到DicomFile 对象中。

在您的情况下,由于您正在编码压缩对象,因此您应该使用 DicomCompressedPixelData 类。可以设置类的属性。调用UpdateMessage 方法会将这些属性值复制到DicomFile 对象。此外,这个类有一个AddFrameFragment 方法,可以正确编码像素数据。请注意,压缩的像素数据必须在每帧数据周围有一些特定的二进制包装器。这是您之前的代码中缺少的部分。下面的代码显示了如何设置它。

        short bitsPerPixel = (short)Image.GetPixelFormatSize(image.PixelFormat);

        var dicomFile = new DicomFile();
        var pd = new DicomCompressedPixelData(dicomFile);

        pd.ImageWidth = (ushort)image.Width;
        pd.ImageHeight = (ushort) image.Height;
        pd.BitsStored = (ushort)bitsPerPixel;
        pd.BitsAllocated = (ushort) bitsPerPixel;
        pd.HighBit = 7;
        pd.SamplesPerPixel = 3;
        pd.PlanarConfiguration = 0;
        pd.PhotometricInterpretation = "YBR_FULL_422";

        byte[] imageBuffer = ImageToByteArray(image);
        pd.AddFrameFragment(imageBuffer);

        pd.UpdateMessage(dicomFile);

        return dicomFile;

【讨论】:

  • 感谢史蒂夫,当我尝试这种方式时,我得到一个 NullReferenceException 就行了:var pd = new DicomCompressedPixelData(dicomFile);
  • 当在 pd 上调用 ctor 时,它抱怨 DicomPixelData 类中的 PhotometricInterpretastion 为空。我添加了一个检查是否为空,但现在我得到“附加的片段错误地是奇数长度”,因为我的字节数组是奇数长度。鉴于它是压缩的,我该怎么做才能将其填充或修剪成均匀的长度?
【解决方案2】:

我最终手动处理了位图,并在图像中的红色通道中创建了一个数组,遵循插件中的一些代码:

            int size = rows * columns;
            byte[] pData = new byte[size]; 
            int i = 0;

            for (int row = 0; row < rows; ++row)
            {
                for (int column = 0; column < columns; column++)
                {
                    pData[i++] = image.GetPixel(column, row).R;
                }
            }

它确实有效,但速度非常慢,并且会创建臃肿的 DICOM 文件。我很想让内置的 DicomCompressedPixelData 类工作。

非常欢迎任何进一步的建议。

【讨论】:

    【解决方案3】:

    在插入 DICOM 数据集之前,了解 JPEG CT 图像的位深度和颜色分量非常重要。它可以是 8 位有损(JPEG 压缩过程 2)或 12 位有损(JPEG 压缩过程 4)或 8、12 或 16 位无损灰度 JPEG(JPEG 压缩过程 14 - 无损、非分层)。此信息对于更新像素数据相关信息至关重要,例如光度解释、每像素样本、平面配置、分配的位、传输语法的高位。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多