リネオブログ

Intel Realsense を動かしてみよう #2

2023 年 02 月 13 日   Linux 技術ネタ

目次

  1. はじめに
  2. Advantech RSB-3720 について
  3. ボードのセットアップ
  4. RSB-3720 起動イメージの構築
  5. Intel RealSense を動かす
  6. まとめ

1. はじめに

第 2 部では、Advantech 社から提供されている RSB-3720 ボードに対して、Intel RealSense™ depth camera D435 を使用するための、起動イメージの構築、RealSense SDK のインストール、Python を用いた自作プログラム実装の流れを説明します。

前回:Intel Realsenseを動かしてみよう #1

2. Advantech RSB-3720 について

RSB-3720 は、Advantech 社が開発した ARM プロセッサ搭載の小型モジュールです。主な機能としては

  • 最大 1.8GHz の NXP Arm® Cortex®-A53 i.MX8M Plus 搭載(クアッド/デュアル)
  • LPDDR4 4 GB / 6 GB、4000M/s メモリをオンボード
  • HDMI (1920x1080/60Hz)、1~2x 24 ビット LVDS (BOMオプションで1x 4レーンMIPI-DSI)
  • 1x 4 線式 RS-232 / 422 / 485、1x USB3.2 Gen1、1x USB2.0、1x マイクロ SD
  • 1x ミニ PCIe (3G / 4G向け)、1 つの M.22230 キー E スロット
  • Yocto Linux・Android をサポート
  • I/O 拡張ボード「UIO40-Express」搭載

といったものがあります。

Memory On-board LDDDR4 4GB/6GB
CPU NXP i.MX8M Plus Cortex-A53 Quad/Dual core(up to 1.8GHz)
Linux Yocto Linux & Android
Power Supply Voltage 12V
Power Consumption 7.13W (Max)
Dimension (mm) 100 x 72 x 19 mm

3. ボードのセットアップ

3.1 起動手順

各機器、ケーブルを 3.2 節の接続図のように接続します。
電源ケーブルを接続すると、すぐにボードが起動します。起動スイッチはありません。SW1 は起動方式を選択するためのスイッチです。以下の表のように設定します。(上:ON 下:OFF)

起動方式 SW1-1 SW1-2 SW1-3 SW1-4
emmc ブート OFF ON OFF OFF
SD ブート ON ON OFF OFF

USB ポートにキーボードやマウスを接続すると、HDMI ディスプレイ上の GUI の操作を行うことができます。
SD カードに書き込むイメージについては、次章で説明します。

3.2 接続図

各種機器やケーブルは以下の図のように接続します。

各種機器やケーブの接続図

4. RSB-3720 起動イメージの構築

4.1 Ubuntu イメージの入手と構築

ホストPC (Ubuntu20.04.1 LTS) にて、起動イメージの構築作業を行います。Advantech が提供しているUbuntu イメージを以下のリンクからダウンロードします。

起動用 SD カードに Ubuntu イメージを書き込みます。

$ gzip -d 3720A1AIM30UIVA0362_iMX8MP_6G_2021-11-29.img.gz
SDカードのデバイス名が /dev/sdx の場合
$ sudo dd if=3720A1AIM30UIVA0362_iMX8MP_6G_2021-11-29.img of=/dev/sdx bs=1M conv=fsync

4.2 起動確認

Ubuntu イメージを書き込んだ SD カードをターゲットボードに差し込み、起動確認を行います。

以下より、RSB-3720 上でのコマンド操作を背景黄色で表現します。 次のユーザでログインできることを確認します。

imx8mprsb3720a1 login: adv
Password: adv
adv@imx8mprsb3720a1:~$

ディストリビューションのバージョンを確認します。

$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 18.04.6 LTS
Release: 18.04
Codename: bionic

5. Intel RealSenseを動かす

SD カード内の Ubuntu (aarch64) イメージに対して RealSense SDK の導入を行い、自作プログラムを実装します。

5.1 realsense-viewer の起動

5.1.1 RealSense SDK のインストール

必要なパッケージをインストールします。

$ sudo apt update && sudo apt upgrade
$ sudo apt install git libssl-dev libusb-1.0-0-dev pkg-config libgtk-3-dev \
libglfw3-dev cmake freeglut3-dev

Github から RealSense SDK のソースファイルをダウンロードして、ビルドとインストールを行います。

$ git clone https://github.com/intelrealsense/librealsense
$ mkdir -p librealsense/build
$ cd librealsense
$ sudo cp config/99-realsense-libusb.rules /etc/udev/rules.d/
$ sudo udevadm control --reload-rules && udevadm trigger
$ cd build
$ cmake ..
$ make -j4
$ sudo make install
5.1.2 realsense-viewer の起動

以下のコマンドより realsense-viewer が起動します。

$ realsense-viewer

以下のような Depth カメラと RGB カメラの映像が表示されれば、OK です。

Depth カメラと RGB カメラの映像

5.2 Python を用いた自作プログラムの実装

いよいよ本題となる、Python を用いた自作プログラムの実装にチャレンジしていきます。

5.2.1 Python モジュールのインストール

Python 本体と pip をインストールします。

$ sudo apt-get install python3 python3-dev
$ sudo apt install wget
$ wget https://bootstrap.pypa.io/get-pip.py
$ python3 get-pip.py

後に使用するモジュールをインストールします。

$ python3 -m pip install numpy
$ python3 -m pip install opencv-python

Intel RealSense SDK 内に用意されている Python モジュールをビルドしてインストールします。

$ cd ~/librealsense/build
$ cmake ../ -DBUILD_PYTHON_BINDINGS:bool=true
$ make -j4
$ sudo make install

標準に設定されている Python のバージョンを確認して、そのバージョンで指定されたライブラリ内に RealSense 用の so ファイルが生成されていることを確認します。

$ python3 -version
Python 3.6.9

$ ls -la /usr/local/lib/python3.6/pyrealsense2/
total 30232
-rw-r--r-- 1 root staff 13232368 Nov 29 02:29 pybackend2.cpython-36m-aarch64-lin ux-gnu.so.2.51.1
-rw-r--r-- 1 root staff 17713584 Nov 29 02:33 pyrealsense2.cpython-36m-aarch64-l inux-gnu.so.2.51.1
...

Python の site-packages に生成された so ファイルのシンボリックリンクを作成します。

$ cd ~/.local/lib/python3.6/site-packages/
$ sudo ln -s /usr/local/lib/python3.6/pyrealsense2/pybackend2.cpython-36m-aarch64-linux-gnu.so.2.51.1 pybackend2.so
$ sudo ln -s /usr/local/lib/python3.6/pyrealsense2/pyrealsense2.cpython-36m-aarch64-linux-gnu.so pyrealsense2.so
5.2.2 サンプルプログラムの動作確認

Intel RealSense SDK 内に用意されているサンプルプログラムを動かしてみます。

$ cd ~/librealsense/wrappers/python/exampes/
$ python3 opencv_viewer_example.py
$ python3 align-depth2color.py
opencv_viewer_example.py の表示

RGB カメラと Depth カメラの映像が表示されます。

RGB カメラと Depth カメラの映像

align-depth2color.py の表示

RGB カメラの背景画像が深度情報よりフィルタリングされます。

RGB カメラの背景画像

5.2.3 自作プログラムの作成と実装

SDK 内のサンプルプログラムが動作することが確認できましたので、RealSense の Python 環境構築は問題なさそうです。
そこで、自作プログラムの作成をトライしてみます。まずはワークスペースを準備します。

$ mkdir -p ~/workspace
$ cd ~/workspace
$ touch my_program1.py

サンプルプログラムを参考にし、RealSense に搭載されている 4 つのカメラ (IR1, IR2, Depth, RGB) の映像を表示するプログラムを作成しました。

my_program1.py
import pyrealsense2 as rs
import numpy as np
import cv2

# ストリームの設定
config = rs.config()
config.enable_stream(rs.stream.infrared, 1, 640, 480, rs.format.y8, 30)
config.enable_stream(rs.stream.infrared, 2, 640, 480, rs.format.y8, 30)
config.enable_stream(rs.stream.color, 640, 480, rs.format.bgr8, 30)
config.enable_stream(rs.stream.depth, 640, 480, rs.format.z16, 30)

# ストリーミング開始
pipeline = rs.pipeline()
pipeline.start(config)

try:
    while True:
        # フレーム待ち
        frames = pipeline.wait_for_frames()

        #IR1
        ir_frame1 = frames.get_infrared_frame(1)
        ir_image1 = np.asanyarray(ir_frame1.get_data())

        #IR2
        ir_frame2 = frames.get_infrared_frame(2)
        ir_image2 = np.asanyarray(ir_frame2.get_data())

        # RGB
        color_frame = frames.get_color_frame()
        color_image = np.asanyarray(color_frame.get_data())

        # 深度
        depth_frame = frames.get_depth_frame()
        depth_image = np.asanyarray(depth_frame.get_data())

        # 2次元データをカラーマップに変換
        ir_colormap1   = cv2.applyColorMap(cv2.convertScaleAbs(ir_image1), cv2.COLORMAP_JET)
        ir_colormap2   = cv2.applyColorMap(cv2.convertScaleAbs(ir_image2), cv2.COLORMAP_JET)
        depth_colormap = cv2.applyColorMap(cv2.convertScaleAbs(depth_image, alpha=0.02), cv2.COLORMAP_JET)

        # イメージの結合
        images = np.vstack(( np.hstack((ir_colormap1, ir_colormap2)), np.hstack((color_image, depth_colormap)) ))

        # 表示
        cv2.namedWindow('RealSense', cv2.WINDOW_AUTOSIZE)
        cv2.imshow('RealSense', images)

        # q キー入力で終了
        if cv2.waitKey(1) & 0xFF == ord('q'):
            cv2.destroyAllWindows()
            break

finally:
    # ストリーミング停止
    pipeline.stop()

表示した映像が以下となります。上 2 つが赤外線カメラ (IR1, IR2)、左下が RGB カメラ、右下が Depth カメラの映像となります。

上 2 つが赤外線カメラ (IR1, IR2)、左下が RGB カメラ、右下が Depth カメラの映像

5.2.4 応用実装(距離の測定)

応用編として、RealSense から物体までの距離を測定するプログラムを作成しました。

my_program2.py
import pyrealsense2 as rs
import numpy as np
import cv2

# ストリームの設定
config = rs.config()
config.enable_stream(rs.stream.color, 640, 480, rs.format.bgr8, 30)
config.enable_stream(rs.stream.depth, 640, 480, rs.format.z16, 30)

# ストリーミング開始
pipeline = rs.pipeline()
pipeline.start(config)

# Alignオブジェクト生成
align_to = rs.stream.color
align = rs.align(align_to)

try:
    while True:
        # フレーム待ち
        frames = pipeline.wait_for_frames()

        # RGBとDepthの位置ずれを修正
        aligned_frames = align.process(frames)

        # RGB
        color_frame = aligned_frames.get_color_frame()
        color_image = np.asanyarray(color_frame.get_data())

        # 深度
        depth_frame = aligned_frames.get_depth_frame()
        depth_image = np.asanyarray(depth_frame.get_data())        

        # 2次元データをカラーマップに変換
        depth_colormap = cv2.applyColorMap(cv2.convertScaleAbs(depth_image, alpha=0.02), cv2.COLORMAP_JET)

        ### 画像処理 ###

        # ポイントで指定した箇所の奥行きを計算
        px = 320
        py = 240
        depth_data = depth_frame.get_distance(px, py)

        # ポイントにマーカーと距離を表示
        depth_str = str(round(depth_data, 2)) + "m"
        cv2.drawMarker(color_image, (px,py), (0,0,255))
        cv2.putText(color_image, depth_str, (px,py), cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0,0,255), thickness=2)
        cv2.drawMarker(depth_colormap, (px,py), (0,0,255))
        cv2.putText(depth_colormap, depth_str, (px,py), cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0,0,255), thickness=2)

        ### 画像処理 end ### 

        # イメージの結合
        images = np.hstack((color_image, depth_colormap))

        # 表示
        cv2.namedWindow('RealSense', cv2.WINDOW_AUTOSIZE)
        cv2.imshow('RealSense', images)

        # q キー入力で終了
        if cv2.waitKey(1) & 0xFF == ord('q'):
            cv2.destroyAllWindows()
            break

finally:
    # ストリーミング停止
    pipeline.stop()

カメラから 50cm 間隔で時計を配置し、距離を計測します。

50cm 間隔で時計を配置し、距離を計測

50cm 間隔で時計を配置し、距離を計測 2

表示された映像が以下となります。

画面中央にあるマーカーの画素で奥行を測定しています。測定データを元に距離 (m) データに変換し、画面上に表示しています。

0.5m

1.01m

1.5m

6. まとめ

RSB-3720 上でも、第 1 回目と同様に RealSense カメラの動作環境を構築することができました。
今回はサンプルアプリケーションだけでなく、Python を用いて自作したプログラムでカメラ表示を行ってみましたが、比較的容易にプログラムを書くことができ、開発の幅が広がったと感じます。
Python からの制御ができるメリットとして、ML ソフトウェア開発との親和性があると考えます。

NXP i.MX8M Plus の Linux 環境では、NXP 社から ML ソフトウェア開発のベースプラットフォームとして、eIQ® ML ソフトウェア開 success 発環境 が提供されています。
eIQ を活用することで、ML ソフトウェア開発への着手が容易となります。

  • メジャーな ML 推論エンジンが使用できる環境がすぐに用意できる(DeepViewRT™、TendorFlow™、etc...)
  • ビッグデータを用意しなくても ML 推論エンジンの評価が可能

NXP i.MX8M Plus をベースとしている、RSB-3720 の BSP (Advantech) でも、eIQ で ML ソフトウェアが構築可能です。

また、ML ソフトウェアは基本的に Python アプリケーションで構成されるため、Intel RealSense と組み合わせることで、物体検出、認識など ML ソフトウェアの開発の加速が期待できます。

■ Intel RealSense が活躍する場面
  • ロボットの目として (対象物・障害物との距離の測定、地形把握)
  • 顔認証の精度向上 (セキュリティ認証の強化)
Yocto Project 公式実践講座 5 月 ~ 7 月 開催分 受講お申込み受付中!
Vigiles サポート
Yocto Project よもやま話
Yocto よもやま話 第 14 回 「Yocto 4.3 Nanbield リリース」
Yocto よもやま話 第 14 回 「Yocto 4.3 Nanbield リリース」

2024 年 03 月 26 日 Yocto Project よもやま話

Yocto よもやま話 第 13 回 「Yocto Project の最新動向 2023 夏」
Yocto よもやま話 第 13 回 「Yocto Project の最新動向 2023 夏」

2023 年 07 月 25 日 Yocto Project よもやま話

Yocto よもやま話 第 12 回 「Yocto Project 始めます その 2」
Yocto よもやま話 第 12 回 「Yocto Project 始めます その 2」

2023 年 06 月 20 日 Yocto Project よもやま話

Linux 技術ネタ
RISC-Vについて学ぶ-後編
RISC-Vについて学ぶ-後編

2024 年 01 月 10 日 Linux 技術ネタ

RISC-Vについて学ぶ-前編
RISC-Vについて学ぶ-前編

2023 年 12 月 12 日 Linux 技術ネタ

イベントレポート
EdgeTech+ 2023 出展レポート
EdgeTech+ 2023 出展レポート

2023 年 12 月 14 日 イベントレポート

EdgeTech+ West 2023 出展レポート
EdgeTech+ West 2023 出展レポート

2023 年 08 月 09 日 イベントレポート

Design Solution Forum 2022
Design Solution Forum 2022

2023 年 02 月 27 日 イベントレポート

リクルート
新卒採用、絶賛募集中!
新卒採用、絶賛募集中!

2023 年 05 月 30 日 リクルート

国立大学オンライン研修レポート 2022
国立大学オンライン研修レポート 2022

2022 年 09 月 27 日 リクルート

北小野通信
北小野通信 桜の季節、珍客来訪?
北小野通信 桜の季節、珍客来訪?

2023 年 05 月 11 日 北小野通信

北小野通信 「 日本土真ん中ウォーク 2022 」
北小野通信 「 日本土真ん中ウォーク 2022 」

2023 年 01 月 30 日 北小野通信

北小野通信 1011
北小野通信 1011

2022 年 10 月 11 日 北小野通信

ソリューション統括部
シリコンバレー探検記 2019 ~番外編~
シリコンバレー探検記 2019 ~番外編~

2019 年 12 月 10 日 ソリューション統括部

シリコンバレー探検記 2019 ~後編~
シリコンバレー探検記 2019 ~後編~

2019 年 12 月 10 日 ソリューション統括部

シリコンバレー探検記 2019 ~前編~
シリコンバレー探検記 2019 ~前編~

2019 年 12 月 10 日 ソリューション統括部

マーケティング統括部
大成功決起大会!!(ET2019)
大成功決起大会!!(ET2019)

2019 年 12 月 13 日 マーケティング統括部

ESEC 2019 決起大会
ESEC 2019 決起大会

2019 年 04 月 25 日 マーケティング統括部

シリコンバレー探検記 その 2
シリコンバレー探検記 その 2

2018 年 12 月 18 日 マーケティング統括部