Outils pour utilisateurs

Outils du site


streaming_over_network_with_opencv_et_zeromq

Différences

Ci-dessous, les différences entre deux révisions de la page.

Lien vers cette vue comparative

Les deux révisions précédentesRévision précédente
Prochaine révision
Révision précédente
Dernière révisionLes deux révisions suivantes
streaming_over_network_with_opencv_et_zeromq [2022/02/19 08:32] – [imageZMQ: Transporting OpenCV images] sergestreaming_over_network_with_opencv_et_zeromq [2022/02/25 13:15] – [Profondeur d'une RealSense D455] serge
Ligne 6: Ligne 6:
 </WRAP> </WRAP>
  
- +**Pas de latence, peu ce consommation CPU, en python super facile à implémenter**\\ 
- +**mais pas de réception dans VLC et Pure Data.**\\ 
 +Utiliser **[[streamer_des_images_opencv_avec_v4l2-loopback|Streamer des images OpenCV avec v4l2-loopback]]**
 =====ZeroMQ===== =====ZeroMQ=====
 **[[https://zeromq.org/|zeromq.org]]** (également écrit ØMQ, 0MQ ou ZMQ) est une bibliothèque de messagerie asynchrone haute performance **[[https://zeromq.org/|zeromq.org]]** (également écrit ØMQ, 0MQ ou ZMQ) est une bibliothèque de messagerie asynchrone haute performance
- 
   * https://fr.wikipedia.org/wiki/ZeroMQ   * https://fr.wikipedia.org/wiki/ZeroMQ
   * https://en.wikipedia.org/wiki/ZeroMQ   * https://en.wikipedia.org/wiki/ZeroMQ
- 
- 
- 
- 
-  * [[https://github.com/jeffbass/imagezmq|Transporting OpenCV images]] 
- 
- 
  
 =====Ressources===== =====Ressources=====
-  * **[[https://pyimagesearch.com/2019/04/15/live-video-streaming-over-network-with-opencv-and-imagezmq/|Live video streaming over network with OpenCV and ImageZMQ]]** L'utilisation de FFMPEG ou GStreamer est définitivement une option. Mais les deux peuvent être une douleur royale à travailler. Aujourd'hui, je vais vous montrer ma solution préférée en utilisant les bibliothèques de transmission de messages , en particulier ZMQ et ImageZMQ, cette dernière ayant été développée par le conférencier PyImageConf 2018, Jeff Bass. Jeff a mis une tonne de travail dans ImageZMQ et ses efforts se voient vraiment.+  * **[[https://pyimagesearch.com/2019/04/15/live-video-streaming-over-network-with-opencv-and-imagezmq/|Live video streaming over network with OpenCV and ImageZMQ]]** FFMPEG ou GStreamer sont des options, mais c'est galère à implémenter.
   * **[[https://stackoverflow.com/questions/43817161/how-to-send-opencv-video-footage-over-zeromq-sockets|How to send OpenCV video footage over ZeroMQ sockets?]]** sur stackoverflow.com   * **[[https://stackoverflow.com/questions/43817161/how-to-send-opencv-video-footage-over-zeromq-sockets|How to send OpenCV video footage over ZeroMQ sockets?]]** sur stackoverflow.com
   * https://zeromq.org/languages/python/   * https://zeromq.org/languages/python/
 +  * [[https://github.com/jeffbass/imagezmq|Transporting OpenCV images]]
  
-=====Installation=====+=====Implémentation dans Pure Data===== 
 +  * https://github.com/sansculotte/pd-zmq 
 + 
 +====Installation de puredata==== 
 +  sudo apt install multimedia-puredata libzmq3-dev 
 +   
 +====Compilation du patch zmq==== 
 +  git clone git@github.com:sansculotte/pd-zmq.git 
 +  cd pd-zmq 
 +  make 
 +   
 +====Utilisation des scripts fournis==== 
 +Ça envoie et reçoit des int/string, mais pas d'images !\\ 
 +Extrait de https://github.com/sansculotte/pd-zmq/blob/master/TODO\\ 
 +<code> 
 +LATER 
 +* proper architecture workflows 
 +** multiconnects/multicast (pgm?) 
 +* complex objects 
 +** [zmf_router] -- [broker] as abstraction? 
 +** [zmf_dealer] -/ 
 +** [zmf_pair] 
 +* implement streams to send audio blocks 
 +** binary modes 
 +* send/receive modes 
 +** binary (for audio/video frames) 
 +** string (for communication w external programs) 
 +</code> 
 +Le paquet de la première image est reçu, mais il ne passe passe rien ensuite ... 
 +=====Installation du module python=====
 Dans un environnement virtuel python (3.9) Dans un environnement virtuel python (3.9)
  
Ligne 48: Ligne 70:
 </code> </code>
  
-=====Exemples simples=====+====Lancement d'un script==== 
 + 
 +  cd /le/dossier/de/votre/projet 
 +  ./mon_env/bin/python3 sender_cam.py  # sender_cam.py est le script ci_dessous 
 +   
 +====Sender avec python et receive dans pd==== 
 + 
 +Bon, là je suis nul en pd ! 
 +=====Exemples===== 
 +  * Exemples inspirés de: https://github.com/jeffbass/imagezmq/tree/master/examples
 ====Caméra==== ====Caméra====
 Le principe est simple, sender envoie "image", c'est une image en np.array\\ Le principe est simple, sender envoie "image", c'est une image en np.array\\
-Cet array peut être définit par ce que vous voulez.+Cet array peut être définit par ce que vous voulez.\\ 
 + 
 +Les exemples utilisent souvent imutils, qui est une surcouche en python sur OpenCV, et qui a quelques bugs. On peut s'en passer facilement, il suffit de lire la doc OpenCV, par exemple pour retailler les images, les convertir en jpg etc ...
  
 <file python sender_cam.py> <file python sender_cam.py>
Ligne 59: Ligne 92:
  
 sender = imagezmq.ImageSender(connect_to='tcp://127.0.0.1:5555') sender = imagezmq.ImageSender(connect_to='tcp://127.0.0.1:5555')
- 
 my_name = "moi" my_name = "moi"
 cap = cv2.VideoCapture(2) cap = cv2.VideoCapture(2)
 time.sleep(2.0) time.sleep(2.0)
- 
 while 1: while 1:
     # image peut venir de n'importe quoi !     # image peut venir de n'importe quoi !
     # ici, c'est pour une caméra     # ici, c'est pour une caméra
     ret, image = cap.read()     ret, image = cap.read()
-     
     if ret:     if ret:
         cv2.imshow("moi", image)         cv2.imshow("moi", image)
         sender.send_image(my_name, image)         sender.send_image(my_name, image)
         print("send:", image.shape)         print("send:", image.shape)
- 
     if cv2.waitKey(10) == 27:     if cv2.waitKey(10) == 27:
         break         break
Ligne 83: Ligne 112:
  
 image_hub = imagezmq.ImageHub() image_hub = imagezmq.ImageHub()
- 
 while 1: while 1:
     your_name, image = image_hub.recv_image()     your_name, image = image_hub.recv_image()
     print(your_name, image.shape)     print(your_name, image.shape)
- 
     cv2.imshow(your_name, image)     cv2.imshow(your_name, image)
     image_hub.send_reply(b'OK')     image_hub.send_reply(b'OK')
- 
     if cv2.waitKey(10) == 27:     if cv2.waitKey(10) == 27:
         break         break
 </file> </file>
  
 +====Profondeur d'une OAK-D Lite====
 +<code bash>
 +cd /le/dossier/de/votre/projet
 +source mon_env/bin/activate
 +python3 -m pip install depthai numpy
 +</code>
  
 +<file python sender_oak_depth.py>
 +import time
 +import imagezmq
 +import cv2
 +import depthai as dai
 +import numpy as np
  
 +sender = imagezmq.ImageSender(connect_to='tcp://127.0.0.1:5555')
 +time.sleep(2.0)
  
 +pipeline = dai.Pipeline()
 +# Define a source - two mono (grayscale) cameras
 +left = pipeline.createMonoCamera()
 +left.setResolution(dai.MonoCameraProperties.SensorResolution.THE_400_P)
 +left.setBoardSocket(dai.CameraBoardSocket.LEFT)
 +right = pipeline.createMonoCamera()
 +right.setResolution(dai.MonoCameraProperties.SensorResolution.THE_400_P)
 +right.setBoardSocket(dai.CameraBoardSocket.RIGHT)
 +# Create a node that will produce the depth map (using disparity output as it's easier to visualize depth this way)
 +depth = pipeline.createStereoDepth()
 +depth.setConfidenceThreshold(200)
  
 +# Options: MEDIAN_OFF, KERNEL_3x3, KERNEL_5x5, KERNEL_7x7 (default)
 +median = dai.StereoDepthProperties.MedianFilter.KERNEL_7x7 # For depth filtering
 +depth.setMedianFilter(median)
  
 +# Better handling for occlusions:
 +depth.setLeftRightCheck(False)
 +# Closer-in minimum depth, disparity range is doubled:
 +depth.setExtendedDisparity(False)
 +# Better accuracy for longer distance, fractional disparity 32-levels:
 +depth.setSubpixel(False)
  
 +left.out.link(depth.left)
 +right.out.link(depth.right)
  
 +# Create output
 +xout = pipeline.createXLinkOut()
 +xout.setStreamName("disparity")
 +depth.disparity.link(xout.input)
 +
 +with dai.Device(pipeline) as device:
 +    device.startPipeline()
 +    # Output queue will be used to get the disparity frames from the outputs defined above
 +    q = device.getOutputQueue(name="disparity", maxSize=4, blocking=False)
 +
 +    while True:
 +        inDepth = q.get()  # blocking call, will wait until a new data has arrived
 +        frame = inDepth.getFrame()
 +        frame = cv2.normalize(frame, None, 0, 255, cv2.NORM_MINMAX)
 +        # Convert depth_frame to numpy array to render image in opencv
 +        depth_gray_image = np.asanyarray(frame)
 +        # Resize Depth image to 640x480
 +        resized = cv2.resize(depth_gray_image, (640, 480), interpolation = cv2.INTER_AREA)
 +        sender.send_image("moi", resized)
 +        cv2.imshow("disparity", resized)
 +        if cv2.waitKey(1) == 27:
 +            break
 +</file>
 +Le receiver est le même que ci-dessus.
  
  
  
-{{tag>opencv pd pure-data pure_data python sb vlc}}+{{tag>zmc opencv pd pure-data pure_data python sb}}
streaming_over_network_with_opencv_et_zeromq.txt · Dernière modification : 2022/02/25 13:15 de serge