使用for循环从OpenCV图像数组提取RGB数据速度过慢问题咨询
性能瓶颈根源
- 最大的性能消耗来自两层Python原生for循环逐像素遍历:Python的循环本身开销极高,加上每次循环的函数调用、列表extend操作,处理数万像素自然耗时极长,这才是你代码慢的核心原因,和
_color16本身的计算逻辑关系不大。 - 你之前用
flatten处理24位RGB速度快,本质是用了numpy的底层C实现的向量化操作,完全规避了Python层面的循环,16位色的转换也可以用同样的思路实现。
全numpy向量化实现方案
全程无Python循环,所有计算都在numpy底层完成,速度和你之前用flatten的效果相当:
import numpy as np import cv2 as cv # 配置项 rgb = True image_path = "你的图片路径" image = cv.imread(image_path) # 拆分三个通道(OpenCV默认读取为BGR顺序) b, g, r = np.moveaxis(image, -1, 0) if rgb: # RGB565格式:R占5位,G占6位,B占5位 rgb565 = ((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3) else: # BGR565格式:B占5位,G占6位,R占5位 rgb565 = ((b & 0xF8) << 8) | ((g & 0xFC) << 3) | (r >> 3) # 转换为大端字节序后拆分为单字节数组,直接得到和你原代码frame完全一致的结果 frame = rgb565.astype('>u2').view('u1').flatten().tolist() print(len(frame))
补充说明
- 原代码存在一处逻辑隐患:
image.shape返回顺序是(高度, 宽度, 通道数),你把l[0]赋值给lx(x方向长度)、l[1]赋值给ly(y方向长度)是写反的,只是因为你用的是正方形图片才没有触发越界错误,非正方形图片会直接报错。 - 如果你不需要转成Python列表,直接用
rgb565.astype('>u2').view('u1')得到的numpy数组就可以直接用于SPI传输,不需要转list还能再快一截。
内容的提问来源于stack exchange,提问作者pmf71
相关产品推荐
相关产品推荐

