【发布时间】:2014-06-05 21:27:56
【问题描述】:
我正在尝试为彩色 JPEG 实现基于 DCT 的图像压缩算法。我是图像处理的新手,所以我需要一些帮助。我需要的是对算法的澄清。
我正在使用来自 here 的 DCT 实现
所以,这是我理解的算法:
- 使用 ImageIO 将图像加载到 BufferedImage 中。
-
创建 3 个矩阵(每个通道 1 个:红色、绿色、蓝色):
int rgb = bufferedImage.getRGB(i, j); int red = (rgb >> 16) & 0xFF; int green = (rgb >> 8) & 0xFF; int blue = rgb & 0xFF; 将矩阵增加到大小,以便它们可以分成 8x8 的块(其中 8 是 DCT 矩阵的大小,N)
- 对于每个矩阵,将其拆分为大小为 8x8 的块(结果:splittedImage)
- 对来自 splittedImage 的矩阵执行 forwardDCT(结果:dctImage)。
- 对来自 dctImage 的矩阵执行量化(结果:quantizedImage)
在这里我不知道该怎么办。我可以:
- 将 quantizedImage 矩阵合并为一个矩阵 margedImage,将其转换为 Vector 并执行 compressImage 方法。
- 或者将小矩阵从quantizedImage转换成Vector,对它们执行compressImage方法,然后将它们拼接成一个矩阵
所以,这里我得到了红色、绿色和蓝色的 3 个矩阵。然后我将这些矩阵转换为一个 RGB 矩阵并创建新的 BufferedImage 并使用方法 setRGB 来设置像素值。然后执行将图像保存到文件。
补充问题:
- 将 RGB 转换为 YCbCr 并对 Y、Cb 和 Cr 进行 DCT 是否更好?
- compressImage 方法的 Javadoc 说它不是 Huffman 编码,而是 Run-Length 编码。那么压缩后的图像会被图像查看器打开吗?或者我应该根据JPEG规范使用Huffman Encoding,Java中有没有开源的Huffman Encoding实现?
【问题讨论】:
-
这两个问题的答案是:你必须按照标准所说的去做。您不能只是做出任意决定并期望解码器能够处理结果。
-
您的问题与 DCT 无关,而是与 JPEG 压缩有关,因此可能需要对标题进行一些重新标记和轻微更改,以便可以帮助的人实际看到问题的含义。 ..
-
int rgb = bufferedImage.getRGB(i, j);不要这样做,这很慢。获取图像的支持 byte[] 或 int[] 并使用它。
-
3 通道 JPEG 标准使用 Y Cb Cr,经常抽取色度通道以减少数据量。亮度与色度没有强耦合,因此当您优化分离的两个时,您可以获得更好的压缩。
-
@arhimed,我也是图像处理的新手,我很想知道您是如何使用 DCT 实现它的。您能否分享您尝试过的示例,以便对您有所帮助。
标签: java algorithm image-processing jpeg dct