JPEG压缩像素数据为Raw像素数据

本文关键字:数据 像素 像素数 Raw 压缩 JPEG | 更新日期: 2023-09-27 18:17:12

对于不知道什么是DICOM文件的人来说,它是一个保存有关患者的医学成像数据的文件。它保存病人数据和一些像素数据。您只需要知道像素数据在同一个文件中,但与患者的其他数据分开。

我编写了一个程序,可以读取DICOM文件中的RAW像素数据。然而,像素数据通常使用JPEG压缩进行压缩。下面是我用来了解像素压缩方法的字典:

using System.Collections.Generic;
namespace DICOMViewer.Parsing
{
    public static class TransferSyntaxDictionary
    {
        // DICOM Transfer Syntax Dictionary
        // Reference: DCIOM Standard 2009, Part 5: Data Structures and Encoding
        static private readonly Dictionary<string, string> d = new Dictionary<string, string>
        {
            { "1.2.840.10008.1.2", "Implicit VR Little Endian: Default Transfer Syntax for DICOM" },
            { "1.2.840.10008.1.2.1", "Explicit VR Little Endian" },
            { "1.2.840.10008.1.2.1.99", "Deflated Explicit VR Little Endian" },
            { "1.2.840.10008.1.2.2", "Explicit VR Big Endian" },
            { "1.2.840.10008.1.2.4.50", "JPEG Baseline (Process 1): Default Transfer Syntax for Lossy JPEG 8 Bit Image Compression" },
            { "1.2.840.10008.1.2.4.51", "JPEG Extended (Process 2 & 4): Default Transfer Syntax for Lossy JPEG 12 Bit Image Compression (Process 4 only)" },
            { "1.2.840.10008.1.2.4.52", "JPEG Extended (Process 3 & 5)" },
            { "1.2.840.10008.1.2.4.53", "JPEG Spectral Selection, Non-Hierarchical (Process 6 & 8)" }, 
            { "1.2.840.10008.1.2.4.54", "JPEG Spectral Selection, Non-Hierarchical (Process 7 & 9)" },
            { "1.2.840.10008.1.2.4.55", "JPEG Full Progression, Non-Hierarchical (Process 10 & 12)" },
            { "1.2.840.10008.1.2.4.56", "JPEG Full Progression, Non-Hierarchical (Process 11 & 13)" },
            { "1.2.840.10008.1.2.4.57", "JPEG Lossless, Non-Hierarchical (Process 14)" }, 
            { "1.2.840.10008.1.2.4.58", "JPEG Lossless, Non-Hierarchical (Process 15)" },
            { "1.2.840.10008.1.2.4.59", "JPEG Extended, Hierarchical (Process 16 & 18)" },
            { "1.2.840.10008.1.2.4.60", "JPEG Extended, Hierarchical (Process 17 & 19)" },
            { "1.2.840.10008.1.2.4.61", "JPEG Spectral Selection, Hierarchical (Process 20 & 22)" },
            { "1.2.840.10008.1.2.4.62", "JPEG Spectral Selection, Hierarchical (Process 21 & 23)" },
            { "1.2.840.10008.1.2.4.63", "JPEG Full Progression, Hierarchical (Process 24 & 26)" }, 
            { "1.2.840.10008.1.2.4.64", "JPEG Full Progression, Hierarchical (Process 25 & 27)" },
            { "1.2.840.10008.1.2.4.65", "JPEG Lossless, Hierarchical (Process 28)" },
            { "1.2.840.10008.1.2.4.66", "JPEG Lossless, Hierarchical (Process 29)" },
            { "1.2.840.10008.1.2.4.70", "JPEG Lossless, Non-Hierarchical, First-Order Prediction (Process 14 [Selection Value 1]): Default Transfer Syntax for Lossless JPEG Image Compression" }, 
            { "1.2.840.10008.1.2.4.80", "JPEG-LS Lossless Image Compression" },
            { "1.2.840.10008.1.2.4.81", "JPEG-LS Lossy (Near-Lossless) Image Compression" },
            { "1.2.840.10008.1.2.4.90", "JPEG 2000 Image Compression (Lossless Only)" },
            { "1.2.840.10008.1.2.4.91", "JPEG 2000 Image Compression" },
            { "1.2.840.10008.1.2.4.92", "JPEG 2000 Part 2 Multi-component Image Compression (Lossless Only)" },
            { "1.2.840.10008.1.2.4.93", "JPEG 2000 Part 2 Multi-component Image Compression" },
            { "1.2.840.10008.1.2.4.94", "JPIP Referenced" },
            { "1.2.840.10008.1.2.4.95", "JPIP Referenced Deflate" },
            { "1.2.840.10008.1.2.4.100", "MPEG2 Main Profile @ Main Level" },
            { "1.2.840.10008.1.2.5", "RLE Lossless" },
            { "1.2.840.10008.1.2.6.1", "RFC 2557 MIME encapsulation" }
        };
        static public string GetTransferSyntaxName(string theTransferSyntaxUID)
        {
            return d.ContainsKey(theTransferSyntaxUID) ? d[theTransferSyntaxUID] : "???";
        }
    }
}

正如你所看到的,有26种不同类型的JPEG压缩方法,我想要解压缩(所有那些具有1.2.840.10008.1.2.4.xx的密钥)。总而言之,我有一些使用JPEG压缩算法压缩的像素数据(作为MemoryStream),我想将其解压缩为RAW像素数据。我都不知道从何说起!这有点令人沮丧。

有些人想知道我尝试了什么:我尝试使用LibJpeg。. NET,但是当我调用jpeg_decompress_struct.jpeg_read_header(bool require_image)函数时,我得到一个例外:Not a JPEG file: starts with 0xFE 0xFF

JPEG压缩像素数据为Raw像素数据

DICOM几乎支持所有的ITU 81标准,而著名的libjpeg(在其通用二进制分发[*]中)仅支持8位霍夫曼&;顺序。

你需要使用另一个JPEG库,至少支持:

  • 8/12位霍夫曼&连续的
  • 16位无损的
参考:

  • libjpeg和无损JPEG
  • JPEG无损in DICOM
  • c#:解码JPEG图像与12位精度使用Silverlight FJCore库?

[*]如果你下载源代码,你将能够编译12位的huffman/顺序二进制文件。


编辑:事实上重读你的问题,我发现你根本没有处理碎片,因此著名的0xFE 0xFF错误信息。您应该阅读DICOM标准,因为它附带了一些简单的示例。

上面列出的大多数传输语法都是废弃的,所以DICOM标准不知道这种压缩是有效的。

  • 1.2.840.10008.1.2.4.52已退役
  • 1.2.840.10008.1.2.4.53已退役
  • 1.2.840.10008.1.2.4.54已退役
  • 1.2.840.10008.1.2.4.55已退役
  • 1.2.840.10008.1.2.4.56已退役
  • 1.2.840.10008.1.2.4.57已退役
  • 1.2.840.10008.1.2.4.58已退役
  • 1.2.840.10008.1.2.4.59已退役
  • 1.2.840.10008.1.2.4.60已退役
  • 1.2.840.10008.1.2.4.61已退役
  • 1.2.840.10008.1.2.4.62已退役
  • 1.2.840.10008.1.2.4.63已退役
  • 1.2.840.10008.1.2.4.64已退役
  • 1.2.840.10008.1.2.4.65已退役
  • 1.2.840.10008.1.2.4.66已退役

所以你不需要支持它。也许您想要支持旧图像,但请记住,它们中的许多在过去并没有真正使用过,并且从2006年开始退役!

此外,每个DICOM设备都必须与DICOM一致性声明相关联,其中声明了传输系统支持等事项。您不需要支持所有的DICOM传输语法,只需要支持您在一致性声明中声明的那些。例如,并非所有DICOM设备都支持Jpeg2000或Jpeg LS

DICOM压缩图像pixeldata没有像JPEG文件那样的标准图像标题。像列、行、bitsperpixel等像素信息只直接编码在DICOM Data-Set Attribute值中,Data-Set PixelData Attribute值包含经过特殊编码的压缩字节流。检查DICOM标准PS 3.5附录A -传输语法,特别注意A.4http://dicom.nema.org/medical/dicom/current/output/chtml/part05/sect_A.4.html

话虽这么说,我也有同样的问题,找到能够解码和编码JPEG无损非分层级别14和预测器选择值1 (DICOM的原生JPEG无损压缩)的库。哪一个可以很容易地从ITU-T.81中实现标准(可以从许多地方下载它的日期从1998年或类似的东西)。仅使用DICOM标准指定的标准,我在一周内编写了两个编码器/解码器编解码器,而不是一个。我只使用查找表,它的工作速度非常快。认为一旦你建立了一个下一个更容易,因为你有JPEG读/写基础设施,唯一捕获的是实现MCU编码/解码逻辑的JPEG扩展,如JPEG- ls。

如果你决定不走那条路,第二个解决方案是重建丢失的头。我决定不这样做,因为大多数库实际上不支持这种压缩(至少我的经验),而且实际上支持它的库非常庞大(支持大量我们实际上不需要的其他东西)。但无论如何,这两条路都通向学习JPEG编码过程的内部。

最后一个解决方案是找到一些能够做到这一点的开源项目,我想现在网上应该有更多的可用项目。