将 8 位值转换为 4 位值并在 python 中的一个字节中保存 2 个 4 位值的快速且节能的方法
fast and power efficient way to convert 8bit values to 4bit values and save 2 4bit values in one byte in python
我想做一个udp的视频流程序,用opencv,我想通过将255色值转换成16色值来进行压缩,因为这样可以节省一半的流量,而且质量还不错。我知道如何将 255 个值转换为 16 个值:
opencvimg = numpy.multiply(opencvimg//16,16)
但我不知道将两个值放入 1 个字节以节省流量的有效方法。它必须是高效的,因为我希望它在 rpi 上达到 运行(github 上的完整代码。com/Open-ATS-Github)。
我想你是这个意思:
import numpy as np
# Make synthetic data
x = np.arange(256, dtype=np.uint8)
# Take pairs of elements shifted by 4 bits and OR together
d2by4 = (x[::2] & 0xf0) | (x[1::2] >> 4)
In [16]: d2by4.dtype
Out[16]: dtype('uint8')
In [21]: d2by4
Out[21]:
array([ 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 17, 17, 17,
17, 17, 17, 34, 34, 34, 34, 34, 34, 34, 34, 51, 51,
51, 51, 51, 51, 51, 51, 68, 68, 68, 68, 68, 68, 68,
68, 85, 85, 85, 85, 85, 85, 85, 85, 102, 102, 102, 102,
102, 102, 102, 102, 119, 119, 119, 119, 119, 119, 119, 119, 136,
136, 136, 136, 136, 136, 136, 136, 153, 153, 153, 153, 153, 153,
153, 153, 170, 170, 170, 170, 170, 170, 170, 170, 187, 187, 187,
187, 187, 187, 187, 187, 204, 204, 204, 204, 204, 204, 204, 204,
221, 221, 221, 221, 221, 221, 221, 221, 238, 238, 238, 238, 238,
238, 238, 238, 255, 255, 255, 255, 255, 255, 255, 255], dtype=uint8)
也就是说... "从第一个元素开始,取 x
的每个第二个元素的高半字节,然后将它与每秒向右移动 4 位的高半字节进行或运算x
的元素从第二个开始。"
有一个不涉及显式算法的解决方案:您可以构建一个完整的 lookup-table 256 x 256 条目,给出一对输入字节的打包结果。
如果这样的 table 看起来大得不合理,请认为您正在处理更大的图像。
使用平面向量还是使用矩阵更好,缓存效应是否会毁了工作,这是一个实验问题。
我想做一个udp的视频流程序,用opencv,我想通过将255色值转换成16色值来进行压缩,因为这样可以节省一半的流量,而且质量还不错。我知道如何将 255 个值转换为 16 个值:
opencvimg = numpy.multiply(opencvimg//16,16)
但我不知道将两个值放入 1 个字节以节省流量的有效方法。它必须是高效的,因为我希望它在 rpi 上达到 运行(github 上的完整代码。com/Open-ATS-Github)。
我想你是这个意思:
import numpy as np
# Make synthetic data
x = np.arange(256, dtype=np.uint8)
# Take pairs of elements shifted by 4 bits and OR together
d2by4 = (x[::2] & 0xf0) | (x[1::2] >> 4)
In [16]: d2by4.dtype
Out[16]: dtype('uint8')
In [21]: d2by4
Out[21]:
array([ 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 17, 17, 17,
17, 17, 17, 34, 34, 34, 34, 34, 34, 34, 34, 51, 51,
51, 51, 51, 51, 51, 51, 68, 68, 68, 68, 68, 68, 68,
68, 85, 85, 85, 85, 85, 85, 85, 85, 102, 102, 102, 102,
102, 102, 102, 102, 119, 119, 119, 119, 119, 119, 119, 119, 136,
136, 136, 136, 136, 136, 136, 136, 153, 153, 153, 153, 153, 153,
153, 153, 170, 170, 170, 170, 170, 170, 170, 170, 187, 187, 187,
187, 187, 187, 187, 187, 204, 204, 204, 204, 204, 204, 204, 204,
221, 221, 221, 221, 221, 221, 221, 221, 238, 238, 238, 238, 238,
238, 238, 238, 255, 255, 255, 255, 255, 255, 255, 255], dtype=uint8)
也就是说... "从第一个元素开始,取 x
的每个第二个元素的高半字节,然后将它与每秒向右移动 4 位的高半字节进行或运算x
的元素从第二个开始。"
有一个不涉及显式算法的解决方案:您可以构建一个完整的 lookup-table 256 x 256 条目,给出一对输入字节的打包结果。
如果这样的 table 看起来大得不合理,请认为您正在处理更大的图像。
使用平面向量还是使用矩阵更好,缓存效应是否会毁了工作,这是一个实验问题。