Last active
November 2, 2023 10:43
-
-
Save JarbasAl/317d8a3fb262efa639745ccc77bb0c3e to your computer and use it in GitHub Desktop.
zmq2mjpeg
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| from time import sleep | |
| import imagezmq | |
| import zmq # needed because we will be using zmq socket options & exceptions | |
| from imutils.video import VideoStream | |
| time_between_restarts = 5 # number of seconds to sleep between sender restarts | |
| def sender_start(connect_to=None): | |
| sender = imagezmq.ImageSender(connect_to=connect_to) | |
| sender.zmq_socket.setsockopt(zmq.LINGER, 0) # prevents ZMQ hang on exit | |
| # NOTE: because of the way PyZMQ and imageZMQ are implemented, the | |
| # timeout values specified must be integer constants, not variables. | |
| # The timeout value is in milliseconds, e.g., 2000 = 2 seconds. | |
| sender.zmq_socket.setsockopt(zmq.RCVTIMEO, 2000) # set a receive timeout | |
| sender.zmq_socket.setsockopt(zmq.SNDTIMEO, 2000) # set a send timeout | |
| return sender | |
| connect_to = 'tcp://0.0.0.0:5555' # replace ip with the zmq2mjpeg host ip | |
| sender = sender_start(connect_to) | |
| rpi_name = "my_OVOS_camera" # some unique device name here | |
| picam = VideoStream().start() | |
| try: | |
| while True: # send images as stream until Ctrl-C | |
| image = picam.read() | |
| try: | |
| reply_from_mac = sender.send_image(rpi_name, image) | |
| except (zmq.ZMQError, zmq.ContextTerminated, zmq.Again): | |
| if 'sender' in locals(): | |
| print('Closing ImageSender.') | |
| sender.close() | |
| sleep(time_between_restarts) | |
| print('Restarting ImageSender.') | |
| sender = sender_start(connect_to) | |
| except (KeyboardInterrupt, SystemExit): | |
| pass # Ctrl-C was pressed to end program | |
| except Exception as ex: | |
| print('Python error with no Exception handler:') | |
| print('Traceback error:', ex) | |
| finally: | |
| if 'sender' in locals(): | |
| sender.close() | |
| picam.stop() # stop the camera thread |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| imutils | |
| opencv_python | |
| imagezmq |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| from threading import Thread | |
| import cv2 | |
| import imagezmq | |
| from flask import Flask, Response | |
| app = Flask(__name__) | |
| class CamReader(Thread): | |
| image_hub = imagezmq.ImageHub() | |
| last_frames = {} | |
| def run(self) -> None: | |
| while True: | |
| rpi_name, frame = self.image_hub.recv_image() | |
| # print(rpi_name, len(frame)) | |
| self.last_frames[rpi_name] = frame | |
| self.image_hub.send_reply(b'OK') | |
| def get(self, name): | |
| return self.last_frames.get(name) | |
| image_hub = CamReader(daemon=True) | |
| image_hub.start() | |
| def gen_frames(target_name): # generate frame by frame from camera | |
| while True: | |
| frame = image_hub.get(target_name) | |
| if frame is None: | |
| continue | |
| try: | |
| ret, jpeg = cv2.imencode('.jpg', frame) | |
| yield (b'--frame\r\n' | |
| b'Content-Type: image/jpeg\r\n\r\n' + jpeg.tobytes() + b'\r\n') | |
| except Exception as e: | |
| pass | |
| @app.route('/video_feed/<name>') | |
| def video_feed(name): | |
| return Response(gen_frames(name), mimetype='multipart/x-mixed-replace; boundary=frame') | |
| if __name__ == '__main__': | |
| app.run(host="0.0.0.0") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment