Skip to main content

LibMultiSense python package wrapped using pybind11

Project description

LibMultiSense

codecov

LibMultiSense is a C++ and Python library designed to simplify interaction with the MultiSense S family of stereo sensors developed by Carnegie Robotics. It provides a comprehensive, easy-to-use API for capturing and processing stereo sensor data an generating depth images, color images, and 3D point clouds.

Official product page: Carnegie Robotics MultiSense Products

Detailed documentation: LibMultiSense Documentation

LibMultiSense was recently refactored to have a new API. The following examples in the README all assume the user is using the new API. To build with the new API, the following CMake arguments should be set.

-DBUILD_LEGACY_API=0FF

The README for the Legacy API can be found here.

The LibMultiSense C++ and Python library has been tested with the following operating systems

  • Ubuntu
    • 20.04
    • 22.04
    • 24.04
  • MacOS Sequoia
  • Windows 11

Table of Contents

Client Networking Prerequisite

The MultiSense comes preconfigured with a static 10.66.171.21 IP address with a /24 subnet. To connect to the MultiSense, a client machine must be updated with an IP address on the 10.66.171 subnet.

Please see the host network configuration for details on how to set a client machine's IP address and MTU.

Quickstart Guide

Below are minimal examples demonstrating basic usage of LibMultiSense to capture rectified images from the camera.

Before running the examples make sure LibMultiSense is installed, and your machines network is properly configured.

For new users, it's recommended to start with the Python version of LibMultiSense. After installing the libmultisense package, several command-line utilities are automatically installed and can be run directly from your terminal:

  • multisense_device_info_utility: Display information about a connected MultiSense device.
  • multisense_save_image_utility: Save images (rectified, color, depth) from the camera to disk.
  • multisense_point_cloud_utility: Generate and save 3D point clouds in .ply format.
  • multisense_version_info_utility: Show firmware and hardware version information.
  • multisense_change_ip_utility: Update the network configuration of a MultiSense device.
  • multisense_image_cal_utility: Query or set the intrinsic and extrinsic calibration of the MultiSense device.
  • multisense_multi_channel_utility: Synchronize outputs from multiple MultiSense devices (requires PTP synchronization).
  • multisense_ptp_utility: Check the current PTP sync of the MultiSense device.
  • multisense_rectified_focal_length_utility: Update the focal length of the rectified image used to compute disparity.
  • multisense_feature_detector_utility: Display a live feed of detected features on the left rectified image.

Example usage:

multisense_device_info_utility --ip_address 10.66.171.21

Python

Install the LibMultiSenes python client and OpenCV dependency via

pip install libmultisense opencv-python
import libmultisense as lms
import cv2

channel_config = lms.ChannelConfig()
channel_config.ip_address = "10.66.171.21"
with lms.Channel.create(channel_config) as channel:
    channel.start_streams([lms.DataSource.LEFT_RECTIFIED_RAW, lms.DataSource.RIGHT_RECTIFIED_RAW])

    while True:
        frame = channel.get_next_image_frame()
        if frame:
            for source, image in frame.images.items():
                cv2.imwrite(str(source) + ".png", image.as_array)

C++

#include <MultiSense/MultiSenseChannel.hh>
#include <MultiSense/MultiSenseUtilities.hh>

namespace lms = multisense;

int main()
{
    const auto channel = lms::Channel::create(lms::Channel::Config{"10.66.171.21"});
    channel->start_streams({lms::DataSource::LEFT_RECTIFIED_RAW, lms::DataSource::RIGHT_RECTIFIED_RAW});

    while(true)
    {
        if (const auto image_frame = channel->get_next_image_frame(); image_frame)
        {
            for (const auto &[source, image]: image_frame->images)
            {
                const auto path = std::to_string(image_frame->frame_id) +  "_" +
                                  std::to_string(static_cast<int>(source)) + ".png";
                lms::write_image(image, path);
            }
        }
    }
    return 0;
}

Optional Dependencies When Building From Source

OpenCV

LibMultiSense optionally has OpenCV utility functions to make the LibMultiSense client API easier to integrate with existing systems. To build the OpenCV helpers the following CMake argument should be set

-DBUILD_OPENCV=ON

This will require a system installation of OpenCV, or an installation which can be pointed to with CMake's CMAKE_PREFIX_PATH argument

nlohmann json

LibMultiSense optionally uses nlohmann_json for serialization of base LibMultiSense types. To build the nlohmann_json serialization helpers the following CMake argument should be set

-DBUILD_JSON_SERIALIZATION=ON

This will require a system installation of nlohmann_json, or an installation which can be pointed to with CMake's CMAKE_PREFIX_PATH argument

pybind11

LibMultiSense optionally uses pybind11 to generate python bindings for the C++ API. To build the pybind11 python bindings the following CMake argument should be set

-DBUILD_PYTHON_BINDINGS=ON

This will require a system installation of pybind11, or an installation which can be pointed to with CMake's CMAKE_PREFIX_PATH argument

googletest

LibMultiSense optionally uses googletest for unit testing the C++ API. To build the googletest unit tests the following CMake argument should be set

-DBUILD_TESTS=ON

This will require a system installation of googletest, or an installation which can be pointed to with CMake's CMAKE_PREFIX_PATH argument

Code Coverage

LibMultiSense supports generating unit test coverage reports using lcov and genhtml. To enable coverage instrumentation, set the following CMake argument:

-DENABLE_COVERAGE=ON

Once enabled, you can generate the coverage report by running:

make coverage

The report will be generated in build/coverage_report/index.html. This requires lcov and genhtml to be installed on the system and is supported on Linux with GCC or Clang.


Installation

Linux

Python

PyPi (Recommended)

The following command installs/updates to the latest version of the LibMultisense Python API:

pip install --upgrade libmultisense

To avoid conflicts with other Python packages, it's recommended to utilize venv to isolate dependency installations.

From Source

LibMultiSense uses pybind11 to generate Python bindings for the base LibMultiSense API. These bindings can be installed via pip into a Python virtual environment or a local Python project.

To install the LibMultiSense Python bindings

> sudo apt install build-essential pybind11-dev nlohmann-json3-dev

> git clone https://github.com/carnegierobotics/LibMultiSense.git
> cd LibMultiSense
> pip install .

C++

LibMultiSense uses CMake for its build system.

To build the standalone LibMultiSense library and demonstration applications.

# Note this only needs to be run once before building
> sudo apt install build-essential nlohmann-json3-dev

> git clone https://github.com/carnegierobotics/LibMultiSense.git
> cd LibMultiSense
> mkdir build
> cd build && cmake -DBUILD_LEGACY_API=OFF -DBUILD_JSON_SERIALIZATION=ON -DCMAKE_INSTALL_PREFIX=../install ..
> make install
> cd ../install

To build the standalone LibMultiSense library without the demonstration applications, set the cmake variable -DMULTISENSE_BUILD_UTILITIES=OFF


MacOS

Python

PyPi (Recommended)

The following command installs/updates to the latest version of the LibMultisense Python API:

pip install --upgrade libmultisense

To avoid conflicts with other Python packages, it's recommended to utilize venv to isolate dependency installations.

From Source

LibMultiSense uses pybind11 to generate Python bindings for the base LibMultiSense API. These bindings can be installed via pip into a Python virtual environment or a local Python project.

To install the LibMultiSense Python bindings

> brew install pybind11 nlohmann-json

> git clone https://github.com/carnegierobotics/LibMultiSense.git
> cd LibMultiSense
> pip install .

C++

LibMultiSense uses CMake for its build system.

To build the standalone LibMultiSense library and demonstration applications.

# Note this only needs to be run once before building
> brew install nlohmann-json

> git clone https://github.com/carnegierobotics/LibMultiSense.git
> cd LibMultiSense
> mkdir build
> cd build && cmake -DBUILD_LEGACY_API=OFF -DBUILD_JSON_SERIALIZATION=ON -DCMAKE_INSTALL_PREFIX=../install ..
> make install
> cd ../install

To build the standalone LibMultiSense library without the demonstration applications, set the cmake variable -DMULTISENSE_BUILD_UTILITIES=OFF


Windows

Python

PyPi (Recommended)

The following command installs/updates to the latest version of the LibMultisense Python API.

After installing Python via the Microsoft Store execute the following command in a Powershell terminal

pip install --upgrade libmultisense

To avoid conflicts with other Python packages, it's recommended to utilize venv to isolate dependency installations.

From Source

LibMultiSense uses pybind11 to generate Python bindings for the base LibMultiSense API. These bindings can be installed via pip into a Python virtual environment or a local Python project. To ensure Windows has the proper build tools installed, please install Microsoft Visual Studio with the C++ and CMake extensions.

Note you will need to have a version of Python installed on your Windows system. This was tested with Python 3.9 installed via the Microsoft Store on Windows 11.

To install the LibMultiSense Python bindings open a powershell terminal and execute the following commands

> git clone https://github.com/carnegierobotics/LibMultiSense.git
> cd LibMultiSense
> git clone https://github.com/microsoft/vcpkg.git
> ./vcpkg/bootstrap-vcpkg.bat

> $Env:VCPKG_ROOT = ./vcpkg

> pip install .

C++

LibMultiSense uses CMake and vcpkg to build the LibMultiSense library. To ensure Windows has the proper build tools installed, please install Microsoft Visual Studio with the C++ and CMake extensions.

Open a powershell terminal and execute the following commands:

> git clone https://github.com/carnegierobotics/LibMultiSense.git
> cd LibMultiSense
> git clone https://github.com/microsoft/vcpkg.git
> ./vcpkg/bootstrap-vcpkg.bat

> $Env:VCPKG_ROOT = ./vcpkg

> cmake --build build --config Release --target install

CMake Project Integration

Integrating LibMultiSense into an existing CMake project is easy. There are two primary methods for integration: a local install on your system, or a submodule clone within your repository

Local Installation

LibMultiSense is installed on your system (i.e. in a location like /opt/multisense)

find_package(MultiSense)
target_link_libraries(<your-library-or-binary> MultiSense)

When running CMake, make sure to specify the location of the LibMultiSense install via -DCMAKE_PREFIX_PATH

Git Submodule

Clone the LibMultiSense repository into the existing project's source tree. In the main CMakeLists.txt file of the project, add the following lines:

 include_directories(LibMultiSense/source/LibMultiSense)
 add_subdirectory(LibMultiSense/source/LibMultiSense)

Documentation

Documentation of high-level LibMultiSense concepts can be found here

Doxygen documentation can be built for LibMultisense by running the Doxygen configuration file located in the docs directory

> cd LibMultiSense/docs
> doxygen Doxyfile

HTML and LaTex documentation will be generated in the docs directory.

Usage examples are included in the Doxygen documentation.


Support

To report an issue with this library or request a new feature, please use the GitHub issues system

For product support, please see the support section of our website Individual support requests can be created in our support portal

Wireshark Plugin

A Wireshark Lua dissector is provided in the wireshark directory to help analyze MultiSense network traffic on UDP port 9001.

Installation

To install the plugin:

Linux

Copy the plugin to your personal Wireshark plugins directory:

mkdir -p ~/.local/lib/wireshark/plugins
cp wireshark/multisense.lua ~/.local/lib/wireshark/plugins/

Windows

Copy wireshark/multisense.lua to %APPDATA%\Wireshark\plugins.

MacOS

Copy wireshark/multisense.lua to ~/.config/wireshark/plugins.

Manual Loading

Alternatively, you can load the plugin manually when starting Wireshark:

wireshark -X lua_script:wireshark/multisense.lua

Camera Configuration

Camera settings like resolution, exposure, FPS, gain, gamma, and white balance can be configured via the LibMultiSense image::Config

Python

import libmultisense as lms
import cv2

def main():
    channel_config = lms.ChannelConfig()
    channel_config.ip_address = "10.66.171.21"

    with lms.Channel.create(channel_config) as channel:
        if not channel:
            print("Invalid channel")
            exit(1)

        config = channel.get_config()
        config.frames_per_second = 10.0
        config.width = 960
        config.height = 600
        config.disparities = lms.MaxDisparities.D256
        config.image_config.auto_exposure_enabled = True
        config.image_config.gamma = 2.2
        if channel.set_config(config) != lms.Status.OK:
            print("Cannot set configuration")
            exit(1)

if __name__ == "__main__":
    main()

C++

#include <iostream>

#include <MultiSense/MultiSenseChannel.hh>
#include <MultiSense/MultiSenseUtilities.hh>

namespace lms = multisense;

int main(int argc, char** argv)
{
    const auto channel = lms::Channel::create(lms::Channel::Config{"10.66.171.21"});
    if (!channel)
    {
        std::cerr << "Failed to create channel" << std::endl;;
        return 1;
    }

    auto config = channel->get_config();
    config.frames_per_second = 10.0;
    config.width = 960;
    config.height = 600;
    config.disparities = lms::MultiSenseConfig::MaxDisparities::D256;
    config.image_config.auto_exposure_enabled = true;
    config.image_config.gamma = 2.2;
    if (const auto status = channel->set_config(config); status != lms::Status::OK)
    {
        std::cerr << "Cannot set config" << std::endl;
        return 1;
    }

    return 0;
}

Point Cloud Generation

Disparity images can be converted to 3D point cloud images using the client API.

The following modified version of the Quickstart example, converts disparity images to 3D point clouds colorized using the left rectified image.

Python

import libmultisense as lms
import cv2

def main():
    channel_config = lms.ChannelConfig()
    channel_config.ip_address = "10.66.171.21"

    with lms.Channel.create(channel_config) as channel:
        if not channel:
            print("Invalid channel")
            exit(1)

        if channel.start_streams([lms.DataSource.LEFT_RECTIFIED_RAW, lms.DataSource.LEFT_DISPARITY_RAW]) != lms.Status.OK:
            print("Unable to start streams")
            exit(1)

        while True:
            frame = channel.get_next_image_frame()
            if frame:
                point_cloud = lms.create_gray8_pointcloud(frame,
                                                         args.max_range,
                                                         lms.DataSource.LEFT_RECTIFIED_RAW,
                                                         lms.DataSource.LEFT_DISPARITY_RAW)

                print("Saving pointcloud for frame id: ", frame.frame_id)
                lms.write_pointcloud_ply(point_cloud, str(frame.frame_id) + ".ply")

if __name__ == "__main__":
    main()

C++

#include <iostream>

#include <MultiSense/MultiSenseChannel.hh>
#include <MultiSense/MultiSenseUtilities.hh>

namespace lms = multisense;

volatile bool done = false;

int main(int argc, char** argv)
{
    const auto channel = lms::Channel::create(lms::Channel::Config{"10.66.171.21"});
    if (!channel)
    {
        std::cerr << "Failed to create channel" << std::endl;;
        return 1;
    }

    if (const auto status = channel->start_streams({lms::DataSource::LEFT_RECTIFIED_RAW,
                                                    lms::DataSource::LEFT_DISPARITY_RAW}); status != lms::Status::OK)
    {
        std::cerr << "Cannot start streams: " << lms::to_string(status) << std::endl;
        return 1;
    }

    const double max_range_m = 20.0;

    while(!done)
    {
        if (const auto image_frame = channel->get_next_image_frame(); image_frame)
        {
            if (const auto point_cloud = lms::create_color_pointcloud<uint8_t>(image_frame.value(),
                                                                               max_range_m,
                                                                               lms::DataSource::LEFT_RECTIFIED_RAW,
                                                                               lms::DataSource::LEFT_DISPARITY_RAW); point_cloud)
            {
                std::cout << "Saving pointcloud for frame id: " << image_frame->frame_id << std::endl;
                lms::write_pointcloud_ply(point_cloud.value(), std::to_string(image_frame->frame_id) + ".ply");
            }
        }
    }

    return 0;
}

Depth Image Generation

Disparity images can be converted to depth images using the client API

The following modified version of the Quickstart example, converts disparity images to openni depth images and saves them to disk using OpenCV.

Python

import libmultisense as lms
import cv2

def main():
    channel_config = lms.ChannelConfig()
    channel_config.ip_address = "10.66.171.21"

    with lms.Channel.create(channel_config) as channel:
        if not channel:
            print("Invalid channel")
            exit(1)

        if channel.start_streams([lms.DataSource.LEFT_DISPARITY_RAW]) != lms.Status.OK:
            print("Unable to start streams")
            exit(1)

        # Set to true to save the depth image in the frame of the aux color camera
        in_aux_frame = False

        while True:
            frame = channel.get_next_image_frame()
            if frame:
                # MONO16 depth images are quantized to 1 mm per 1 pixel value to match the OpenNI standard.
                # For example, a depth image pixel with a value of 10 would correspond to a depth of 10mm
                depth_image = lms.create_depth_image(frame, lms.PixelFormat.MONO16, lms.DataSource.LEFT_DISPARITY_RAW, in_aux_frame, 65535)
                if depth_image:
                    print("Saving depth image for frame id: ", frame.frame_id)
                    cv2.imwrite(str(frame.frame_id) + ".png", depth_image.as_array)

if __name__ == "__main__":
    main()

C++

#include <iostream>

#include <opencv2/opencv.hpp>

#include <MultiSense/MultiSenseChannel.hh>
#include <MultiSense/MultiSenseUtilities.hh>

namespace lms = multisense;

volatile bool done = false;

int main(int argc, char** argv)
{
    const auto channel = lms::Channel::create(lms::Channel::Config{"10.66.171.21"});
    if (!channel)
    {
        std::cerr << "Failed to create channel" << std::endl;;
        return 1;
    }

    if (const auto status = channel->start_streams({lms::DataSource::LEFT_DISPARITY_RAW}); status != lms::Status::OK)
    {
        std::cerr << "Cannot start streams: " << lms::to_string(status) << std::endl;
        return 1;
    }

    // Set to true to save the depth image in the frame of the aux color camera
    const bool in_aux_frame = false;

    while(!done)
    {
        if (const auto image_frame = channel->get_next_image_frame(); image_frame)
        {
            //
            // MONO16 depth will be quantized to mm to match OpenNI's depth format
            //
            if (const auto depth_image = lms::create_depth_image(image_frame.value(),
                                                                 lms::Image::PixelFormat::MONO16,
                                                                 lms::DataSource::LEFT_DISPARITY_RAW,
                                                                 in_aux_frame,
                                                                 65535); depth_image)
            {
                std::cout << "Saving depth image for frame id: " << image_frame->frame_id << std::endl;
                cv::imwrite(std::to_string(image_frame->frame_id) + ".png", depth_image->cv_mat());
            }
        }
    }

    return 0;
}

Color Image Generation

Luma and Chroma Aux images can be converted to BGR color images using the client API

The following modified version of the Quickstart example, converts luma and chroma aux images to BGR images and saves them to disk using OpenCV.

Python

import libmultisense as lms
import cv2

def main():
    channel_config = lms.ChannelConfig()
    channel_config.ip_address = "10.66.171.21"

    with lms.Channel.create(channel_config) as channel:
        if not channel:
            print("Invalid channel")
            exit(1)

        if channel.start_streams([lms.DataSource.AUX_RAW]) != lms.Status.OK:
            print("Unable to start streams")
            exit(1)

        while True:
            frame = channel.get_next_image_frame()
            if frame:
                bgr = lms.create_bgr_image(frame, lms.DataSource.AUX_RAW)
                if bgr:
                    cv2.imwrite(str(frame.frame_id) + ".png", bgr.as_array)

if __name__ == "__main__":
    main()

C++

#include <iostream>

#include <opencv2/opencv.hpp>

#include <MultiSense/MultiSenseChannel.hh>
#include <MultiSense/MultiSenseUtilities.hh>

namespace lms = multisense;

volatile bool done = false;

int main(int argc, char** argv)
{
    const auto channel = lms::Channel::create(lms::Channel::Config{"10.66.171.21"});
    if (!channel)
    {
        std::cerr << "Failed to create channel" << std::endl;;
        return 1;
    }

    if (const auto status = channel->start_streams({lms::DataSource::AUX_RAW}); status != lms::Status::OK)
    {
        std::cerr << "Cannot start streams: " << lms::to_string(status) << std::endl;
        return 1;
    }

    while(!done)
    {
        if (const auto image_frame = channel->get_next_image_frame(); image_frame)
        {
            if (const auto bgr = create_bgr_image(image_frame.value(), lms::DataSource::AUX_RAW); bgr)
            {
                cv::imwrite(std::to_string(image_frame->frame_id) + ".png", bgr->cv_mat());
            }
        }
    }

    return 0;
}

Lighting Control

MultiSense units like the KS21 contain integrated lighting which can be controlled via the lighting_config. Some units also support driving external LEDs via GPIO.

Python

import libmultisense as lms

def main():
    channel_config = lms.ChannelConfig()
    channel_config.ip_address = "10.66.171.21"

    with lms.Channel.create(channel_config) as channel:
        if not channel:
            print("Invalid channel")
            exit(1)

        config = channel.get_config()

        # Check if the camera supports lighting
        if config.lighting_config is not None:
            # Internal LEDs (Integrated into the camera)
            if config.lighting_config.internal is not None:
                # Set the lighting intensity to 50%
                config.lighting_config.internal.intensity = 50.0
                # Enable flashing. When enabled the lights will only be on while the camera is exposing
                config.lighting_config.internal.flash = True

            # External LEDs (Driven via external GPIO)
            if config.lighting_config.external is not None:
                # Set the external lighting intensity to 100%
                config.lighting_config.external.intensity = 100.0
                # Sync external flash with the main stereo pair
                config.lighting_config.external.flash = lms.FlashMode.SYNC_WITH_MAIN_STEREO
                # Number of pulses per exposure (useful for human persistence of vision)
                config.lighting_config.external.pulses_per_exposure = 1

            if channel.set_config(config) != lms.Status.OK:
                print("Cannot set configuration")
                exit(1)

if __name__ == "__main__":
    main()

C++

#include <iostream>
#include <MultiSense/MultiSenseChannel.hh>

namespace lms = multisense;

int main(int argc, char** argv)
{
    const auto channel = lms::Channel::create(lms::Channel::Config{"10.66.171.21"});
    if (!channel)
    {
        std::cerr << "Failed to create channel" << std::endl;
        return 1;
    }

    auto config = channel->get_config();

    // Check if the camera supports lighting
    if (config.lighting_config)
    {
        // Internal LEDs (Integrated into the camera)
        if (config.lighting_config->internal)
        {
            // Set the lighting intensity to 50%
            config.lighting_config->internal->intensity = 50.0f;
            // Enable flashing. When enabled the lights will only be on while the camera is exposing
            config.lighting_config->internal->flash = true;
        }

        // External LEDs (Driven via external GPIO)
        if (config.lighting_config->external)
        {
            // Set the external lighting intensity to 100%
            config.lighting_config->external->intensity = 100.0f;
            // Sync external flash with the main stereo pair
            config.lighting_config->external->flash = lms::MultiSenseConfig::LightingConfig::ExternalConfig::FlashMode::SYNC_WITH_MAIN_STEREO;
            // Number of pulses per exposure (useful for human persistence of vision)
            config.lighting_config->external->pulses_per_exposure = 1;
        }

        if (const auto status = channel->set_config(config); status != lms::Status::OK)
        {
            std::cerr << "Cannot set configuration" << std::endl;
            return 1;
        }
    }

    return 0;
}

IMU Data Streaming

LibMultiSense supports streaming IMU data from the camera. The IMU must first be configured to enable the desired sensors (accelerometer, gyroscope) and set their sample rates and ranges.

Python

import libmultisense as lms

def main():
    channel_config = lms.ChannelConfig()
    channel_config.ip_address = "10.66.171.21"

    with lms.Channel.create(channel_config) as channel:
        if not channel:
            print("Invalid channel")
            exit(1)

        #
        # Get the current configuration
        #
        config = channel.get_config()

        #
        # Configure the IMU. We first need to get the IMU info to find supported rates and ranges
        #
        info = channel.get_info()
        if not info.imu:
            print("Sensor does not have an IMU")
            exit(1)

        imu_config = lms.ImuConfig()
        imu_config.samples_per_frame = 10 # Number of samples per ImuFrame

        # Enable Accelerometer. Select appropriate rate/range
        if info.imu.accelerometer:
            accel_mode = lms.ImuOperatingMode()
            accel_mode.enabled = True
            accel_mode.rate = info.imu.accelerometer.rates[0]
            accel_mode.range = info.imu.accelerometer.ranges[0]
            imu_config.accelerometer = accel_mode

        # Enable Gyroscope. Select appropriate rate/range
        if info.imu.gyroscope:
            gyro_mode = lms.ImuOperatingMode()
            gyro_mode.enabled = True
            gyro_mode.rate = info.imu.gyroscope.rates[0]
            gyro_mode.range = info.imu.gyroscope.ranges[0]
            imu_config.gyroscope = gyro_mode

        config.imu_config = imu_config
        if channel.set_config(config) != lms.Status.OK:
            print("Failed to set IMU configuration")
            exit(1)

        #
        # Start the IMU stream
        #
        if channel.start_streams([lms.DataSource.IMU]) != lms.Status.OK:
            print("Unable to start IMU stream")
            exit(1)

        while True:
            imu_frame = channel.get_next_imu_frame()
            if imu_frame:
                for sample in imu_frame.samples:
                    if sample.accelerometer:
                        print(f"Accel: x={sample.accelerometer.x}, y={sample.accelerometer.y}, z={sample.accelerometer.z}")
                    if sample.gyroscope:
                        print(f"Gyro: x={sample.gyroscope.x}, y={sample.gyroscope.y}, z={sample.gyroscope.z}")

if __name__ == "__main__":
    main()

C++

#include <iostream>
#include <MultiSense/MultiSenseChannel.hh>

namespace lms = multisense;

int main(int argc, char** argv)
{
    const auto channel = lms::Channel::create(lms::Channel::Config{"10.66.171.21"});
    if (!channel)
    {
        std::cerr << "Failed to create channel" << std::endl;
        return 1;
    }

    //
    // Get the current configuration
    //
    auto config = channel->get_config();

    //
    // Configure the IMU. We first need to get the IMU info to find supported rates and ranges
    //
    const auto info = channel->get_info();
    if (!info.imu)
    {
        std::cerr << "Sensor does not have an IMU" << std::endl;
        return 1;
    }

    lms::MultiSenseConfig::ImuConfig imu_config;
    imu_config.samples_per_frame = 10;

    // Enable Accelerometer
    if (info.imu->accelerometer)
    {
        lms::MultiSenseConfig::ImuConfig::OperatingMode accel_mode;
        accel_mode.enabled = true;
        accel_mode.rate = info.imu->accelerometer->rates[0];
        accel_mode.range = info.imu->accelerometer->ranges[0];
        imu_config.accelerometer = accel_mode;
    }

    // Enable Gyroscope
    if (info.imu->gyroscope)
    {
        lms::MultiSenseConfig::ImuConfig::OperatingMode gyro_mode;
        gyro_mode.enabled = true;
        gyro_mode.rate = info.imu->gyroscope->rates[0];
        gyro_mode.range = info.imu->gyroscope->ranges[0];
        imu_config.gyroscope = gyro_mode;
    }

    config.imu_config = imu_config;
    if (const auto status = channel->set_config(config); status != lms::Status::OK)
    {
        std::cerr << "Failed to set IMU configuration: " << lms::to_string(status) << std::endl;
        return 1;
    }

    //
    // Start the IMU stream
    //
    if (const auto status = channel->start_streams({lms::DataSource::IMU}); status != lms::Status::OK)
    {
        std::cerr << "Cannot start IMU stream: " << lms::to_string(status) << std::endl;
        return 1;
    }

    while(true)
    {
        if (const auto imu_frame = channel->get_next_imu_frame(); imu_frame)
        {
            for (const auto& sample : imu_frame->samples)
            {
                if (sample.accelerometer)
                {
                    std::cout << "Accel: x=" << sample.accelerometer->x
                              << ", y=" << sample.accelerometer->y
                              << ", z=" << sample.accelerometer->z << std::endl;
                }
                if (sample.gyroscope)
                {
                    std::cout << "Gyro: x=" << sample.gyroscope->x
                              << ", y=" << sample.gyroscope->y
                              << ", z=" << sample.gyroscope->z << std::endl;
                }
            }
        }
    }

    return 0;
}

Query Camera Calibration

The camera's internal stereo calibration can be queried from the MultiSense. This calibration corresponds to the full-resolution operating mode of the camera and can be used to rectify raw images or project 3D points.

Python

import libmultisense as lms

def main():
    channel_config = lms.ChannelConfig()
    channel_config.ip_address = "10.66.171.21"

    with lms.Channel.create(channel_config) as channel:
        if not channel:
            print("Invalid channel")
            exit(1)

        # Query the camera calibration. NOTE this is for the full resolution operating mode. Each frame
        # also contains a scaled calibration which can be easier to handle depending on the application
        calibration = channel.get_calibration()

        # Print the intrinsic matrix (K) for the left camera
        print("Left Camera Intrinsic Matrix (K):")
        print(calibration.left.K)

        # Print the rectified projection matrix (P) for the left camera
        print("Left Camera Rectified Projection Matrix (P):")
        print(calibration.left.P)

        # Print the distortion coefficients (D) for the left camera
        print("Left Camera Distortion Coefficients (D):")
        print(calibration.left.D)

        # Access aux camera calibration if present
        if calibration.aux is not None:
             print("Aux Camera Intrinsic Matrix (K):")
             print(calibration.aux.K)

        # Create a Q matrix to convert disparity pixels to 3D point clouds
        Q = lms.QMatrix(calibration.left, calibration.right);
        print(Q.matrix())

if __name__ == "__main__":
    main()

C++

#include <iostream>
#include <MultiSense/MultiSenseChannel.hh>
#include <MultiSense/MultiSenseUtilities.hh>

namespace lms = multisense;

int main(int argc, char** argv)
{
    const auto channel = lms::Channel::create(lms::Channel::Config{"10.66.171.21"});
    if (!channel)
    {
        std::cerr << "Failed to create channel" << std::endl;
        return 1;
    }

    // Query the camera calibration. NOTE this is for the full resolution operating mode. Each frame also contains
    // a scaled calibration which can be easier to handle depending on the application
    const auto calibration = channel->get_calibration();

    // Access intrinsic matrix (K) for the left camera
    std::cout << "Left Camera Intrinsic Matrix (K):" << std::endl;
    for (const auto& row : calibration.left.K)
    {
        for (float val : row)
        {
            std::cout << val << " ";
        }
        std::cout << std::endl;
    }

    // Access rectified projection matrix (P) for the left camera
    std::cout << "Left Camera Rectified Projection Matrix (P):" << std::endl;
    for (const auto& row : calibration.left.P)
    {
        for (float val : row)
        {
            std::cout << val << " ";
        }
        std::cout << std::endl;
    }

    // Generate a Q matrix to convert disparity points to 3D point clouds
    const auto Q = QMatrix(calibration.left, calibration.right);

    return 0;
}

Feature Rendering

LibMultiSense supports retrieving image features computed on-camera. These are synchronized with the corresponding image frames.

The following example demonstrates how to retrieve and render features on a rectified image.

[!NOTE] MultiSense firmware version v7.36 or newer is required to use the onboard feature detector

Python

import libmultisense as lms
import cv2

def main():
    channel_config = lms.ChannelConfig()
    channel_config.ip_address = "10.66.171.21"

    with lms.Channel.create(channel_config) as channel:
        if not channel:
            print("Invalid channel")
            exit(1)

        # Set the feature detector config to enable the feature detector
        config = channel.get_config()
        config.feature_detector_config = lms.FeatureDetectorConfig()
        config.feature_detector_config.number_of_features = 1500
        config.feature_detector_config.grouping_enabled = True
        channel.set_config(config)

        # Start both the rectified image and the corresponding feature stream
        sources = [lms.DataSource.LEFT_MONO_RAW, lms.DataSource.LEFT_ORB_FEATURES]
        if channel.start_streams(sources) != lms.Status.OK:
            print("Unable to start streams")
            exit(1)

        while True:
            frame = channel.get_next_image_frame()
            if frame and frame.has_image(lms.DataSource.LEFT_MONO_RAW):
                img = frame.get_image(lms.DataSource.LEFT_MONO_RAW).as_array

                # Convert grayscale to BGR for color rendering
                display_img = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR)

                if frame.has_feature(lms.DataSource.LEFT_ORB_FEATURES):
                    features = frame.get_feature(lms.DataSource.LEFT_ORB_FEATURES)
                    print(f"Frame {frame.frame_id}: Received {len(features.keypoints)} features")

                    for kp in features.keypoints:
                        cv2.circle(display_img, (int(kp.x), int(kp.y)), 3, (0, 255, 0), -1)

                cv2.imshow("MultiSense Features", display_img)
                if cv2.waitKey(1) & 0xFF == ord('q'):
                    break

if __name__ == "__main__":
    main()

C++

#include <iostream>
#include <opencv2/opencv.hpp>

#include <MultiSense/MultiSenseChannel.hh>
#include <MultiSense/MultiSenseUtilities.hh>

namespace lms = multisense;

int main(int argc, char** argv)
{
    const auto channel = lms::Channel::create(lms::Channel::Config{"10.66.171.21"});
    if (!channel)
    {
        std::cerr << "Failed to create channel" << std::endl;
        return 1;
    }

    //
    // Set the feature detector config to enable the feature detector
    //
    auto config = channel->get_config();
    config.feature_detector_config = lms::MultiSenseConfig::FeatureDetectorConfig{number_of_features, true, 1};
    channel->set_config(config);

    // Start both the rectified image and the corresponding feature stream
    const std::vector<lms::DataSource> sources = {
        lms::DataSource::LEFT_MONO_RAW,
        lms::DataSource::LEFT_ORB_FEATURES
    };

    if (const auto status = channel->start_streams(sources); status != lms::Status::OK)
    {
        std::cerr << "Cannot start streams: " << lms::to_string(status) << std::endl;
        return 1;
    }

    while(true)
    {
        if (const auto frame = channel->get_next_image_frame(); frame)
        {
            if (frame->has_image(lms::DataSource::LEFT_MONO_RAW))
            {
                cv::Mat img = frame->get_image(lms::DataSource::LEFT_MONO_RAW).cv_mat();
                cv::Mat display_img;
                cv::cvtColor(img, display_img, cv::COLOR_GRAY2BGR);

                if (frame->has_feature(lms::DataSource::LEFT_ORB_FEATURES))
                {
                    const auto& features = frame->get_feature(lms::DataSource::LEFT_ORB_FEATURES);

                    // Use the native OpenCV utility to convert keypoints and draw them
                    cv::drawKeypoints(display_img, features.cv_keypoints(), display_img, cv::Scalar(0, 255, 0));
                }

                cv::imshow("MultiSense Features", display_img);
                if (cv::waitKey(1) == 'q') break;
            }
        }
    }

    return 0;
}

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

libmultisense-7.9.0-cp313-cp313-win_amd64.whl (3.1 MB view details)

Uploaded CPython 3.13Windows x86-64

libmultisense-7.9.0-cp313-cp313-win32.whl (2.6 MB view details)

Uploaded CPython 3.13Windows x86

libmultisense-7.9.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (3.1 MB view details)

Uploaded CPython 3.13manylinux: glibc 2.17+ x86-64

libmultisense-7.9.0-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl (3.4 MB view details)

Uploaded CPython 3.13manylinux: glibc 2.17+ i686

libmultisense-7.9.0-cp313-cp313-macosx_11_0_arm64.whl (2.2 MB view details)

Uploaded CPython 3.13macOS 11.0+ ARM64

libmultisense-7.9.0-cp312-cp312-win_amd64.whl (3.1 MB view details)

Uploaded CPython 3.12Windows x86-64

libmultisense-7.9.0-cp312-cp312-win32.whl (2.6 MB view details)

Uploaded CPython 3.12Windows x86

libmultisense-7.9.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (3.1 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.17+ x86-64

libmultisense-7.9.0-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl (3.4 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.17+ i686

libmultisense-7.9.0-cp312-cp312-macosx_11_0_arm64.whl (2.2 MB view details)

Uploaded CPython 3.12macOS 11.0+ ARM64

libmultisense-7.9.0-cp311-cp311-win_amd64.whl (3.1 MB view details)

Uploaded CPython 3.11Windows x86-64

libmultisense-7.9.0-cp311-cp311-win32.whl (2.6 MB view details)

Uploaded CPython 3.11Windows x86

libmultisense-7.9.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (3.1 MB view details)

Uploaded CPython 3.11manylinux: glibc 2.17+ x86-64

libmultisense-7.9.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl (3.4 MB view details)

Uploaded CPython 3.11manylinux: glibc 2.17+ i686

libmultisense-7.9.0-cp311-cp311-macosx_11_0_arm64.whl (2.2 MB view details)

Uploaded CPython 3.11macOS 11.0+ ARM64

libmultisense-7.9.0-cp310-cp310-win_amd64.whl (3.1 MB view details)

Uploaded CPython 3.10Windows x86-64

libmultisense-7.9.0-cp310-cp310-win32.whl (2.6 MB view details)

Uploaded CPython 3.10Windows x86

libmultisense-7.9.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (3.1 MB view details)

Uploaded CPython 3.10manylinux: glibc 2.17+ x86-64

libmultisense-7.9.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl (3.4 MB view details)

Uploaded CPython 3.10manylinux: glibc 2.17+ i686

libmultisense-7.9.0-cp310-cp310-macosx_11_0_arm64.whl (2.2 MB view details)

Uploaded CPython 3.10macOS 11.0+ ARM64

libmultisense-7.9.0-cp39-cp39-win_amd64.whl (3.1 MB view details)

Uploaded CPython 3.9Windows x86-64

libmultisense-7.9.0-cp39-cp39-win32.whl (2.6 MB view details)

Uploaded CPython 3.9Windows x86

libmultisense-7.9.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (3.1 MB view details)

Uploaded CPython 3.9manylinux: glibc 2.17+ x86-64

libmultisense-7.9.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl (3.4 MB view details)

Uploaded CPython 3.9manylinux: glibc 2.17+ i686

libmultisense-7.9.0-cp39-cp39-macosx_11_0_arm64.whl (2.2 MB view details)

Uploaded CPython 3.9macOS 11.0+ ARM64

libmultisense-7.9.0-cp38-cp38-win_amd64.whl (3.1 MB view details)

Uploaded CPython 3.8Windows x86-64

libmultisense-7.9.0-cp38-cp38-win32.whl (2.6 MB view details)

Uploaded CPython 3.8Windows x86

libmultisense-7.9.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (3.1 MB view details)

Uploaded CPython 3.8manylinux: glibc 2.17+ x86-64

libmultisense-7.9.0-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl (3.4 MB view details)

Uploaded CPython 3.8manylinux: glibc 2.17+ i686

libmultisense-7.9.0-cp38-cp38-macosx_11_0_arm64.whl (2.2 MB view details)

Uploaded CPython 3.8macOS 11.0+ ARM64

File details

Details for the file libmultisense-7.9.0-cp313-cp313-win_amd64.whl.

File metadata

File hashes

Hashes for libmultisense-7.9.0-cp313-cp313-win_amd64.whl
Algorithm Hash digest
SHA256 e9530e6c1c0d742a1b4659db779fd697fa450a037fe2b1c45b86856602163fbe
MD5 bae5ac98213688a2fc6339d0277c7920
BLAKE2b-256 68678e22082f015762707765fc3b5db23b5c39b545ebf2b35e6855ed6a20c89e

See more details on using hashes here.

File details

Details for the file libmultisense-7.9.0-cp313-cp313-win32.whl.

File metadata

  • Download URL: libmultisense-7.9.0-cp313-cp313-win32.whl
  • Upload date:
  • Size: 2.6 MB
  • Tags: CPython 3.13, Windows x86
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for libmultisense-7.9.0-cp313-cp313-win32.whl
Algorithm Hash digest
SHA256 5c4b0ac9e41e1b6f92004497a60d2e02875012320018b9c26da811bdc61cfebb
MD5 fc36d18d0d587d08d130d9dff978f0d5
BLAKE2b-256 2f8ed1b1f5530cbde12f98fd4a08de8d05d1d5eb242e20f17dd5d169f39ed935

See more details on using hashes here.

File details

Details for the file libmultisense-7.9.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for libmultisense-7.9.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 876b4428bd606122e21a8cef3c48b08083ab8113770db45f03848ed4d2bb38c1
MD5 8d359ad452e876c72480b7375f4a219d
BLAKE2b-256 5b850420642b3bcaf8549482c54c9c010eb9bd580005af109b26ccef7f6c1cdd

See more details on using hashes here.

File details

Details for the file libmultisense-7.9.0-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl.

File metadata

File hashes

Hashes for libmultisense-7.9.0-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 be298473c5cca1dee3952f360bdd9c783e06c2bbbaee3c0e0ac559ca17cc6ca4
MD5 39b3ef9a2cb55023ed53f916e61a07f5
BLAKE2b-256 f319165d14f759d2291efad3183ca5af5c37cce05673db596db0e4b672cbed71

See more details on using hashes here.

File details

Details for the file libmultisense-7.9.0-cp313-cp313-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for libmultisense-7.9.0-cp313-cp313-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 2fdb2483ce2f59578582f2e87f9cc659c14c67ed11322dc6bc8645359e0ddd2e
MD5 dc5a7e5a5aaf2cbba2ae37ff3f08b03c
BLAKE2b-256 919639697b2ea20fb859cbf006b75a4f841bdbef1059abb57f638a4d864fd994

See more details on using hashes here.

File details

Details for the file libmultisense-7.9.0-cp312-cp312-win_amd64.whl.

File metadata

File hashes

Hashes for libmultisense-7.9.0-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 e8c3f1860ebdd13d9cd8334ae4e9090388711a4233bf8924dc9f26f04beec817
MD5 20e02100c74f2c8ab114f96e3f8c9954
BLAKE2b-256 042d6a408511814d5fd07ff05912a0c06dde6b60194b0e5426dac2f686e5689c

See more details on using hashes here.

File details

Details for the file libmultisense-7.9.0-cp312-cp312-win32.whl.

File metadata

  • Download URL: libmultisense-7.9.0-cp312-cp312-win32.whl
  • Upload date:
  • Size: 2.6 MB
  • Tags: CPython 3.12, Windows x86
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for libmultisense-7.9.0-cp312-cp312-win32.whl
Algorithm Hash digest
SHA256 b5724783d28cb3d5c458e6c6002041deb8dac110d24ba07947fc2d578a239166
MD5 8d84cec88ef23865e9bd1e9e1eb7e76d
BLAKE2b-256 9eee3ad2051fae05cd32be91df64f288c915e8069c04d2fe3bdcc03389fc57e4

See more details on using hashes here.

File details

Details for the file libmultisense-7.9.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for libmultisense-7.9.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 c2506a24c2737b334de331e1af4100bee66537c781b62fb1e379735657e0eece
MD5 57b9b7572324217eae0714cb0ce9405b
BLAKE2b-256 be29e1c74b7f8838bcadc6582b81b48334273e7d30bb535a78e57a582d5531c9

See more details on using hashes here.

File details

Details for the file libmultisense-7.9.0-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl.

File metadata

File hashes

Hashes for libmultisense-7.9.0-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 4ff57b0aa067eaefece9c1e21ba4e7206880fe445ae47b07ad78a6a294c96db8
MD5 ae51ee48c09ea44fc02aff7233367e92
BLAKE2b-256 afed3d84ee3d25a4d9f646ebdf155632af19e507bbddb9a914db38f88a9534f0

See more details on using hashes here.

File details

Details for the file libmultisense-7.9.0-cp312-cp312-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for libmultisense-7.9.0-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 1ad7c435963a0d121b5a83dcf92ef157bd113014d3524d572aaac968bd114df3
MD5 1b71dbf459d0fa8cc68daf6df930542a
BLAKE2b-256 02471a7bfe89e02e4accbe93d501d6fc847284381a76b38c90e4ee0244b52205

See more details on using hashes here.

File details

Details for the file libmultisense-7.9.0-cp311-cp311-win_amd64.whl.

File metadata

File hashes

Hashes for libmultisense-7.9.0-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 21a7a4dc49c1705861d6f3b9a0a2115daa1ae30b720241ef4f5767133de5a515
MD5 965538b450741fa9050c38af774f19f6
BLAKE2b-256 65aea412d091737f7fec5ffe7c658d40db70ddba766ffa50a9868dac40b36693

See more details on using hashes here.

File details

Details for the file libmultisense-7.9.0-cp311-cp311-win32.whl.

File metadata

  • Download URL: libmultisense-7.9.0-cp311-cp311-win32.whl
  • Upload date:
  • Size: 2.6 MB
  • Tags: CPython 3.11, Windows x86
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for libmultisense-7.9.0-cp311-cp311-win32.whl
Algorithm Hash digest
SHA256 919a60aa2dba2be12c520d6c070163a4794ae5247a63386c191f9ffbd146d4ad
MD5 2b6b6f3d97ed402de9331fa12fbd114b
BLAKE2b-256 e7056159a61b96b0a9c18260525ec8f7290a91a9bae5e3ff83fad4f73d2475fd

See more details on using hashes here.

File details

Details for the file libmultisense-7.9.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for libmultisense-7.9.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 1cf4bf3f2edffd1cc6721b799b75fa53402a5e1fe55f34b2dae2c5834e721b99
MD5 9c89f6dcc457804a50616749ab907258
BLAKE2b-256 e653d44f2fd2377a0bb0d2f25ed00b98e740d597688366af558a2c8d703a2b87

See more details on using hashes here.

File details

Details for the file libmultisense-7.9.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl.

File metadata

File hashes

Hashes for libmultisense-7.9.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 c6951e08e8909ad143542b9f0da24db145ab1ac52f2820420bd52ca076f3cbe3
MD5 ddb5e79e99563d552c44d006b5000c55
BLAKE2b-256 a355126f0d673405208f2b9ce4054365e3532dfdc7b47c80b345128d5b7dfb4c

See more details on using hashes here.

File details

Details for the file libmultisense-7.9.0-cp311-cp311-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for libmultisense-7.9.0-cp311-cp311-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 add1287b68633c58e696595f5e45664edb20baf5d36eb24aebaa7a29f0e362ab
MD5 d48a89295b2eff5e2c20077abbe7910f
BLAKE2b-256 f1d3f70eb150ab25081e3d53a4fd18f124e5fbf5aa7b2c5b99ca3c4de9e7b862

See more details on using hashes here.

File details

Details for the file libmultisense-7.9.0-cp310-cp310-win_amd64.whl.

File metadata

File hashes

Hashes for libmultisense-7.9.0-cp310-cp310-win_amd64.whl
Algorithm Hash digest
SHA256 71833df263d56642cce444c420dc570fb778f9378b174cc81bc2cc9cfb1aa8e5
MD5 c6159f65cdc9864fe3f07e1287a2ebac
BLAKE2b-256 7f024a74ca1d4073ea43d26d3c60248ca2b6ec2e9a25f70a5a9b0286358d1e90

See more details on using hashes here.

File details

Details for the file libmultisense-7.9.0-cp310-cp310-win32.whl.

File metadata

  • Download URL: libmultisense-7.9.0-cp310-cp310-win32.whl
  • Upload date:
  • Size: 2.6 MB
  • Tags: CPython 3.10, Windows x86
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for libmultisense-7.9.0-cp310-cp310-win32.whl
Algorithm Hash digest
SHA256 0839e9ae01433456ef5d4de954f571057e8bdab731328dad788283aaefe6cd9f
MD5 007847b4185cbb7e403caef49b8c5c63
BLAKE2b-256 1abceb8fa3d42dd54790a15bba912a266859c2ebbe1ea43a27b99f8116878390

See more details on using hashes here.

File details

Details for the file libmultisense-7.9.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for libmultisense-7.9.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 08d3bd95db6f796038b0e881e4cfc95a2fe6a999542146dcd3fef4c6d31c11c5
MD5 486f9a4d3493ca16860451def27ff769
BLAKE2b-256 78b3d782d00d6a053a5cb033e92b883ed8eb148f51651c8f83907ff5fccea373

See more details on using hashes here.

File details

Details for the file libmultisense-7.9.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl.

File metadata

File hashes

Hashes for libmultisense-7.9.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 61329f33980f7b7888e84f5d733358819a5a4daa8287ddc8758fd3ffaa5eb0ca
MD5 cb8644288e1c7e6511f3ad16e38592b8
BLAKE2b-256 65bb05f74877dc2bdea5ced4d1778a62c7e73479cafbe03cb403452cc7d993b6

See more details on using hashes here.

File details

Details for the file libmultisense-7.9.0-cp310-cp310-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for libmultisense-7.9.0-cp310-cp310-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 5e77bbea369119881e587c866a452df6ca7ee5bb4d74a866b11b429dc0c61fe4
MD5 e1194de6ab9362a648fca4cb4ea87551
BLAKE2b-256 530682fd94f17a023b433e3d37d1525875479d9c459068541b392003a1eac79c

See more details on using hashes here.

File details

Details for the file libmultisense-7.9.0-cp39-cp39-win_amd64.whl.

File metadata

File hashes

Hashes for libmultisense-7.9.0-cp39-cp39-win_amd64.whl
Algorithm Hash digest
SHA256 30b9bc604b10abf0496b3d733465076aed5078d64276d12b8eb2bc15abb6baaf
MD5 6e76676818ff8d248c5f2a1674b6cb00
BLAKE2b-256 3c59866e8dda28ef78497f7aa7e3fa57aad6304d8d4b463fa00e162e31ce1611

See more details on using hashes here.

File details

Details for the file libmultisense-7.9.0-cp39-cp39-win32.whl.

File metadata

  • Download URL: libmultisense-7.9.0-cp39-cp39-win32.whl
  • Upload date:
  • Size: 2.6 MB
  • Tags: CPython 3.9, Windows x86
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for libmultisense-7.9.0-cp39-cp39-win32.whl
Algorithm Hash digest
SHA256 5739106db14e9494b98b63c7d68d83ab1bd58a2d6253cd40365708a0c5317855
MD5 f1e7fa94370c61f41b189f608b8da608
BLAKE2b-256 e4590e71b0afddd9734c4b23be1039e46691797fe2949685fd4433ce514bfcb0

See more details on using hashes here.

File details

Details for the file libmultisense-7.9.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for libmultisense-7.9.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 6ab8bcef1509026debdf2cdedf08dde314546d8993667bee855d49d6920f22d2
MD5 ab04551bbca2ec41ce6ba1f58ef35ac4
BLAKE2b-256 ec38f8df11ef98ed8f72ab9b48b434c22098a6fb9f32733a7592f9d60053d6c2

See more details on using hashes here.

File details

Details for the file libmultisense-7.9.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl.

File metadata

File hashes

Hashes for libmultisense-7.9.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 43741f3ee31d22436f43dae3d6c446b7301147c67e7903d675d75aff3545df4d
MD5 60cd8e8cb90f0e5bf80a3984d5e1c704
BLAKE2b-256 6683b72d2bd44897ff2dc641f0a9afefcb4040193b0c7ff5e0960e8dfc96ea5f

See more details on using hashes here.

File details

Details for the file libmultisense-7.9.0-cp39-cp39-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for libmultisense-7.9.0-cp39-cp39-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 a475adf53b05acbcbf407010390c91c0badbe8c39ea18247d1e1ad6b9719e039
MD5 ae04f33262ad56f5d5a2db4c08613b08
BLAKE2b-256 b8799b883fe294c75d2f2a66247078cef3aecf5e695568df80f1b9815267e5c4

See more details on using hashes here.

File details

Details for the file libmultisense-7.9.0-cp38-cp38-win_amd64.whl.

File metadata

File hashes

Hashes for libmultisense-7.9.0-cp38-cp38-win_amd64.whl
Algorithm Hash digest
SHA256 66f081a79bbd7e64ae88feecfa55088289852ebc1bb9a5153042e853cb046d41
MD5 33b3d5737b4c40e7eae0c712e24f96df
BLAKE2b-256 7f52292caf42db21cdfbaed9f7f0068394ea2e96d25e8f23e182091c1800906c

See more details on using hashes here.

File details

Details for the file libmultisense-7.9.0-cp38-cp38-win32.whl.

File metadata

  • Download URL: libmultisense-7.9.0-cp38-cp38-win32.whl
  • Upload date:
  • Size: 2.6 MB
  • Tags: CPython 3.8, Windows x86
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for libmultisense-7.9.0-cp38-cp38-win32.whl
Algorithm Hash digest
SHA256 5f357c77db5deba523b3a136e65a8192da6d11fc3206b1b19b1f043201b2e9bb
MD5 d026ae7e17be506762f75d04d5b3b3d1
BLAKE2b-256 06f564b437e10f2d36c4aa61d48eba9645413fa82cc6c14006b30726c8799f2f

See more details on using hashes here.

File details

Details for the file libmultisense-7.9.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for libmultisense-7.9.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 e9a359d5f50e4c0ac40923bf4ca9f007996c95dd09e1e74d8e38ea21cfd145cb
MD5 fae14480802e743a0e058ef9ab210250
BLAKE2b-256 79306567da06f8d80dc7be0add9ccbe9b8d4a233b68591d0052634c915c9d542

See more details on using hashes here.

File details

Details for the file libmultisense-7.9.0-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl.

File metadata

File hashes

Hashes for libmultisense-7.9.0-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 9003057b84d645dfd3b6ca24a6b966a49ee1ee5a9b47220d7588a25479f8e250
MD5 c634157da1e089416fd33ddd20aed107
BLAKE2b-256 25795dbf9f2735e56b4822aafda7e3bedcfa9ac133245321298b9ea7ec62bcb1

See more details on using hashes here.

File details

Details for the file libmultisense-7.9.0-cp38-cp38-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for libmultisense-7.9.0-cp38-cp38-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 a59f15144205e67dcb04a50a444fbf9b08ab6273da5f97a4ef8ab2eb4d171465
MD5 7823c2f79f5c2226cc18063c36108012
BLAKE2b-256 93f7af0525c59e53cd8a002d4cd4100cbac8e960520682dfe2515a28af113cb5

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page