如何在NumPy中快速实现两数组合位右滚?台达HMI图像转换优化
快速实现台达HMI特殊像素格式转换
核心思路
利用NumPy向量化位运算替代逐像素循环或unpackbits/packbits操作,直接在16位整数层面完成格式转换与循环移位,最大化运算效率。
转换逻辑拆解
目标格式的核心步骤:
- 从RGB888中提取有效位:B取高5位,R取高5位,G取高4位
- 组合为16位中间值:
[B5(5位), R5(5位), G4(4位), 00(2位)] - 对16位值循环右移2位(低2位移至最高2位)
优化代码实现
from PIL import Image import numpy as np def convert_bmp_to_delta_hmi(img_path): # 读取BMP并转为RGB格式的NumPy数组 img = Image.open(img_path).convert('RGB') img_np = np.array(img, dtype=np.uint8) # 形状为 (高度, 宽度, 3) # 拆分RGB通道 R, G, B = img_np[..., 0], img_np[..., 1], img_np[..., 2] # 提取各通道有效位并转为16位整数 b5 = (B >> 3).astype(np.uint16) # B的高5位(0~31) r5 = (R >> 3).astype(np.uint16) # R的高5位(0~31) g4 = (G >> 4).astype(np.uint16) # G的高4位(0~15) # 组合为16位中间像素值 pixel_16 = (b5 << 11) | (r5 << 6) | g4 # 循环右移2位:低2位移到高2位 final_pixel = (pixel_16 >> 2) | ((pixel_16 & 0x03) << 14) # 转换为字节流(根据HMI要求调整字节序,默认小端,大端则用byteswap()) byte_data = final_pixel.view(np.uint8) # 若需大端格式,替换为:byte_data = final_pixel.byteswap().view(np.uint8) return byte_data.tobytes()
效率说明
- 所有运算均为NumPy底层实现的向量化操作,避免Python循环的开销
- 跳过
unpackbits/packbits带来的数组膨胀(这类操作会将单字节拆为8个布尔值,数组规模扩大8倍,大幅降低速度) - 测试600×250像素图像,转换耗时可降至几十毫秒级别
内容的提问来源于stack exchange,提问作者0livaw
相关产品推荐
相关产品推荐

