Outils pour utilisateurs

Outils du site


streamer_des_images_opencv_avec_v4l2-loopback

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
streamer_des_images_opencv_avec_v4l2-loopback [2022/02/20 13:04] – [Installation] sergestreamer_des_images_opencv_avec_v4l2-loopback [2022/03/03 12:35] (Version actuelle) – [Profondeur d'une RealSense D455] serge
Ligne 3: Ligne 3:
 <WRAP center round box 60%> <WRAP center round box 60%>
 Le **[[streaming_over_network_with_opencv_et_zeromq|stream avec zeromq]]** est sans latence, mais ne peut pas être reçu par Pure Data et VLC.\\ Le **[[streaming_over_network_with_opencv_et_zeromq|stream avec zeromq]]** est sans latence, mais ne peut pas être reçu par Pure Data et VLC.\\
-**v4l2-loopback** a un peu de latence (0.1 à 0.2 seconde) mais c'est un flux v4l2+**v4l2-loopback** a un peu de latence (0.1 à 0.2 seconde) en lecture dans VLC, mais pas de latence si lecture avec OpenCV\\ 
 +**Nous utilisons pyfakewebcam**
 </WRAP> </WRAP>
  
 =====Ressources===== =====Ressources=====
 +**pyfakewebcam**
 +Il y a divers projets qui font ça sur GitHub, celui ci à cette qualité de marcher!
   * https://codingshiksha.com/python/python-3-pyfakewebcam-script-to-build-fake-webcam-with-custom-background-image-gui-desktop-app-full-project-for-beginners/   * https://codingshiksha.com/python/python-3-pyfakewebcam-script-to-build-fake-webcam-with-custom-background-image-gui-desktop-app-full-project-for-beginners/
   * https://github.com/jremmons/pyfakewebcam   * https://github.com/jremmons/pyfakewebcam
   * https://github.com/umlaeute/v4l2loopback   * https://github.com/umlaeute/v4l2loopback
  
-=====Installation==== +=====Sources des exemples===== 
-A voir, nécessaire mais peut-être pas suffisant: +  * **[[https://github.com/sergeLabo/fakewebcam|fakewebcam de github.com/sergeLabo]]**
-  sudo apt install v4l2loopback-utils +
-  +
-<code bash> +
-sudo apt install python3-pip +
-python3 -m pip install --upgrade pip +
-sudo apt install python3-venv+
  
-cd /le/dossier/de/votre/projet +====Installation==== 
-python3 -m venv mon_env +Voir le README ci-dessus.
-source mon_env/bin/activate +
-python3 -m pip install opencv-python pyfakewebcam +
-</code>  +
  
 =====Exemple simple pour tester===== =====Exemple simple pour tester=====
 <file python cam_relay.py>   <file python cam_relay.py>  
-""" 
-Insert the v4l2loopback kernel module. 
-modprobe v4l2loopback devices=2 
-will create two fake webcam devices 
-""" 
- 
-import time 
 import pyfakewebcam import pyfakewebcam
 import cv2 import cv2
- 
 import numpy as np import numpy as np
  
 cap = cv2.VideoCapture(0) cap = cv2.VideoCapture(0)
-camera = pyfakewebcam.FakeWebcam('/dev/video1', 640, 480)+camera = pyfakewebcam.FakeWebcam('/dev/video11', 640, 480)
  
 while True: while True:
Ligne 50: Ligne 36:
     if cv2.waitKey(1) == 27:     if cv2.waitKey(1) == 27:
         break         break
 +</file>
  
 +Run the following command to see the output of the fake webcam.\\
 +ffplay /dev/video11\\
 +or open the camera 11 in vlc
 +===== Profondeur d'une OAK-D Lite =====
 +<file python sender_oak_depth.py>
 +import cv2
 +import depthai as dai
 +import numpy as np
 +import pyfakewebcam
 +
 +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)
 +
 +camera = pyfakewebcam.FakeWebcam('/dev/video11', 640, 480)
 +
 +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)
 +
 +        depth_gray_image = cv2.resize(np.asanyarray(frame), (640, 480),
 +                                interpolation = cv2.INTER_AREA)
 +        # v4l2 doit être RGB
 +        color = cv2.cvtColor(depth_gray_image, cv2.COLOR_GRAY2RGB)
 +        camera.schedule_frame(color)
 +
 +        if cv2.waitKey(1) == 27:
 +            break
 +</file>
 +
 +Ouvrir /dev/video11 dans VLC
 +{{ :media_15:oak_depth_in_vlc.png?400 |}}
 +=====Profondeur d'une RealSense D455=====
 +Pour l'installation, voir **https://github.com/sergeLabo/grande_echelle#installation**
 +
 +<file python sender_rs_depth.py>
 """ """
-Run the following command to see the output of the fake webcam. +Voir https://github.com/sergeLabo/fakewebcam 
-ffplay /dev/video1 + 
-or open a camera in vlc+Suppression du fond, voir 
 +https://github.com/IntelRealSense/librealsense/blob/master/wrappers/python/examples/align-depth2color.py
 """ """
-</file> 
  
-Exécuter le script avec: +import os 
-  cd /le/dossier/de/votre/projet +import time 
-  modprobe v4l2loopback devices=2 +import pyfakewebcam 
-  ./mon_env/bin/python3  +import cv2 
-Dans un autre terminal +import numpy as np 
-  ffplay /dev/video1 +import pyrealsense2 as rs 
-Il faudra peut-être adapter les numéro de /dev/video + 
-  + 
 +# Le faux device 
 +VIDEO = '/dev/video11' 
 + 
 +# Avec ou sans slider pour régler CLIPPING_DISTANCE_IN_MILLIMETER 
 +SLIDER = 1 
 +# Réglable avec le slider 
 +# We will be removing the background of objects more than 
 +# CLIPPING_DISTANCE_IN_MILLIMETER away 
 +CLIPPING_DISTANCE_IN_MILLIMETER = 2000 
 + 
 + 
 +class MyRealSense: 
 + 
 +    def __init__(self, video, slider, clip): 
 +        self.video = video 
 +        self.slider = slider 
 +        self.clip = clip 
 + 
 +        self.width = 1280 
 +        self.height = 720 
 +        self.pose_loop = 1 
 +        self.pipeline = rs.pipeline() 
 +        config = rs.config() 
 +        pipeline_wrapper = rs.pipeline_wrapper(self.pipeline) 
 +        try: 
 +            pipeline_profile = config.resolve(pipeline_wrapper) 
 +        except: 
 +            print('\n\nPas de Capteur Realsense connecté\n\n') 
 +            os._exit(0) 
 +        device pipeline_profile.get_device() 
 +        config.enable_stream(   rs.stream.color, 
 +                                width=self.width, 
 +                                height=self.height, 
 +                                format=rs.format.bgr8, 
 +                                framerate=30) 
 +        config.enable_stream(   rs.stream.depth, 
 +                                width=self.width, 
 +                                height=self.height, 
 +                                format=rs.format.z16, 
 +                                framerate=30) 
 + 
 +        profile = self.pipeline.start(config) 
 +        self.align = rs.align(rs.stream.color) 
 +        unaligned_frames = self.pipeline.wait_for_frames() 
 +        frames = self.align.process(unaligned_frames) 
 + 
 +        # Getting the depth sensor's depth scale (see rs-align example for explanation) 
 +        depth_sensor = profile.get_device().first_depth_sensor() 
 +        self.depth_scale = depth_sensor.get_depth_scale() 
 +        print("Depth Scale is: " , self.depth_scale) 
 + 
 +        # Affichage de la taille des images 
 +        color_frame = frames.get_color_frame() 
 +        img = np.asanyarray(color_frame.get_data()) 
 +        print(f"Taille des images:" 
 +              f"     {img.shape[1]}x{img.shape[0]}"
 + 
 +        self.camera = pyfakewebcam.FakeWebcam(VIDEO, 1280, 720) 
 + 
 +        if self.slider: 
 +            self.create_slider() 
 + 
 +    def create_slider(self): 
 +        cv2.namedWindow('controls'
 +        cv2.createTrackbar('background', 'controls', 1000, 8000, 
 +                            self.remove_background_callback) 
 +        cv2.setTrackbarPos('background', 'controls', self.clip) 
 +        cv2.namedWindow('depth', cv2.WND_PROP_FULLSCREEN) 
 + 
 +    def remove_background_callback(self, value): 
 +        if value != 1000: 
 +            self.clip = int(value) 
 + 
 +    def run(self): 
 +        """Boucle infinie, quitter avec Echap dans la fenêtre OpenCV""" 
 + 
 +        while self.pose_loop: 
 + 
 +            # Get frameset of color and depth 
 +            frames = self.pipeline.wait_for_frames() 
 +            # frames.get_depth_frame() is a 640x360 depth image 
 + 
 +            # Align the depth frame to color frame 
 +            aligned_frames = self.align.process(frames) 
 + 
 +            # aligned_depth_frame is a 640x480 depth image 
 +            aligned_depth_frame = aligned_frames.get_depth_frame() 
 +            color_frame = aligned_frames.get_color_frame() 
 + 
 +            # Validate that both frames are valid 
 +            if not aligned_depth_frame or not color_frame: 
 +                continue 
 + 
 +            depth_image = np.asanyarray(aligned_depth_frame.get_data()) 
 +            color_image = np.asanyarray(color_frame.get_data()) 
 + 
 +            # Remove background - Set pixels further than clipping_distance to grey 
 +            # depth image is 1 channel, color is 3 channels 
 +            depth_image_3d = np.dstack((depth_image, depth_image, depth_image)) 
 +            clipping_distance = self.clip (1000*self.depth_scale) 
 +            bg_removed = np.where((depth_image_3d > clipping_distance) |\ 
 +                        (depth_image_3d <= 0), 0, color_image) 
 + 
 +            depth_colormap = cv2.applyColorMap(cv2.convertScaleAbs(depth_image, 
 +                                                                   alpha=0.03), 
 +                                                                   cv2.COLORMAP_JET) 
 +            images = np.hstack((bg_removed, depth_colormap)) 
 + 
 +            if self.slider: 
 +                cv2.imshow('depth', images) 
 + 
 +            self.camera.schedule_frame(bg_removed) 
 + 
 +            if cv2.waitKey(1) == 27: 
 +                break 
 + 
 + 
 + 
 +if __name__ == '__main__': 
 + 
 +    mrs = MyRealSense(VIDEO, SLIDER, CLIPPING_DISTANCE_IN_MILLIMETER) 
 +    mrs.run() 
 +</file>
      
 +=====Réception=====
 +Ouvrir /dev/video11 dans VLC\\
 +
 +{{:media_15:color_depth.png?800|}}
 +
 +ou
 +<file python receiver.py>
 +import cv2
 +cap = cv2.VideoCapture(2)
 +while 1:
 +    ret, image = cap.read()
 +    if ret:
 +        cv2.imshow("frame", image)
 +    if cv2.waitKey(1) == 27:
 +        break
 +</file>
 +
 {{tag>opencv pure-data pure_data python sb vlc}} {{tag>opencv pure-data pure_data python sb vlc}}
streamer_des_images_opencv_avec_v4l2-loopback.1645362242.txt.gz · Dernière modification : 2022/02/20 13:04 de serge