算术解码 算法实现

数字图像处理 冈萨雷斯 第三版 8.18题
在这里插入图片描述一个简单的解题脚本(Python)

import warnings
import numpy as np


def arith_decode(code_map, encoded_num):
    assert 0 < encoded_num < 1, f"encoded_num:{encoded_num} not in (0,1)"

    codes = [''] + list(code_map.keys())
    acc_values = np.cumsum([0.] + list(code_map.values()))

    def init_idxes():
        nonlocal lower_idx, mid_idx, upper_idx
        mid_idx = len(codes) >> 1
        lower_idx = 0
        upper_idx = len(codes) - 1

    lower_idx, mid_idx, upper_idx = 0, 0, 0
    init_idxes()

    decode_idxes = np.empty(0xff, dtype=np.int8)
    # Binary search
    for decode_idx in range(0xff):
        while upper_idx - lower_idx > 1:
            if acc_values[mid_idx] < encoded_num <= acc_values[upper_idx]:
                lower_idx = mid_idx
                mid_idx = (mid_idx + upper_idx) >> 1
            elif acc_values[lower_idx] <= encoded_num <= acc_values[mid_idx]:
                upper_idx = mid_idx
                mid_idx = (mid_idx + lower_idx) >> 1
            else:
                raise RuntimeError(
                    f"encoded_num:{encoded_num} not in ({acc_values[lower_idx]},{acc_values[upper_idx]})")

        decode_idxes[decode_idx] = upper_idx
        if codes[upper_idx] == '!':
            # Reach the end
            decode_idxes = decode_idxes[:decode_idx + 1]
            break

        # Shrink the range
        acc_values = (acc_values - acc_values[0]) / (acc_values[-1] - acc_values[0]) * (
            acc_values[upper_idx] - acc_values[lower_idx]) + acc_values[lower_idx]

        # Check the range
        min_gap = 1e-15 * (len(codes) - 1)
        if acc_values[-1] - acc_values[0] < min_gap:
            warnings.warn(
                f"acc_vec[-1] - acc_vec[0] = {acc_vec[-1] - acc_vec[0]} is smaller than {min_gap}", RuntimeWarning)
            decode_idxes = decode_idxes[:decode_idx + 1]
            break

        init_idxes()

    decode_res = ''.join([codes[idx] for idx in decode_idxes])
    return decode_res


if __name__ == '__main__':
    code_map = {'a': .2, 'e': .3, 'i': .1, 'o': .2, 'u': .1, '!': .1}
    encoded_num = 0.32256

    print(arith_decode(code_map, encoded_num))

运行结果:eeoe!

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值