我目前正在尝试将视频数据传送到激光器(我们使用激光器进行通信)。激光通过调制工作,我们总共有两种状态,相当于0和1。因此,为了给激光器提供视频数据,我首先需要将其转换为比特。我从openCV的网络摄像头中获取的帧由2D数组表示,该数组包含8位整数以获得灰度图像。目前,我正在对这些阵列进行如下转换:
if __name__ == '__main__':
video = Video()
frame = video.getFrameBits()
其中,视频类定义为:
class Video:
# scale_percent: percent of original size of frame
def __init__(self, scale_percent=100):
self.cap = cv2.VideoCapture(0)
# Get one frame to figure out sizing constraints
_, frame = self.cap.read()
width = int(frame.shape[1] * scale_percent / 100)
height = int(frame.shape[0] * scale_percent / 100)
self.dim = (width, height)
# color: If true show color frames. Not yet implemented
def getFrame(self, color=False):
_, frame = self.cap.read()
frame = cv2.resize(frame, self.dim, interpolation=cv2.INTER_AREA)
if not color:
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
return gray
def getFrameBits(self):
frame = self.getFrame()
for row in frame:
for pixel in row:
frame_bits.append(intToBits(pixel))
return frame_bits
整数到位的功能如下:
def intToBits(x):
send = str(bin(x).lstrip('0b'))
send = send.zfill(8)
return send
我之所以使用intToBits函数,是因为我希望能够获取我称之为frame
的数组,并将其直接送入激光器。在当前实现中,前导零不会从数组中截断。所以我得到了如下输出:
[10010101,10010100,10010101,10010111,10010110,10010101,10010100,10010001,10010001,01011000,...]
这整段代码的问题是,它在我现有的微控制器上运行太慢。只需要5秒钟就可以得到一帧,这相当糟糕。我的第一个想法是去掉getFrameBits中的嵌套for循环,如下所示:
frame_bits = [intToBits(pixel) for row in frame for pixel in row]
这确实缩短了时间,但我想看看是否可以进一步改进。我们仍然需要大约1秒的时间来获得帧,这是更好的,但我们期望更大的采样率
我的下一个想法是用C编写代码并用Python运行,但我对C不太熟悉。因此,虽然我愿意这样做,但我想确保这是正确的方向
还有其他方法可以优化此代码吗
谢谢
一点位屏蔽就可以了:
再加上一点矢量化——如果numpy的内置代码已经是用C编写的,那么就不需要编写C代码了
为了完整性起见,探查器的结果是:
如您所见,即使生成数据也比切换到按位表示要花费更多的时间。虽然您需要对其进行一些修改以适应您的代码,因为输出格式有点不同-一个大数组而不是一个数组数组-但这应该是值得的
相关问题 更多 >
编程相关推荐