Operator JPEG_Encoder_Gray

Operator Library: Compression

该算子对 8 位灰度图像执行 JPEG 压缩。

[重要] 要求输入数据为 8x8 像素块

在其输入端,算子需要接收已重新映射为 8x8 像素块的图像数据。

如果使用 microEnable IV 采集卡,您可以使用算子 ImageBuffer_JPEG_Gray 进行此重新映射。 对于 microEnable IV 设计,只需在算子 JPEG_Encoder_Gray 前面使用算子 ImageBuffer_JPEG_Gray。 算子 ImageBuffer_JPEG_Gray 旨在执行此重新排序。

如果使用 microEnable 5 采集卡,请确保在使用算子 JPEG_Encoder_Gray 之前,将图像数据重新映射为 8x8 像素块(使用通用的 VisualApplet 选项)。

算子的输出是没有 JPEG 标头的 Huffman 流。 压缩率取决于所选的量化表,该量化表在运行时可更改。 对于 Huffman 编码,使用标准亮度表。 除量化表外,压缩率即输出流大小取决于输入图像。 因此,算子的输出宽度可更改为所需的输出大小。

JPEG 编码器能够以每个时钟周期处理约 2.5 个输入像素的速度运行。 时钟频率取决于所使用的采集卡。microEnable IV 采集卡的基准时钟频率为 62.5MHz。 因此,该算子能够在 microEnable IV 采集卡上处理 158MPixels/s。 如果使用会导致高 Quality 压缩的量化表,则可以降低数据速率。 这适用于大约 95% 以上的 Quality 级别。 有关更多详情,请参阅 JPEG 应用说明。

该算子允许使用代表两种不同配置方式的两个参数来选择量化表。

  • 如果需要,可以单独设置每个量化表值。 在这种情况下,请使用参数 quantization_matrix。

  • 或者,可以根据百分比值确定量化表。 在这种情况下,请使用参数 quality_in_percent。

标准亮度量化表如下所示,并用作算子的默认设置。

如果使用百分比 Quality,则通过以下公式计算量化表

如前所述,算子的输出是已编码图像数据的 Huffman 流。 底层 DC 系数和 AC 系数是固定的,取自文献, 即 W. P. Pennbaker 和 J. L. Mitchell 所著的《JPEG 静态图像数据压缩标准》(Van Nostrand Rheinhold,1993 年)。 有关清单,请参见下文。 编码器生成的 Huffman 流不包含生成 JPEG 图像文件所需的 JPEG 标头。 此外,生成的数据流的 Bit Width 为 32 位。 JPEG 数据流的最后一个字(即最后四个字节)提供以下格式的状态信息:

  • 最后一个字的第零字节和第一字节表示 JPEG EOI 标记,即 0xff 和 0xd9。

  • 第二字节表示倒数第二个数据字中使用的字节数,范围为 [1, 4],即 JPEG 数据流的真正末尾。

  • 最后一个字节(第三字节)表示错误代码。 如果 JPEG 数据流大于为输出链路指定的最大图像宽度,则输出将被截断。 如果发生这种情况,最后一个字节将设置为 1,这允许检测此截断。

以下是 JPEG 输出数据流末尾的示例:

倒数第二个字:0xffff5fed

最后一个字:0x0002d9ff

因此,JPEG 输出数据流以倒数第二个字的第二个字节结束。 数据流未被截断。

算子限制

  • 该 operator 不支持空图像,即不包含像素的图像。

  • 端口 I 处每个输入图像的行必须具有相同的长度。因此不允许行长度可变的图像。

I/O Property

Property 值
Operator Type M
Input Link I,数据输入
Output Link O,数据输出

Supported Link Format

Link Parameter Input Link I Output Link O
Bit Width 8 32
Arithmetic unsigned as I
Parallelism 8 1
Kernel Columns 1 as I
Kernel Rows 1 as I
Img Protocol VALT_IMAGE2D as I
Color Format VAF_GRAY as I
Color Flavor FL_NONE as I
Max. Img Width any1 any
Max. Img Height any2 1

1 2

输入宽度和高度必须是 8 的倍数。

参数

quality_in_percent
键入 动态读/写参数
默认 50
范围 [-1, 100]

使用此参数可以更改 JPEG 压缩的 Quality。 量化矩阵是使用上面给出的公式从百分比值确定的。 确定的量化值可以从参数 quantization_matrix 中读取。 该参数是动态的,应仅在小程序的空闲时间更改。

可以定义介于 0 和 100 之间的 Quality 设置。 写入此参数将覆盖通过参数 quantization_matrix 对量化矩阵进行的手动更改。 如果从 quality_in_percent 中读取到 -1,则说明已对量化矩阵进行了手动更改。

quantization_matrix
键入 静态/动态读写参数
默认 标准矩阵(见上文)
范围 [1, 255]

此参数是一个动态读写矩阵参数。 如果以百分比值设置 JPEG Quality。 此参数可用于读取确定的量化矩阵值。

该参数也可用于指定用户自定义的量化矩阵。 这可以通过写入任何量化矩阵值来实现。 请注意,写入 qulity_in_percent 参数将丢弃用户指定的量化值。 为了方便起见,在写入用户指定的值后,quality_in_percent 参数将被设置为 -1。

使用示例

以下示例展示了 JPEG_Encoder_Gray 算子的使用方法:

更多信息

使用以下 Huffman DC 和 AC 系数。

typedef char DCHuffTableType[12][17]; // huffman-table for luminance-DC-coefficients

DCHuffTableType Lum_DC_HuffmanTable= {
"00",
"010",
"011",
"100",
"101",
"110",
"1110",
"11110",
"111110",
"1111110",
"11111110",
"111111110" };

typedef char ACHuffTableType[16][11][17]; // Huffman-Tabelle für Luminance-AC-Koeffizienten

ACHuffTableType Lum_AC_HuffmanTable= {
{ //Run == 0
"1010",//EOB
"00",
"01",
"100",
"1011",
"11010",
"1111000",
"11111000",
"1111110110",
"1111111110000010",
"1111111110000011"
},
{ //Run == 1
"1010",//EOB
"1100",
"11011",
"1111001",
"111110110",
"11111110110",
"1111111110000100",
"1111111110000101",
"1111111110000110",
"1111111110000111",
"1111111110001000"
},
{ //Run == 2
"1010",//EOB
"11100",
"11111001",
"1111110111",
"111111110100",
"1111111110001001",
"1111111110001010",
"1111111110001011",
"1111111110001100",
"1111111110001101",
"1111111110001110"
},
{ //Run == 3
"1010",//EOB
"111010",
"111110111",
"111111110101",
"1111111110001111",
"1111111110010000",
"1111111110010001",
"1111111110010010",
"1111111110010011",
"1111111110010100",
"1111111110010101"
},
{ //Run == 4
"1010",//EOB
"111011",
"1111111000",
"1111111110010110",
"1111111110010111",
"1111111110011000",
"1111111110011001",
"1111111110011010",
"1111111110011011",
"1111111110011100",
"1111111110011101",
},
{ //Run == 5
"1010",//EOB
"1111010",
"11111110111",
"1111111110011110",
"1111111110011111",
"1111111110100000",
"1111111110100001",
"1111111110100010",
"1111111110100011",
"1111111110100100",
"1111111110100101"
},
{ //Run == 6
"1010",//EOB
"1111011",
"111111110110",
"1111111110100110",
"1111111110100111",
"1111111110101000",
"1111111110101001",
"1111111110101010",
"1111111110101011",
"1111111110101100",
"1111111110101101"
},
{ //Run == 7
"1010",//EOB
"11111010",
"111111110111",
"1111111110101110",
"1111111110101111",
"1111111110110000",
"1111111110110001",
"1111111110110010",
"1111111110110011",
"1111111110110100",
"1111111110110101",
},
{ //Run == 8
"1010",//EOB
"111111000",
"111111111000000",
"1111111110110110",
"1111111110110111",
"1111111110111000",
"1111111110111001",
"1111111110111010",
"1111111110111011",
"1111111110111100",
"1111111110111101"
},
{ //Run == 9
"1010",//EOB
"111111001",
"1111111110111110",
"1111111110111111",
"1111111111000000",
"1111111111000001",
"1111111111000010",
"1111111111000011",
"1111111111000100",
"1111111111000101",
"1111111111000110"
},
{ //Run == 0xA
"1010",//EOB
"111111010",
"1111111111000111",
"1111111111001000",
"1111111111001001",
"1111111111001010",
"1111111111001011",
"1111111111001100",
"1111111111001101",
"1111111111001110",
"1111111111001111"
},
{ //Run == 0xB
"1010",//EOB
"1111111001",
"1111111111010000",
"1111111111010001",
"1111111111010010",
"1111111111010011",
"1111111111010100",
"1111111111010101",
"1111111111010110",
"1111111111010111",
"1111111111011000"
},
{ //Run == 0xC
"1010",//EOB
"1111111010",
"1111111111011001",
"1111111111011010",
"1111111111011011",
"1111111111011100",
"1111111111011101",
"1111111111011110",
"1111111111011111",
"1111111111100000",
"1111111111100001"
},
{ //Run == 0xD
"1010",//EOB
"11111111000",
"1111111111100010",
"1111111111100011",
"1111111111100100",
"1111111111100101",
"1111111111100110",
"1111111111100111",
"1111111111101000",
"1111111111101001",
"1111111111101010"
},
{ //Run == 0xE
"1010",//EOB
"1111111111101011",
"1111111111101100",
"1111111111101101",
"1111111111101110",
"1111111111101111",
"1111111111110000",
"1111111111110001",
"1111111111110010",
"1111111111110011",
"1111111111110100"
},
{ //Run == 0xF
"11111111001", //ZRL
"1111111111110101",
"1111111111110110",
"1111111111110111",
"1111111111111000",
"1111111111111001",
"1111111111111010",
"1111111111111011",
"1111111111111100",
"1111111111111101",
"1111111111111110"
}
};