콘텐츠로 바로 가기
STAGING SERVER
DEVELOPMENT SERVER

타사 드라이버, 라이브러리 및 샘플#

이 페이지에서는 Basler Stereo mini 카메라를 사용하기 위한 타사 라이브러리 정보와 예제 코드를 제공합니다.

NumPy#

파이썬 예제에서는 pypylon이 반환하는 원시 구성 요소 데이터를 처리하기 위해 NumPy를 사용합니다.

pip install numpy

OpenCV#

OpenCV를 사용하면 Stereo mini 카메라에서 가져온 강도 이미지를 처리할 수 있습니다. 강도 구성 요소는 RGBA8 이미지를 제공하며, 이 이미지는 OpenCV 처리에 적합한 형식으로 변환할 수 있습니다.

pip install opencv-python

예시: 강도 성분을 OpenCV 이미지로 변환하기

import cv2
import numpy as np
from pypylon import pylon

# ... camera setup (see Python Programmer's Guide) ...

data_container = grab_result.GetDataContainer()
for i in range(data_container.DataComponentCount):
    component = data_container.GetDataComponentByIndex(i)
    try:
        if component.ComponentType == pylon.ComponentType_Intensity:
            raw = component.GetData()
            h, w = component.Height, component.Width
            # Stereo mini intensity is RGBA8
            rgba = np.frombuffer(raw, dtype=np.uint8).reshape(h, w, 4)
            bgr = cv2.cvtColor(rgba, cv2.COLOR_RGBA2BGR)
            cv2.imshow("Intensity", bgr)
            cv2.waitKey(1)
    finally:
        component.Release()

자세한 내용은 OpenCV를 참조하십시오.

Open3D#

Open3D는 다음에서 사용됩니다. ShowPointCloud Stereo mini 카메라에서 얻은 3D 포인트 클라우드를 시각화하는 예제입니다. 의 거리 성분은 Coord3D_ABC32f 이 형식은 직접적인 XYZ 좌표를 제공합니다.

pip install open3d

예시: 거리 및 강도 데이터를 기반으로 Open3D 포인트 클라우드를 생성하기

import numpy as np
import open3d as o3d
from pypylon import pylon

# ... camera setup with ComponentSelector Range, PixelFormat Coord3D_ABC32f ...

data_container = grab_result.GetDataContainer()
xyz = None
colors = None

for i in range(data_container.DataComponentCount):
    component = data_container.GetDataComponentByIndex(i)
    try:
        if component.ComponentType == pylon.ComponentType_Range:
            h, w = component.Height, component.Width
            raw = component.GetData()
            pts = np.frombuffer(raw, dtype=np.float32).reshape(h * w, 3)
            valid = np.isfinite(pts).all(axis=1)
            xyz = pts[valid]
        elif component.ComponentType == pylon.ComponentType_Intensity:
            h, w = component.Height, component.Width
            raw = component.GetData()
            rgba = np.frombuffer(raw, dtype=np.uint8).reshape(h * w, 4)
            colors = rgba[..., :3].astype(np.float64) / 255.0
    finally:
        component.Release()

if xyz is not None and colors is not None:
    pcd = o3d.geometry.PointCloud()
    pcd.points = o3d.utility.Vector3dVector(xyz)
    pcd.colors = o3d.utility.Vector3dVector(colors[:len(xyz)])
    o3d.visualization.draw_geometries([pcd])

자세한 내용은 Open3D를 참조하십시오.

Point Cloud Library (PCL)#

PCL은 고급 3D 포인트 클라우드 처리에 사용할 수 있습니다. Stereo mini 카메라에서 얻은 거리 데이터는 Coord3D_ABC32f 이 형식은 PCL 데이터 구조에 입력될 수 있습니다.

sudo apt-get install libpcl-dev

Download from PCL website.

자세한 내용은 『 C++ 프로그래머 가이드』를 참조하십시오.

ROS 2#

Stereo mini 카메라는 다음을 사용하여 ROS 2에 통합할 수 있습니다. pypylon 다리 역할과 출판으로서 sensor_msgs/Image 주제.

필수 패키지:

pip install pypylon numpy
sudo apt install ros-humble-rclpy ros-humble-sensor-msgs

이 접근 방식에서는 Stereo mini 데이터 구성 요소에서 이미지 데이터를 읽어옵니다 (Intensity, Range)를 처리하여 ROS 토픽에 게시합니다. 예를 들어:

  • /stereo_mini/intensity_rgba8 (인코딩 rgba8)
  • /stereo_mini/range_c16_mm (인코딩 mono16)

최소한의 브리지 예제:

import numpy as np
import rclpy
from rclpy.node import Node
from sensor_msgs.msg import Image
from pypylon import pylon


class StereoMiniBridge(Node):
    def __init__(self):
        super().__init__("stereo_mini_bridge")
        self.pub_intensity = self.create_publisher(Image, "/stereo_mini/intensity_rgba8", 10)

        di = pylon.DeviceInfo()
        di.SetDeviceClass("BaslerGTC/Basler/TLModel_keep")
        self.camera = pylon.InstantCamera(pylon.TlFactory.GetInstance().CreateFirstDevice(di))
        self.camera.Open()

        self.camera.ComponentSelector.Value = "Intensity"
        self.camera.ComponentEnable.Value = True
        try:
            self.camera.PixelFormat.Value = "RGBA8"
        except Exception:
            self.camera.PixelFormat.Value = "RGBA8packed"

        self.camera.StartGrabbing()
        self.timer = self.create_timer(0.03, self.tick)

    def tick(self):
        grab = self.camera.RetrieveResult(3000, pylon.TimeoutHandling_ThrowException)
        try:
            if not grab.GrabSucceeded():
                return
            dc = grab.GetDataContainer()
            for i in range(dc.DataComponentCount):
                c = dc.GetDataComponentByIndex(i)
                try:
                    if c.ComponentType == pylon.ComponentType_Intensity:
                        h, w = c.Height, c.Width
                        rgba = np.frombuffer(c.GetData(), dtype=np.uint8).reshape(h, w, 4)
                        msg = Image()
                        msg.header.stamp = self.get_clock().now().to_msg()
                        msg.header.frame_id = "stereo_mini"
                        msg.height = h
                        msg.width = w
                        msg.encoding = "rgba8"
                        msg.is_bigendian = 0
                        msg.step = w * 4
                        msg.data = rgba.tobytes()
                        self.pub_intensity.publish(msg)
                finally:
                    c.Release()
        finally:
            grab.Release()


def main():
    rclpy.init()
    node = StereoMiniBridge()
    rclpy.spin(node)


if __name__ == "__main__":
    main()