首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >提高10到8位转换性能

提高10到8位转换性能
EN

Stack Overflow用户
提问于 2018-07-03 18:34:00
回答 2查看 75关注 0票数 2

我有10位数据的灰度图像文件。10位保存在2字节上,低位对齐( 10位值0b10 0000 1111保存为0x020F

我想把它转换成8位,保留最重要的字节。

代码语言:javascript
运行
复制
def convert_10bitTo8Bit(tenBitData):
    output_size = int(len(tenBitData) / 2)
    eightBitData = bytearray(output_size)
    for i in range(output_size):
        lowbyte, highbyte = tenBitData[i * 2 + 1], tenBitData[i * 2]
        value = (highbyte << 8) + lowbyte
        value = (value >> 2) & 0xff
        eightBitData[i] = value
    return eightBitData

这是有效的,但相当慢:对于一个3MB的图像,在我的dev机器上需要大约0.5秒,在打算运行它的设备上需要>8秒(ARM系统,性能类似于PI)。

我试图分析它以找到瓶颈,但cProfile只报告builtins.exec是最耗时的函数。

代码语言:javascript
运行
复制
$ python3 ImageTools.py
     5 function calls in 8.560 seconds

Ordered by: standard name

ncalls  tottime  percall  cumtime  percall filename:lineno(function)
     1    0.000    0.000    8.560    8.560 <string>:1(<module>)
     1    8.559    8.559    8.559    8.559 ImageTools.py:11(convert_10bitTo8Bit)
     1    0.000    0.000    8.560    8.560 {built-in method builtins.exec}
     1    0.000    0.000    0.000    0.000 {built-in method builtins.len}
     1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}

如何提高性能?

EN

回答 2

Stack Overflow用户

发布于 2018-07-03 19:05:27

您可以通过使用numpy对操作进行矢量化来提高性能

代码语言:javascript
运行
复制
# Store byte pairs as columns.
# If `tenBitData` is a `bytes` object, then use `np.fromiter` instead.
>>> data = np.asarray(tenBitData, dtype=np.uint8).reshape(-1, 2)

# Now we apply vectorized conversion.
>>> (data[:, 0] << 6) + (data[:, 1] >> 2)

在我的计算机上测试(4MB数据)时,我得到以下计时:

代码语言:javascript
运行
复制
Conversion: 3.044390e-01s
Function: 1.002173e+00s
Numpy: 7.728000e-03s

因此,尽管numpy速度很快,但转换仍然是一个瓶颈(至少是3倍)。根据数据最初的存储方式,这种转换可能甚至不是必需的。

票数 2
EN

Stack Overflow用户

发布于 2018-07-03 18:59:59

你的函数名与函数的实际功能有一点冲突,但它是可以改进的,这假设你不再关心原始的10位数据。假设你总是有成对的字节,它将适用于任何大小,奇数将抛出错误

代码语言:javascript
运行
复制
def convert_8bitTo10Bit(tenBitData):
    eightBitData = bytearray()
    while tenBitData:
        eightBitData.insert(0,((tenBitData.pop() | (tenBitData.pop() << 8)) >> 2 & 0xFF))
    return eightBitData
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51152402

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档