我目前正在开发一个项目来控制连接到连接到 Windows PC 的 Teensy 3.2 板的 LED 灯条。它在技术上基于这个项目: https ://www.pjrc.com/teensy/td_libs_OctoWS2811.html
在 vvvv 中还实现了一个项目: https ://vvvv.org/contribution/realtime-led-control-with-teensy3.xoctows2811
到目前为止,两者都工作正常。我想要做的是将movie2serial 程序(关于pjrc.com 上的项目)移植到Python。
所以我找到了这个项目: https ://github.com/agwn/movie2serial_py
它不是开箱即用的,但经过一些修改,我让它运行起来。这是我接收图像,将其转换为字节数组并将其发送到串行端口的类的代码:
import serial
import numpy as np
class Teensy:
def __init__(self, port='COM3', baudrate=115200, stripes=4, leds=180):
self.stripes = stripes
self.leds = leds
self.connected = True
try:
self.port = serial.Serial(port, baudrate)
except:
self.connected = False
def close(self):
if not self.connected:
return
self.black_out()
self.port.close()
def send(self, image):
data = list(self.image2data(image))
data.insert(0, 0x00)
data.insert(0, 0x00)
data.insert(0, ord('*'))
if not self.connected:
return
self.port.write(''.join(chr(b) for b in data).encode())
def black_out(self):
self.send(np.zeros((self.leds,self.stripes,3), np.uint8))
def image2data(self, image):
buffer = np.zeros((8*self.leds*3), np.uint8)
byte_count = 0
order = [1,2,0]
for led in range(self.leds):
for channel in range(3):
for bit in range(8):
bits_out = 0
for pin in range(self.stripes):
if 0x80 >> bit & image[led,pin,order[channel]]:
bits_out |= 1 << pin
buffer[byte_count] = bits_out
byte_count += 1
return buffer
它正在工作,但速度很慢(我的电脑上大约 13 FPS)。
解释代码:我正在使用 cv2 创建一个简单的动画并将图像(具有 4 x 180 像素的 numpy ndarray,因为我有 4 个 LED 条带,每个 LED 条有 180 个 LED)发送到 Teensy 实例的发送方法。send 方法将图像发送到 image2data 方法以将图像转换为字节数组,在开头放置几个字节并将整个内容发送给 Teensy。
这段代码有两个瓶颈:
- 写入串行端口(方法 send 中的 self.port.write)。也许它无法加速,这是可以接受的。
但更重要的是:
访问图像数组(方法 image2data 中的 image[led,pin,order[channel]])。当我将行更改为例如:
如果 0x80 >> 位 & 255:
代码运行速度快 6-7 倍(~ 80 FPS)。顺便说一句,order[channel] 用于将颜色从 BGR 转换为 GRB。
长话短说:从图像数组中读取颜色非常慢。如何在 image2data 方法中加快将图像数组转换为字节数组的速度?
说到这里,感谢您的耐心等待 :-) 很抱歉这篇文章很长,但这是一个复杂的项目,对我来说不容易解释。我非常感谢您的帮助,也许其他人可以从中受益。
提前致谢, 艾尔