RealSence  D435をPythonで使う【画角を合わせる編】（Windows10）

#お詫び
半年くらい全く更新がありませんでしたが飽きたわけではなくて
あるイベントのロボット製作が忙しく更新できていませんでした。

VAEとかもほったらかしですし単眼カメラのSLAMとかもやりたいなぁ・・・
・・・
・・・・・・（過労死）

#はじめに

先日PythonでD435を動かす[ラッパーのビルド方法](https://qiita.com/tom_eng_ltd/items/87ce6e6c82db0d965db0)とか[とりあえず表示する方法](https://qiita.com/tom_eng_ltd/items/ae5f27b2d17edb1d47e5)をアップしたので
この記事からの方は上記もご参照いただきたく・・・

「とりあえず表示編」のスクリプトでIR,RGB,Depthの画像を得ることが出来ましたが
**実はRGBとDepthの画角がずれている**という問題がありますので、その辺を解決したいと思います

#環境
windows10
python：3.6.6とか3.6.7とか3.6.8
OpenCV：3.4.2
pyrealsense2:2.19.0
numpy：1.15.1

#RGB＋Depthを表示するスクリプト
まずどのくらいずれているのかを見てみたいと思います

いちいち作るのも面倒かと思いますのでRGBとDepthのカラーマップを並べて表示する
スクリプトを下記に示します

```python
import pyrealsense2 as rs
import numpy as np
import cv2

# ストリーム(Color/Depth)の設定
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()
profile = pipeline.start(config)

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

        #RGB
        RGB_frame = frames.get_color_frame()
        RGB_image = np.asanyarray(RGB_frame.get_data())
                
        #depyh
        depth_frame = frames.get_depth_frame()
        depth_image = np.asanyarray(depth_frame.get_data())
        depth_colormap = cv2.applyColorMap(cv2.convertScaleAbs(depth_image, alpha=0.08), cv2.COLORMAP_JET)


        # 表示
        images = np.hstack((RGB_image, depth_colormap))
        cv2.namedWindow('RealSense', cv2.WINDOW_AUTOSIZE)
        cv2.imshow('RealSense', images)
        if cv2.waitKey(1) & 0xff == 27:#ESCで終了
            cv2.destroyAllWindows()
            break

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

#結果
見ての通りDepthの方が明らかに広角で画角が合っていません
このままのDepthを使用してRGB側にマスクをかけるとずれたり
単眼SLAMの学習データに出来ないという問題が・・・
![zure.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286585/4ec235b3-491a-3b46-dd32-23f04b369b11.png)

#対策
と書きましたが、私が何かを作ったわけでもなく普通にライブラリにコマンドがありますｗ
とりあえず動かしてみましょう

```python
import pyrealsense2 as rs
import numpy as np
import cv2

# ストリーム(Depth/Color)の設定
config = rs.config()
#config.enable_stream(rs.stream.color, 1280, 720, rs.format.bgr8, 30)
#config.enable_stream(rs.stream.depth, 1280, 720, rs.format.z16, 30)
#
config.enable_stream(rs.stream.color, 640, 360, rs.format.bgr8, 30)
#
config.enable_stream(rs.stream.depth, 640, 360, rs.format.z16, 30)

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

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

try:
    while True:

        # フレーム待ち(Color & Depth)
        frames = pipeline.wait_for_frames()
        
        aligned_frames = align.process(frames)
        color_frame = aligned_frames.get_color_frame()
        depth_frame = aligned_frames.get_depth_frame()
        if not depth_frame or not color_frame:
            continue

        #imageをnumpy arrayに
        color_image = np.asanyarray(color_frame.get_data())
        depth_image = np.asanyarray(depth_frame.get_data())


        #depth imageをカラーマップに変換
        depth_colormap = cv2.applyColorMap(cv2.convertScaleAbs(depth_image, alpha=0.08), cv2.COLORMAP_JET)

        #画像表示
        color_image_s = cv2.resize(color_image, (640, 360))
        depth_colormap_s = cv2.resize(depth_colormap, (640, 360))
        images = np.hstack((color_image_s, depth_colormap_s))
        cv2.namedWindow('RealSense', cv2.WINDOW_AUTOSIZE)
        cv2.imshow('RealSense', images)

        if cv2.waitKey(1) & 0xff == 27:#ESCで終了
            cv2.destroyAllWindows()
            break

finally:

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

```
![align.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286585/a4ed86af-0bad-2895-2213-8bd5a75daed9.png)

無事に画角が揃いました！！
~~おわり・・・~~解説したいと思います

#解説
ストリーミングを開始した後に下記の2行を追記し画角を合わせます

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

今まではカメラに格納されていたデータを取りに行っていましたが
alignを行ったので処理後のデータを下記のように取得します

```python
 aligned_frames = align.process(frames)
 color_frame = aligned_frames.get_color_frame()
 depth_frame = aligned_frames.get_depth_frame()
```

正直**「標準でこの状態で出力してくれ」**と思いますが何か不都合があるんでしょうか？

兎にも角にも、これでRGB+Dデータを正しく取得できることが出来ました。
次回は深度情報を使った簡単な事例を・・・紹介できるといいなぁ・・・