Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Connecting multiple devices with pyrealsense2 #1735

Closed
marialarsson opened this issue May 21, 2018 · 8 comments
Closed

Connecting multiple devices with pyrealsense2 #1735

marialarsson opened this issue May 21, 2018 · 8 comments

Comments

@marialarsson
Copy link

marialarsson commented May 21, 2018

Hi,

I am trying to connect two camera devices (D415) and get their images at the same time, using pyrealsense2.

There is a description how to do exactly that here: https://github.com/IntelRealSense/librealsense/tree/master/examples/multicam

But unfortunately it doesnt help me much because it is not written with pyrealsense2.

I started from the provided example file opencv_viewer_example.py trying to modify it.

I could identify my two cameras with the code below;

ctx = rs.context()
devices = ctx.query_devices()
print devices[0]
print devices[1]

But how do I move on to create separate streams for them? In the pipeline, confi`guration....? I tried everything.

I would be grateful for some sample code!

Thanks,
M

Camera Model: D415
Operating System: Linux Ubuntu

@lramati
Copy link
Contributor

lramati commented May 21, 2018

pyrealsense2 is a direct port of the C++ API.
In the example you linked, the helper class device_container is defined to help manage the devices.
On line 169 this class is used to start the devices with the device_container::enable_device() function, which is implemented on line 30.
Inside device_container::enable_device()'s implementation, you can see on lines 45-50 that a separate pipeline/config object is created for each one. This code can be ported directly to Python.
line 52 holds the relevant objects alive inside the device_container object. Note that only the profile and pipeline are stored, not the config object.
device_container::poll_frames(), implemented on line 97, is how the example accesses the frames from the devices, simply polling each in turn (lines 101-114). This code can also be ported directly.

Hope this helps!

@marialarsson
Copy link
Author

Thank you!

It helped. I could finally implement two cameras. Let me share my code below.

Again, I started from the opencv_viewer_example.py. The added functions are that there are two cameras working at the same time, and that you can save the images by pressing 's'.

import pyrealsense2 as rs
import numpy as np
import cv2
import logging


# Configure depth and color streams...
# ...from Camera 1
pipeline_1 = rs.pipeline()
config_1 = rs.config()
config_1.enable_device('013102060174')
config_1.enable_stream(rs.stream.depth, 640, 480, rs.format.z16, 30)
config_1.enable_stream(rs.stream.color, 640, 480, rs.format.bgr8, 30)
# ...from Camera 2
pipeline_2 = rs.pipeline()
config_2 = rs.config()
config_2.enable_device('046112051680')
config_2.enable_stream(rs.stream.depth, 640, 480, rs.format.z16, 30)
config_2.enable_stream(rs.stream.color, 640, 480, rs.format.bgr8, 30)


# Start streaming from both cameras
pipeline_1.start(config_1)
pipeline_2.start(config_2)

try:
    while True:

        # Camera 1
        # Wait for a coherent pair of frames: depth and color
        frames_1 = pipeline_1.wait_for_frames()
        depth_frame_1 = frames_1.get_depth_frame()
        color_frame_1 = frames_1.get_color_frame()
        if not depth_frame_1 or not color_frame_1:
            continue
        # Convert images to numpy arrays
        depth_image_1 = np.asanyarray(depth_frame_1.get_data())
        color_image_1 = np.asanyarray(color_frame_1.get_data())
        # Apply colormap on depth image (image must be converted to 8-bit per pixel first)
        depth_colormap_1 = cv2.applyColorMap(cv2.convertScaleAbs(depth_image_1, alpha=0.5), cv2.COLORMAP_JET)

        # Camera 2
        # Wait for a coherent pair of frames: depth and color
        frames_2 = pipeline_2.wait_for_frames()
        depth_frame_2 = frames_2.get_depth_frame()
        color_frame_2 = frames_2.get_color_frame()
        if not depth_frame_2 or not color_frame_2:
            continue
        # Convert images to numpy arrays
        depth_image_2 = np.asanyarray(depth_frame_2.get_data())
        color_image_2 = np.asanyarray(color_frame_2.get_data())
        # Apply colormap on depth image (image must be converted to 8-bit per pixel first)
        depth_colormap_2 = cv2.applyColorMap(cv2.convertScaleAbs(depth_image_2, alpha=0.5), cv2.COLORMAP_JET)

        # Stack all images horizontally
        images = np.hstack((color_image_1, depth_colormap_1,color_image_2, depth_colormap_2))

        # Show images from both cameras
        cv2.namedWindow('RealSense', cv2.WINDOW_NORMAL)
        cv2.imshow('RealSense', images)
        cv2.waitKey(1)

        # Save images and depth maps from both cameras by pressing 's'
        ch = cv2.waitKey(25)
        if ch==115:
            cv2.imwrite("my_image_1.jpg",color_image_1)
            cv2.imwrite("my_depth_1.jpg",depth_colormap_1)
            cv2.imwrite("my_image_2.jpg",color_image_2)
            cv2.imwrite("my_depth_2.jpg",depth_colormap_2)
            print "Save"


finally:

    # Stop streaming
    pipeline_1.stop()
    pipeline_2.stop()

@RealSense-Customer-Engineering
Copy link
Collaborator

[Realsense Customer Engineering Team Comment]
@marialarsson
Great to see it works for you now, you can consider to contribute this example to LibRS python wrapper by creating PR.

@LLUWE19
Copy link

LLUWE19 commented Aug 8, 2019

Does anybody know how to retrieve only the serial number? I am trying to load multiple cameras using a for loop

Thanks

@jamie-serrano
Copy link

Does anybody know how to retrieve only the serial number? I am trying to load multiple cameras using a for loop

Thanks

you could try something like:

realsense_ctx = rs.context()
connected_devices = []
for i in range(len(realsense_ctx.devices)):
detected_camera = realsense_ctx.devices[i].get_info(rs.camera_info.serial_number)
connected_devices.append(detected_camera)

config = rs.config()
config.enable_device(sensor_sn)
config.enable_stream(rs.stream.depth, 424, 240, rs.format.z16, 30)
config.enable_stream(rs.stream.color, 424, 240, rs.format.bgr8, 30)

profile = pipeline.start(config)

@ivomarvan
Copy link

I wrote an example of connecting multiple Realsense cameras in Python:
https://github.com/ivomarvan/samples_and_experiments/tree/master/Multiple_realsense_cameras
Enjoy it if you find it useful.

@22pilarskil
Copy link

Thank you so much for figuring this out- I've been looking online for hours for how to do exactly this

@YonatanSimson
Copy link

To get the serial device numbers for two samples this is what worked for me:

import pyrealsense2 as rs

ctx = rs.context()
devices = ctx.query_devices()
dev0 = ctx.query_devices()[0]  
dev1 = ctx.query_devices()[1]

device_model0 = str(dev0.get_info(rs.camera_info.name))
device_model1 = str(dev1.get_info(rs.camera_info.name))

print(f'device_model0: {device_model0}') 
print(f'device_model1: {device_model1}')

print('Config ... ')
pipe1 = rs.pipeline()
cfg1 = rs.config()
cfg1.enable_device(dev0.get_info(rs.camera_info.serial_number))
cfg1.enable_stream(rs.stream.infrared, 1, 424, 240, rs.format.y8, 30)
cfg1.enable_stream(rs.stream.infrared, 2, 424, 240, rs.format.y8, 30)

pipe2 = rs.pipeline()
cfg2 = rs.config()
cfg2.enable_device(dev1.get_info(rs.camera_info.serial_number))
cfg2.enable_stream(rs.stream.infrared, 1,  424, 240, rs.format.y8, 30)
cfg2.enable_stream(rs.stream.infrared, 2,  424, 240, rs.format.y8, 30

....

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

9 participants