LoginSignup
14
8

More than 3 years have passed since last update.

RealSenseをcv2.VideoCaptureライクに使う

Last updated at Posted at 2019-09-20

RealSenseとは

Intelが作っているDepthカメラシリーズです。
今回D415を使います。
このRealSenseをOpenCVで使うとき、通常のWebカメラと同じように cv2.VideoCapture(0) とできなくて面倒だったので、VideoCaptureと同じように使えるクラスを作成しました。

依存関係

  • pyrealsense2
  • numpy

どちらもpipでインストールできます。

2019/10/11 追記

MacやJetson Nanoなど,ArmチップのCPUではpipでpyrealsense2がインストールできないようです.sourceからbuildする必要があります.

コード

下記のクラスが cv2.VideoCapture の代わりになるものです。

realsensecv.py
import pyrealsense2 as rs
import numpy as np


class RealsenseCapture:

    def __init__(self):
        self.WIDTH = 640
        self.HEGIHT = 480
        self.FPS = 30
        # Configure depth and color streams
        self.config = rs.config()
        self.config.enable_stream(rs.stream.color, self.WIDTH, self.HEGIHT, rs.format.bgr8, self.FPS)
        self.config.enable_stream(rs.stream.depth, self.WIDTH, self.HEGIHT, rs.format.z16, self.FPS)

    def start(self):
        # Start streaming
        self.pipeline = rs.pipeline()
        self.pipeline.start(self.config)
        print('pipline start')

    def read(self, is_array=True):
        # Flag capture available
        ret = True
        # get frames
        frames = self.pipeline.wait_for_frames()
        # separate RGB and Depth image
        self.color_frame = frames.get_color_frame()  # RGB
        self.depth_frame = frames.get_depth_frame()  # Depth

        if not self.color_frame or not self.depth_frame:
            ret = False
            return ret, (None, None)
        elif is_array:
            # Convert images to numpy arrays
            color_image = np.array(self.color_frame.get_data())
            depth_image = np.array(self.depth_frame.get_data())
            return ret, (color_image, depth_image)
        else:
            return ret, (self.color_frame, self.depth_frame)

    def release(self):
        # Stop streaming
        self.pipeline.stop()

今回 realsensecv.py という名前で保存して、他のファイルからimportします。

Example

上記のクラスを用いてリアルタイムに映像を出力してみます。

rs_streaming.py
# coding: utf-8
import cv2
import numpy as np
from realsensecv import RealsenseCapture


cap = RealsenseCapture()
# プロパティの設定
cap.WIDTH = 640
cap.HEIGHT = 480
cap.FPS = 30
# cv2.VideoCapture()と違ってcap.start()を忘れずに
cap.start()

while True:
    ret, frames = cap.read()  # frames[0]にRGB、frames[1]にDepthの画像がndarrayが入っている
    color_frame = frames[0]
    depth_frame = frames[1]
    # ヒートマップに変換
    depth_colormap = cv2.applyColorMap(cv2.convertScaleAbs(
        depth_frame, alpha=0.08), cv2.COLORMAP_JET)
    # レンダリング
    images = np.hstack((color_frame, depth_colormap))  # RGBとDepthを横に並べて表示
    cv2.imshow('RealSense', images)

    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

# ストリーミング停止
cap.release()
cv2.destroyAllWindows()

pyrealsense2ではdepth_frameから距離を取得する get_distance メソッドなどがありますが、RealsenseCaptureで出力されるdepth_frameにはそのメソッドはありません。
get_distance などを使いたい場合は、インスタンス変数にアクセスしてください。

下記にクリックしたピクセルの距離を取得する例を載せます。

get_distance.py
# coding: utf-8

import cv2
import numpy as np
from realsensecv import RealsenseCapture


# マウスイベント時に処理を行う
def mouse_event(event, x, y, flags, param):
    depth_frame = param
    distance = depth_frame.get_distance(x, y)
    # 左クリックで座標を返す
    if event == cv2.EVENT_LBUTTONUP:
        return print(distance)

cap = RealsenseCapture()
cap.start()

while True:
    ret, frames = cap.read()
    color_frame = frames[0]
    depth_frame = frames[1]
    # ヒートマップに変換
    depth_colormap = cv2.applyColorMap(cv2.convertScaleAbs(
        depth_frame, alpha=0.08), cv2.COLORMAP_JET)
    # レンダリング
    images = np.hstack((color_frame, depth_colormap))
    cv2.namedWindow('RealSense', cv2.WINDOW_AUTOSIZE)
    cv2.imshow('RealSense', images)

    # マウスイベント時に関数mouse_eventの処理を行う
    cv2.setMouseCallback('RealSense', mouse_event, cap.depth_frame)

    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

# ストリーミング停止
cap.release()
cv2.destroyAllWindows()

これでVideoCaptureのように使えて、既存のコードを簡単に使いまわせるようになりました!
ミスや改善点などあればコメントお願いしますm(_ _)m

14
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
8