jeffbass / imagezmq

A set of Python classes that transport OpenCV images from one computer to another using PyZMQ messaging.
MIT License
1.01k stars 160 forks source link

Fails when run inside a class #6

Closed AnoRebel closed 5 years ago

AnoRebel commented 5 years ago

Hi, this is abit of an emergency, so, when I run it in a normal way(like the example in the README), it runs fine, but whenever I put it inside a class, it runs once for a second-ish and crashes, with this error:

Traceback (most recent call last): File "cserver.py", line 16, in <module> Cserver() File "cserver.py", line 6, in __init__ self.stream() File "cserver.py", line 11, in stream pi_nem, image = image_hub.recv_image() File "/home/user/Desktop/imagezmq.py", line 119, in recv_image msg, image = self.zmq_socket.recv_array(copy=False) File "/home/user/Desktop/imagezmq.py", line 216, in recv_array md = self.recv_json(flags=flags) File "/usr/local/lib/python3.6/dist-packages/zmq/sugar/socket.py", line 668, in recv_json msg = self.recv(flags) File "zmq/backend/cython/socket.pyx", line 788, in zmq.backend.cython.socket.Socket.recv File "zmq/backend/cython/socket.pyx", line 824, in zmq.backend.cython.socket.Socket.recv File "zmq/backend/cython/socket.pyx", line 191, in zmq.backend.cython.socket._recv_copy File "zmq/backend/cython/socket.pyx", line 186, in zmq.backend.cython.socket._recv_copy File "zmq/backend/cython/checkrc.pxd", line 25, in zmq.backend.cython.checkrc._check_rc zmq.error.ZMQError: Operation cannot be accomplished in current state

My code is:

import cv2 import imagezmq class Cserver: def init(self): self.stream() def stream(self): image_hub = imagezmq.ImageHub() while True: pi_nem, image = image_hub.recv_image() cv2.imshow(pi_nem, image) cv2.waitKey(1) if name == "main": Cserver()

I would appreciate any help you can provide as soon as possible

jeffbass commented 5 years ago

It looks to me like you left out the "send_reply" statement after the cv2.waitKey(1) statement. It should be:

# your code snippet below shows the statement I think needs to be added.
while True:
    pi_nem, image = image_hub.recv_image()
    cv2.imshow(pi_nem, image)
    cv2.waitKey(1)
    image_hub.send_reply(b'OK')  # this statement is missing from your while True loop

Try adding that last statement and let me know what happens.

AnoRebel commented 5 years ago

It looks to me like you left out the "send_reply" statement after the cv2.waitKey(1) statement. It should be:

# your code snippet below shows the statement I think needs to be added.
while True:
    pi_nem, image = image_hub.recv_image()
    cv2.imshow(pi_nem, image)
    cv2.waitKey(1)
    image_hub.send_reply(b'OK')  # this statement is missing from your while True loop

Try adding that last statement and let me know what happens.

Wow, it worked in the local machine, I'll test it in the Pi too and see if it works, but so far, looks like it will.. Thanks for the quick reply, quite a save.. Side question, whats the significance of the statement, what does it change to make it run inside a class but not outside.?

jeffbass commented 5 years ago

As far as I know, the "send_reply" function call is required in every hub program that uses imagezmq. The imagezmq library uses the imagezmq Request-Reply (REQ-REP) pattern of ZMQ. That pattern requires a specific sequence for every communication between client and server:

# ImageSender Client sends (text, image) pair message
#                 # ImageHub Server sends b'OK'
# ImageSender Client sends (text, image) pair message
#                 # ImageHub Server sends b'OK'

...etc. This pattern repeats forever. The "send_reply" is required every time in the REQ-REP messaging sequence. The server can send any message; it does not have to send only the message b'OK'. In my evolving versions of imagehub, the ImageHub Server sends messages such as b'Restart' to restart the ImageSender Client when changing the imagenode client. You can read more about the ZMQ Request-Reply pattern here: http://zguide.zeromq.org/page:all#Ask-and-Ye-Shall-Receive.

AnoRebel commented 5 years ago

Thank you jeffbass, just tested on the pi and it works too.. I'm gonna close the issue now. Thanks for the explanation too, good work with this, you should think about packaging it, a real life saver..