Mask R-CNNを試す

はじめに

Mask R-CNNとはICCV 2017 Best Paper に選出された手法で、物体検出Object Dectectionやセマンティック・セグメンテーションSemantic Segmentationを実現するための手法である。COCOデータセットにより学習した、Matterport Mask_RCNNモデルを利用して、デモ画像より物体検出、セグメンテーションデモをGoogle colabで動かしてみよう。

デモを動かそう

Matterport Mask_RCNN、COCO API・Datasetのインストール、デフォルトのデモを動かす手順の以下の通り。

・Mask_RCNNのインストール、セットアップ

%cd /content/drive/My Drive
!git clone https://github.com/matterport/Mask_RCNN.git
%cd ./Mask_RCNN
!pip install -r requirements.txt
%run -i setup.py install

・COCO APIのインストール、セットアップ

%cd ..
!git clone https://github.com/waleedka/coco.git
%cd ./coco/PythonAPI
%run -i setup.py build_ext --inplace

・COCO Datasetで学習したMask_RCNNモデルのインストール

import os
import sys
import random
import math
import numpy as np
import skimage.io
import matplotlib
import matplotlib.pyplot as plt

# Root directory of the project
ROOT_DIR = os.path.abspath("/content/drive/My Drive/Mask_RCNN")

<pre class="brush: actionscript3; gutter: false">
# Import Mask RCNN
sys.path.append(ROOT_DIR)  # To find local version of the library
from mrcnn import utils
import mrcnn.model as modellib
from mrcnn import visualize
# Import COCO config
sys.path.append(os.path.join(ROOT_DIR, "samples/coco/"))  # To find local version
import coco

%matplotlib inline 

# Directory to save logs and trained model
MODEL_DIR = os.path.join(ROOT_DIR, "logs")

# Local path to trained weights file
COCO_MODEL_PATH = os.path.join(ROOT_DIR, "mask_rcnn_coco.h5")
# Download COCO trained weights from Releases if needed
if not os.path.exists(COCO_MODEL_PATH):
    utils.download_trained_weights(COCO_MODEL_PATH)

# Directory of images to run detection on
IMAGE_DIR = os.path.join(ROOT_DIR, "images")

class InferenceConfig(coco.CocoConfig):
    # Set batch size to 1 since we'll be running inference on
    # one image at a time. Batch size = GPU_COUNT * IMAGES_PER_GPU
    GPU_COUNT = 1
    IMAGES_PER_GPU = 1

config = InferenceConfig()
# config.display()

いよいよ認識しようと、以下のpythonコードを実行する。

# Create model object in inference mode.
model = modellib.MaskRCNN(mode="inference", model_dir=MODEL_DIR, config=config)

# Load weights trained on MS-COCO
model.load_weights(COCO_MODEL_PATH, by_name=True)

# COCO Class names
# Index of the class in the list is its ID. For example, to get ID of
# the teddy bear class, use: class_names.index('teddy bear')
class_names = ['BG', 'person', 'bicycle', 'car', 'motorcycle', 'airplane',
               'bus', 'train', 'truck', 'boat', 'traffic light',
               'fire hydrant', 'stop sign', 'parking meter', 'bench', 'bird',
               'cat', 'dog', 'horse', 'sheep', 'cow', 'elephant', 'bear',
               'zebra', 'giraffe', 'backpack', 'umbrella', 'handbag', 'tie',
               'suitcase', 'frisbee', 'skis', 'snowboard', 'sports ball',
               'kite', 'baseball bat', 'baseball glove', 'skateboard',
               'surfboard', 'tennis racket', 'bottle', 'wine glass', 'cup',
               'fork', 'knife', 'spoon', 'bowl', 'banana', 'apple',
               'sandwich', 'orange', 'broccoli', 'carrot', 'hot dog', 'pizza',
               'donut', 'cake', 'chair', 'couch', 'potted plant', 'bed',
               'dining table', 'toilet', 'tv', 'laptop', 'mouse', 'remote',
               'keyboard', 'cell phone', 'microwave', 'oven', 'toaster',
               'sink', 'refrigerator', 'book', 'clock', 'vase', 'scissors',
               'teddy bear', 'hair drier', 'toothbrush']
# Load a random image from the images folder
file_names = next(os.walk(IMAGE_DIR))[2]
for file_name in file_names:
  image = skimage.io.imread(os.path.join(IMAGE_DIR, file_name))

  # Run detection
  results = model.detect([image], verbose=1)

  # Visualize results
  r = results[0]
  visualize.display_instances(image, r['rois'], r['masks'], r['class_ids'], 
                              class_names, r['scores'])

うまくいけばSemantic Segmentationでマスクしたデモ画像が表示される。

Mask_RCNNデモ
Mask_RCNNデモ

※ Mask_RCNNの利用は、以下のとおりtensorflowバージョンを1.xに、

%tensorflow_version 1.x
import tensorflow
print(tensorflow.__version__)

ランタイムのタイプをGPUに設定して再起動して、またもう1回tensorflowバージョンを1.xにして確認する。

%tensorflow_version 1.x
import tensorflow
print(tensorflow.__version__)

デモの画像を入れ替えてみよう

images直下のデモ画像を入れ替えて上記pythonコードを実行してたら、以下画像のようにDining tableの一部が未検出であった。

Mask_RCNNテーブル一部検出
Mask_RCNNテーブル一部検出

Notebook ipynbファイルがGithubへ公開済み。

感想

デモ画像がよさそうに検出できたように見えますが、入れ替えたらそうでもない結果となった。やはり検出の正確性が学習モデルに大いに相関することで、専用学習データで学習モデルを作成しないと納得いく結果が得られず。画像データアノテーションImage Data Annotation業務が請負可能な業者さんがドンドン増えているらしい。

参考文献

Matterport Mask_RCNN on Github.

以上

1+

ロボット・ドローン部品お探しなら
ROBOT翔・電子部品ストア

RGB-D 3Dカメラ市販品

RGB-D 3Dカメラ(デプスカメラ)市販品(一部)の主なスペックを以下のとおりまとめてみよう。

主なスペック

銘柄
型番
深度、Depth-FPS、Depth-解像度、Depth-FOV、Pose FPS)、検出法市場
相場
Hight
Light
STEREO LABS ZED100fps、720p 2560x720他上位解像度あり、0.3~25m、90° (H)x60° (V)x100° (D)、Max100Hz、Stereo Depth Sensing10万円前後深度
Realsense L5150.25~9m、30fps、1024x768、70°±3 x 43°±2°、TOF Lidar方式、IMU付5万円前後精度
Realsense D4550.4~20m、1280×720@30fps、848 × 480@90fps、D455:86° × 57° (±3)、Active IR stereo4万円前後深度
Percipio確認中1.5万円~価格

防水
Orbbec確認中1.5万円~価格
OCCIPITAL0.3~10m、1280x 960@30 fps、FOV:横59° x 縦 46°、IRカメラ&レーザーパターン投影、IMU付7万円前後
MYNT EYE 3D 10300.3~10m(18mはRGB)、752x480@60FPS、D: 146° H:122 V°:76°、IRカメラ&レーザーパターン投影、IMU3万円前後FOV
Matterport Pro2 3DRGB-D Camera x 3、360°回転、8092x4552 pixels @ 70% zoom level (36 MP)本体50万円前後FOV

※ 銘柄並べ替え順=イニシャルアルファベット順

以上

1+

ロボット・ドローン部品お探しなら
ROBOT翔・電子部品ストア

struct2depth~単眼カメラ2D camera Visual SLAM

はじめに

Google がTensorflowのResearch Modelとしてstruct2depth、vid2depthを公開したので、struct2depthを利用して単眼カメラMonocular Cameraで撮った写真から深度Depthを推定してみよう。struct2depth、vid2depthは、KITTIまたは、CITYSCAPEの学習データを通してVisual Odometry、Depthの推定を習得するモデルである。また他の学習データを入れ替えてもあり得ると考えられる。SFM:Structure From Motionに基づく技術で、Depth深度まで推定できれば、3D Recontruction3次元復元まで使われる。

実測

雑居ビール内、ドラッグストア前および、ホールで写真を撮って完了とした。

推定

画像サイズを416×128に縮小して、推定の時間を短縮する。

環境

・ Google Colab, 18.04.3 LTS Bionic Beaver, GPU Tesla k80
・ Tensorflow 1.15.2
・ Research model struct2depth/KITTI

手順

学習せずKITTIモデルをそのまま利用したので、推定手順は以下のとおり。
・tensorflow_versionを1.xに合わせる。

・ランタイムを再起動。

%tensorflow_version 1.x
import tensorflow
print(tensorflow.__version__)

・以下確認できるまで、またランタイムを再起動する。

TensorFlow 1.x selected.
1.15.2

・インファレンス

!python inference.py --logtostderr --file_extension png --depth --egomotion true --input_dir image --output_dir output --model_ckpt model/KITTI/model-199160

結果

単眼カメラで撮ったRGB写真、レンダリングした深度推定イメージを結果として出力される。点群データの3Dイメージは別途プログラムを作成してレンダリングRenderingとする。

うまくいく例

完璧ではないが、扉、旗まで殆ど良く推定できている。

struct2depth_depth_ok_case
struct2depth_depth_ok_case

mayaviで点群Point Cloudデータの3D表現

Mayaviは、matplotlibよりパワーアップして、強力なエンジンVTKを利用した3Dツールである。

point_cloud_3d_plot
point_cloud_3d_plot

上図のように3Dで写真を細かく表現できた。点群データ(npyファイル)による3D表現のpythonソースは、Githubへ公開済み。

うまくいかない例

左下に推定が失敗と見られる。他の場所はなんとなく推定てきている。

struct2depth_depth_ng_case
struct2depth_depth_ng_case

原因を探る

・ KITTIモデルは屋外モデルでそのままでは屋内に向かない場合ある。測定環境にふさわしい学習データセット(モデル)が必要である。
・ 照明の強弱、特徴量に大きく関わること。
・ ついてはまだ実験が不十分だが、商用可能なVisual SLAMに道が長く感じさせられる。

参考文献

Depth Prediction Without the Sensors: Leveraging Structure for Unsupervised Learning from Monocular Videos, Auther: Vincent Casser etc
github google tensorflow model struct2depth

以上

1+

ロボット・ドローン部品お探しなら
ROBOT翔・電子部品ストア