はじめに
前回は realsense を動かす Python のベースプログラムを作成しました。
今回は、カメラのズレ補正や背景削除について説明していきます。
前提条件
前提条件は以下の通りです。
- pyrealsense2 がインストールされている
- OpenCV ==4.6.0
- Python == 3.9.13
今回はこちらの公式ページを参考に進めていきます。
コード掲載と起動
今回使用するコードはこちらを参考にしました。
## License: Apache 2.0. See LICENSE file in root directory.
## Copyright(c) 2017 Intel Corporation. All Rights Reserved.
#####################################################
##              Align Depth to Color               ##
#####################################################
# First import the library
import pyrealsense2 as rs
# Import Numpy for easy array manipulation
import numpy as np
# Import OpenCV for easy image rendering
import cv2
# Create a pipeline
pipeline = rs.pipeline()
# Create a config and configure the pipeline to stream
#  different resolutions of color and depth streams
config = rs.config()
# Get device product line for setting a supporting resolution
pipeline_wrapper = rs.pipeline_wrapper(pipeline)
pipeline_profile = config.resolve(pipeline_wrapper)
device = pipeline_profile.get_device()
device_product_line = str(device.get_info(rs.camera_info.product_line))
found_rgb = False
for s in device.sensors:
    if s.get_info(rs.camera_info.name) == 'RGB Camera':
        found_rgb = True
        break
if not found_rgb:
    print("The demo requires Depth camera with Color sensor")
    exit(0)
config.enable_stream(rs.stream.depth, 640, 480, rs.format.z16, 30)
if device_product_line == 'L500':
    config.enable_stream(rs.stream.color, 960, 540, rs.format.bgr8, 30)
else:
    config.enable_stream(rs.stream.color, 640, 480, rs.format.bgr8, 30)
# Start streaming
profile = pipeline.start(config)
# Getting the depth sensor's depth scale (see rs-align example for explanation)
depth_sensor = profile.get_device().first_depth_sensor()
depth_scale = depth_sensor.get_depth_scale()
print("Depth Scale is: " , depth_scale)
# We will be removing the background of objects more than
#  clipping_distance_in_meters meters away
clipping_distance_in_meters = 1 #1 meter
clipping_distance = clipping_distance_in_meters / depth_scale
# Create an align object
# rs.align allows us to perform alignment of depth frames to others frames
# The "align_to" is the stream type to which we plan to align depth frames.
align_to = rs.stream.color
align = rs.align(align_to)
# Streaming loop
try:
    while True:
        # Get frameset of color and depth
        frames = pipeline.wait_for_frames()
        # frames.get_depth_frame() is a 640x360 depth image
        # Align the depth frame to color frame
        aligned_frames = align.process(frames)
        # Get aligned frames
        aligned_depth_frame = aligned_frames.get_depth_frame() # aligned_depth_frame is a 640x480 depth image
        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
        grey_color = 153
        depth_image_3d = np.dstack((depth_image,depth_image,depth_image)) #depth image is 1 channel, color is 3 channels
        bg_removed = np.where((depth_image_3d > clipping_distance) | (depth_image_3d <= 0), grey_color, color_image)
        # Render images:
        #   depth align to color on left
        #   depth on right
        depth_colormap = cv2.applyColorMap(cv2.convertScaleAbs(depth_image, alpha=0.03), cv2.COLORMAP_JET)
        images = np.hstack((color_image, bg_removed))
        images = np.hstack((images, depth_colormap))
        images = cv2.resize(images, (1280, 480))
        cv2.imshow('Align Example', images)
        key = cv2.waitKey(1)
        # Press esc or 'q' to close the image window
        if key & 0xFF == ord('q') or key == 27:
            cv2.destroyAllWindows()
            break
finally:
    pipeline.stop()上記プログラムを実行すると、以下のような画面が表示されます。

左から BGR画像、背景削除BGR画像、深度BGR画像 となります。
コード説明
背景削除
コード説明に移ります。
前回説明した部分は、飛ばして説明します。
# Getting the depth sensor's depth scale (see rs-align example for explanation)
depth_sensor = profile.get_device().first_depth_sensor()
depth_scale = depth_sensor.get_depth_scale()
print("Depth Scale is: " , depth_scale)first_depth_sensor() で深度センサのインスタンスを作成します。
get_depth_scale() で、現実の (m) と 深度センサ値 の変換係数を取得します。
詳細はこちらの公式サイトにあります。
# We will be removing the background of objects more than
#  clipping_distance_in_meters meters away
clipping_distance_in_meters = 1 #1 meter
clipping_distance = clipping_distance_in_meters / depth_scale変換係数を使用して、1(m) / 係数 でクリッピングする深度センサ値を決定します。
bg_removed = np.where((depth_image_3d > clipping_distance) | (depth_image_3d <= 0), grey_color, color_image)np.where() を使用して、1m より遠くのBGR画像を削除することができます。
BGR画像と深度センサ値の整列
# Create an align object
# rs.align allows us to perform alignment of depth frames to others frames
# The "align_to" is the stream type to which we plan to align depth frames.
align_to = rs.stream.color
align = rs.align(align_to)align の公式サイトの説明はこちらにあります。
BGR画像と深度センサ値を揃えることができます。
# Align the depth frame to color frame
aligned_frames = align.process(frames)wait_for_frames() で取得した frames に対して整列を実行することができます。
背景削除の効果について
背景削除の効果についてですが、障害物の影まで深度センサは届かないので、背景として削除されてしまいます。

上図の赤枠の部分です。
深度センサ間の距離が限られている以上、赤枠の部分は画像処理ではどうにもなりません。
実運用の際は赤枠のような領域ができないように注意が必要です。
おわりに
今回は、背景削除の方法と、BGR画像と深度画像の整列について説明をしました。
次回は、realsense の他の機能・モードについて説明をする予定です。
 
  
  
  
  



コメント