gpt4 book ai didi

java - 尝试压缩图像时出现彩色像素(包括图片)

转载 作者:搜寻专家 更新时间:2023-10-31 20:22:35 24 4
gpt4 key购买 nike

我正在尝试使用奇异值分解来压缩给定图像。我以为我明白了,直到我注意到我在整个过程中不断出现乱七八糟的彩色像素。

Garbage pixels

右上角显示的数字表示迭代次数,其中 0 为原始图像。

这是一个常见错误吗?有什么我想念的吗?

我认为这可能与我的数学本身有关。我正在使用 JAMA,这是一个为我处理这个问题的 java 矩阵包。以下是我对每次迭代的实现:

for (int i = 0; i < k; i++) {    
Matrix step = (uColumns[i].times(sValues[i])).times(vColumns[i].transpose());
encoded = encoded.plus(step);
}

基本上我正在做的(或试图做的)是:

M = M + (s1*u1*v1^t)

我的实现是否有明显的错误,或者错误可能是由于 JAMA 执行 SVD 的方式造成的?根据我的测试,矩阵 U 和 V 中值的符号在某些行中与 Wolframalpha 或 Matlab 生成的值的符号不同。

感谢任何帮助。

谢谢,

贾斯蒂安

最佳答案

这是分解成原色的图片:

Lena SVD decomposed to RGB

显然,您以错误的方式将颜色转换为数字以及将数字转换为颜色。您将 int RGB 像素视为单个数值并通过 SVD 数值过程传递它,但它实际上是 RGB 的信息丢失了。

大多数有损图像压缩方法都是通过丢弃低有效位来实现压缩的。但是当您在单个 int 中包含 RGB 时,每个 R、G 和 B 的低有效位与高有效位交错。当将像素作为单个数值传递时,此信息丢失,并且 SVD 程序有效地将低有效位 R 位解释为比高有效位 G 位更有效,并且可能会尝试完全丢弃所有 G 和 B 位,因为它们存储在 R 位“之后”。

例如,浅灰色像素 (192,192,192) 的 RGB 值为 0xC0C0C0。以 1% 的误差压缩此值会产生例如 0xC2AE32。从压缩算法的角度来看,这个值只比原来大了1%,几乎察觉不到。但是将其转换回 RGB 会得到 (194,174,50)。 R 组件确实几乎相同,但 G 和 B 已损坏。这是您程序中“垃圾颜色”的来源。分解后的图像显示,R分量被正确压缩,G分量在高压缩级别变成随机噪声,B分量始终是随机的。

实现中的另一个问题是分散在黑暗区域中的单个明亮像素。这些显然是由数字溢出和下溢引起的。例如,黑色像素 (0,0,0) 编码为 0x000000 = 0;有损压缩会引入一个小错误,可以是正数也可以是负数,并且可以产生 -1 = 0xFFFFFFFF;在 RGB 中,它变成 (255,255,255),这是白色的。

怎么办?

如果你只是测试SVD图像压缩,使用灰度图像就足够了,那么你应该直接从RGB值中取低字节,范围是0到255。相应地,在显示结果或写入时输出文件,将此值解释为灰度,或乘以 0x010101 以获得完整的 RGB 值。

如果需要压缩彩色图像,应该对 R、G、B 分量分别运行 SVD 算法。这是处理颜色的最简单方法,但不是最有效的方法。为了获得更高的压缩率和不太明显的伪像,最好从 RGB 转换为 Lab(亮度和两个色度 channel );色度可以压缩得更多,这就是 JPEG 的工作方式。

解压缩图像时,在从 SVD 计算值之后但在将它们显示在屏幕上或写入文件之前,将所有结果值(R、G 和 B)限制在 0-255 范围内。这将消除分散的白点。

关于java - 尝试压缩图像时出现彩色像素(包括图片),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9671186/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com