我创建了两个程序来使用ZeroMQ发送和接收视频供稿。但是,接收程序始终卡在.recv()函数上。
我已经为此程序使用了两个ZeroMQ库:一个zmq,一个imagezmq。 imagezmq用于发送和接收来自视频的帧数据,而zmq库用于发送和接收发送图像的时间。
imagezmq部分工作正常。该程序仅卡在zmq部分。
以下是我的两个程序:
FinalCam.py
import struct
import time
import imutils
import imagezmq
import cv2
import zmq
import socket
import pickle
# image sending
sender = imagezmq.ImageSender(connect_to='tcp://localhost:5555')
hostName = socket.gethostname() # send RPi hostname with each image
vid_dir = "/root/redis-opencv-videostream/vtest.avi"
cap = cv2.VideoCapture(vid_dir) # init the camera
#time sending setup
context = zmq.Context()
socket = context.socket(zmq.PUB)
socket.connect("tcp://localhost:6666")
while True: # send images as stream until Ctrl-C
ret, frame = cap.read()
frame = imutils.resize(frame, width=400) # resize without compressionq
captureTime = time.time()
sender.send_image(hostName, frame)
print (captureTime)
captureTime = struct.pack('d', captureTime)
#msg = pickle.dumps(captureTime)
print("message primed")
socket.send(captureTime)
print("time sent")
输出
1591824603.5772414
message primed
time sent
FinalRecieve.py
import cv2
import imagezmq
import time
import zmq
import struct
# image socket
FRAMES = 5
image_hub = imagezmq.ImageHub()
#time socket
context = zmq.Context()
socket = context.socket(zmq.SUB)
socket.bind("tcp://*:6666")
while True: # show streamed images until Ctrl-C
loopTime = time.time()
for i in range (0, FRAMES):
hostName, frame = image_hub.recv_image()
image_hub.send_reply(b'OK')
print("recieved image, waiting for time")
captureTime = socket.recv()
print("meow")
print(captureTime)
finishTime = time.time()
fpsTime = finishTime - loopTime
fps = FRAMES / fpsTime
print(fps)
输出
received image, waiting for time
这里有几件事可以尝试:
对于接收器,使用连接而不是绑定socket.connect("tcp://*:6666")
解释了here in the guide,应使用connect从套接字创建传出连接。在用于绑定的同级文档中,该文档解释为用于接受连接。
也尝试设置套接字选项socket.setsockopt(zmq.SUBSCRIBE, "")
here in the guide描述了子套接字最初会过滤掉所有消息,因此可以解释为什么您什么都没收到。
问题定义:
“ ZeroMQ部分工作正常。程序仅卡在"ZeroMQ: Principles in less than Five Seconds"部分。”
解决方案?
imagezmq
,并且一个AccessPoint可以自由地zmq
一些{ .bind() | .connect() }
其他[.bind()
-.connect()
通信拓扑的通道(根据需要)(换句话说,“倒置的” TransportClass
是不是 [1:N
-spin-off模块。在您的控制范围内有一系列硬连线的选择(并且任何劫持Class-internal属性.bind()/.connect()
ImageZMQ
发布的内部性本身是根据硬编码的选择预先确定的(相同的Class实例,具体取决于模式,有时{ ImageHub.zmq_socket | ImageSender.zmq_socket }
和imagezmq
则声明为有效),让我们集中精力使用它(已发布)最大值。基于上述内容,组成您的工作部分,以便在工作方案内发送时间:
.bind()
并且可以很容易地在.connect()
端进行相应的解码,而无需修复使用的
PAYLOAD_MASK = "{0:}|||{1:}"
...
while ...
sender.send_image( PAYLOAD_MASK.format( time.time(), hostName ),
frame
)
.recv()
中,ZeroMQ互连世界中的情况越多,人们永远不会知道,即远程平台是什么,则字节序(Endian-convention)将被认为是“少”,因此[struct.pack()
应始终在[distributed-computing-中显式声明Endian类型。如果不确定,可以设计一条自我检测的消息,该消息可以挽救这种幼稚的用法,并相应地测试/调整您的struct.pack()
字符串以供您在本地使用format
方法对于任何暗含.pack()-sender ...的情况,都超出了本文的范围,但是所有RPi /非Rpi平台项目都倾向于这种(仅)假定为“相同”的Endian警告) 惊奇:如果使用format
版本18。[[。
.unpack()
方法可用,并且ImageZMQ注定会崩溃。pyzmq