【问题标题】:JPEG Huffman TableJPEG 霍夫曼表
【发布时间】:2023-03-23 00:37:01
【问题描述】:

我有一个关于 JPEG 霍夫曼表和使用霍夫曼表从树构造符号/二进制字符串的问题。假设,在3-Bit 代码长度的霍夫曼表中,代码的数量大于 6,那么我们如何将所有这些代码添加到树中?如果我是正确的,只能在树的 3 位级别/深度添加 6 个代码。那么,如果它们不适合该级别,我们如何添加剩余的代码?我们就忽略它们吗?

例子

code length | Total Codes | Codes  
3-Bit       |    10       | 25 43 34 53 92 A2 B2 63 73 C2

在上面的例子中,如果我们按照为代码构建符号/二进制字符串的顺序进行,然后直到 A2,我们可以在树中添加 3 位级别的代码,但是 B2、63、73、C2 等呢? ?不能在树的 3 位级别添加它们吗?那么我们如何处理它们呢?

【问题讨论】:

  • 在每个级别,您都会有一些终端代码和一些延续代码。一个终端代码对应一个实际值。延续代码意味着您需要阅读更多位才能获得完整代码。因此,如果您有一个 3 位代码,则最多可以有 7 个终端代码,只留下一个延续代码。
  • This wikipedia article 可能有用。为了为您的示例设计霍夫曼代码,您需要为每个值指定一个频率。然后,只有少数值会使用 3 位代码。有些值必须使用更长的代码。
  • This question/answer 可能会有所帮助。
  • 这是一个理论问题,还是您找到了包含此数据的 JPEG 文件?如果您要问如何在 JPEG 中实际解码,那么我怀疑 Mats 的回答是不够的。
  • @LuckyAli 我不能在不关闭问题的情况下投票给副本。 @500 提供的链接是您正在寻找的答案吗?

标签: c++ c jpeg


【解决方案1】:

嗯,很明显,可以用 3 位表示的“事物”的绝对最高数量是 8 - (000, 001, 010, 011, 100, 101, 110, 111)。

在 Huffman 编码中,位表示 trie 数据结构中的“左”或“右”,为了能够“继续”,您必须使用一些代码来表示“这会继续另一个级别”,这就是为什么不是全部8 个值可以用 3 位编码。如果您有更多要编码的值,则需要使用更多位(对于某些值 - 这是霍夫曼编码的重点,一些组合很短,其他组合更长,有时甚至比原始组合更长,但因为它是基于关于什么是最常见的,没关系,因为它们会很少见......)

如何构建和解码 Huffman 树大约是典型的算法书籍中的四五页,如果您没有其中之一,您可能想要找到一个 - 要么是真正的论文,要么是 e -书。它们有很多——我不会推荐一个,因为我拥有的都是 15 岁以上。

我应该补充一点,我认为您的问题缺少一些东西。显然,3 位不可能代表 10 个值。而且你不能在 10 个完全不同的值上构建 [有意义的] 霍夫曼树 - 除非想法是将这些值分成 {2,5}, {4,3}, {3,4}, {5,3}, {9,2}, {A,2}, {B,2}, {6,3}, {7,3}, {C,2} 对 - 这给出了相当数量的重复值 - 这些值的频率是: 2 : 5 3 : 5 4 : 2 5 : 2 6:1 7:1 9:1 答:1 乙:1 C : 1

但这仍然太多,无法代表任何有意义的东西......

或者相反,我们应该使用那些比特值来解码?在这种情况下,我们需要从原始数据构建的树来解码它......

【讨论】:

  • 是的,我的意思只是从解码的角度来看。您知道构建树以获取霍夫曼表中代码的二进制字符串/符号。
  • 对,那么我们需要一个树或者翻译表来翻译它——就是这里表1中的值:impulseadventure.com/photo/jpeg-huffman-coding.html
  • 嘿,即使我也跟着冲动冒险哈哈。不,我只是编造了这些值。但是,让我们以他们为例。在 class= 1 ID = 0(AC Table) 中查看 16 位长度的代码,它有 115 个代码。但是它们都不适合树的 16 位级别/深度。我认为只有 32 或其他适合。那么我们如何处理剩下的 (115-32) 代码呢?一旦添加了 32 个左右的代码,就无法再在该级别添加它们。
  • 在 16 位时,您可以编码 65535 个值 - 但由于一些用于较短的代码,因此 16 位表上有很多“漏洞” - 但显然足以编码足够的值115 个不同的“答案”。就像我在回答中所说的那样,它是一个 Trie 数据结构,其中每个值要么以一个节点结尾以进一步发展,要么以一个编码结尾。二叉树表示在这一点上非常清楚。值 01 编码为 00,值 02 编码为 01,100 编码为 03,依此类推。
  • @MatsPetersson 这个问题似乎是在询问特别是的JPEG格式;此数据存储在文件中,JPEG 将具有用于重建树的定义过程。
【解决方案2】:

在 JPEG 中,霍夫曼代码最多可以是 16 位。 DHT 市场包含一个由 16 个元素组成的数组,给出了每个长度的代码数量。

JPEG 标准解释了如何使用代码计数来进行霍夫曼转换。这是少数详细解释的事情之一。

这本书从程序员的角度解释了它是如何完成的。

JPEG Book

任何代码长度存在的代码数量取决于其他长度的计数。

我想知道您是否真的在查看长度为 4 而不是 3 的代码计数。

【讨论】:

    【解决方案3】:

    在从 JPEG 表创建 Huffman 代码时,您似乎没有遵循正确的程序。除非表已损坏,否则提供的计数将适合位数。从 DHT 标记读取代码非常简单。更复杂的部分是您如何根据该数据定义查找表。一种合乎逻辑(但不实用)的方法是创建一个反向查找表,该表是最大代码长度(表中的 16 位 = 65536 个条目)。然后解码您的 JPEG 数据,只需从输入流中提取 16 位压缩数据并将其用作表中的索引,您将在其中获得代码的符号和实际长度。我想出了一种使用单个、更小的查找表的方法。我不打算分享我的具体码表方法。我将分享的是从 DHT 标记创建代码的循环的基本格式:

    int iCurrentCode; // the current Huffman code
    int iLength; // the code length in bits that you're working on
    int i;
    int iCount; // the number of codes defined for this length
    int iSymbol; // JPEG symbol defined for each Huffman code
    unsigned char *pData; // pointer to the data in the DHT marker
    
    iCurrentCode = 0; // start with a Huffman code of 0
    for (iLength = 1; iLength <= 16; iLength++)
    {
        iCount = *pData++; // get number of symbols for this bit length
        for (i=0; i<iCount; i++) // read each of the codes for this bit length
        {
            iSymbol = *pData++; // get the JPEG symbol value (e.g. RRRR/SSSS value)
            // It's up to you to create a lookup table from the code and its value
            iCurrentCode++; // the Huffman bit pattern just increments for each code value
        } // for each code defined at this bit length
        iCurrentCode <<= 1; // shift the code left 1 bit to advance to the next bit length
    } // for each bit length
    

    【讨论】:

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