我的目标是从RPi(服务器)向客户机发送图像和数据字符串。我使用send_json(data)
,其中数据是dict {'img': img_ls, 'telemetry':'0.01, 320, -10'}
。img_ls
是转换为列表的图像。问题是我得到了len( img_ls ) = 57556
,而原始图像的大小是:320x240=76800。我不明白为什么会有差异。代码如下:
context = zmq.Context()
socket = context.socket(zmq.PUB)
socket.bind("tcp://0.0.0.0:5557")
def outputs():
stream = io.BytesIO()
while True:
yield stream
stream.seek(0)
sensors = '0.01, 320, -10'
img_ls = np.fromstring(stream.getvalue(), dtype=np.uint8).tolist()
data = {'telemetry': sensors, 'img': img_ls}
socket.send_json(data)
stream.seek(0)
stream.truncate()
with picamera.PiCamera() as camera:
camera.resolution = (320, 240)
camera.framerate = 80
time.sleep(2)
camera.capture_sequence(outputs(), 'jpeg', use_video_port=True)
最后一点:这是我尝试将图像和传感器数据从RPi同步传输到客户端。我担心数组和列表转换(在RPi端完成)可能会减慢流式处理的速度。如果有更好的方法(仍然)使用zmq
,请告诉我。在
图像处理是CPU昂贵的。所以,表演第一:
ZeroMQ应允许一个人享受零拷贝的操作方式,以防止任何破坏这一点的不利操作。在
由于只使用了一个通用的OpenCV相机,而不是RPi/PiCamera,我总是喜欢在一个受控事件循环下,在采集端采集单独的相机帧(而不是序列)。在
相机获得一个已知的、固定的几何图形(在opencva
numpy.ndarray
3D结构[X,Y,[B,G,R]]),因此最快和最直接的序列化是在发送方使用struct.pack( CONST_FRAME_STRUCT_MASK, aFrame )
,在接收方使用struct.unpack( CONST_FRAME_STRUCT_MASK, aMessage )
。在是的,
struct.pack()
是迄今为止最快的方法,即使文档提供了其他方法(灵活性需要额外的成本,这是不合理的):任何颜色转换和类似的源端转换都可能消耗+150~180[ms],因此请尽量避免任何和所有不必要的颜色空间或重塑或类似的非核心转换,因为这些会对累积的管道延迟包络造成不利影响。在
使用
struct.pack()
还可以避免任何类型的大小不匹配,因此加载到二进制有效载荷着陆台上的内容正是接收端接收到的内容。在如果确实希望在消息核心数据周围也有与JSON相关的开销,那么应该设置一个双套接字范式,都有}-有效负载,第二个JSON修饰的遥测。在
ZMQ_CONFLATE == 1
,其中第一个移动{如果RPi允许,}映射可以分离/分配工作负载,使每个工作负载都在不同的、独立的
zmq.Context( nIOthreads )
可以使用nIOthreads >= 2
进一步增加两边的数据泵送吞吐量,并且附加的{IOthread
上运行。在查看下面的代码。我使用了Nlohmann json和一些小的调整(来自各种来源)来发送图像、vetor、string等。
客户代码
服务器代码
^{2}$应该包括nlohmann git的include包。或者yoy可以直接从:https://github.com/zsfVishnu/zmq.git下载源代码和链接。 另外,如果您使用的是g++或任何其他编译器,但不包括nlohmann的include文件夹,只需在CLI ie add-I/include文件夹的路径/
相关问题 更多 >
编程相关推荐