有损压缩方法:uint16 到 uint8?

问题描述 投票:0回答:1

我正在寻找有关有损数据压缩方法的建议。我需要将

uint16
压缩为
uint8
,以便分辨率损失随着
uint16
值的增加而增加。我目前正在使用以下内容:

def log2_compress(x: np.uint16) -> np.uint8:
    # Add l to avoid log2(0)
    y = math.log2(x + 1)
    # log2(1) = 0.
    # log2(65536) = 16.
    # Scale from [0,16] to [0,255].
    return np.uint8((y / 16) * 255)

这很简单,但有一个缺点,那就是在

uint8
方面很浪费,即

log2_compress(0) = 0
log2_compress(1) = 15
log2_compress(2) = 25

所以不使用

[1,14]
[16,24]
等。有人可以建议一种类似于
log2_compress
但使用更多(全部?)
uint8
位的方法吗?我也不太关心性能。

python algorithm compression
1个回答
0
投票

取决于你的意思

分辨率损失随着

uint16
的增加而增加 价值观

您可能想尝试不同的压缩功能。如果没有有关上下文的任何进一步信息,我们将假设您正在寻找递增的凹函数来将 [0~65535] 映射到 [0~255]。

您可以先尝试一下该功能

sqrt
:

def sqrt_compress(x: np.uint16) -> np.uint8:
    return np.uint8(math.sqrt(x))

如果这个函数的平滑度不完全符合您的需要,您可以尝试其他幂而不是平方根的 1/2。您可以添加功率作为参数

p
,这将影响压缩函数的平滑度:

def power_compress_p(x: np.uint16, p: float = 2) -> np.uint8:
    """Compression function. Higher value of p use less bits."""
    return np.uint8(2 ** (8 - 16 / p) * x ** (1 / p))

对于您的用例,请使用

p > 1

幂函数显然不是唯一存在的压缩,如果您想更好地控制粒度,您可以使用字典来定义映射函数。

© www.soinside.com 2019 - 2024. All rights reserved.