Mask R-CNNを簡単にカメラ映像から試す方法

Mask R-CNNを簡単にカメラ映像から試す方法

Mask R-CNNを実際に動かしてみよう

こんにちは。

AI coordinatorの清水秀樹です。

現時点でおそらく最新最強の物体検出であるMask R-CNNを簡単に試せる方法を紹介します。

難しい論文なんぞ読まなくても、ここで紹介している手順通りに実行するだけでMask R-CNNを動かすことができるようになります。

Mask R-CNNの仕組みについては他のサイトに任せるとして、ここでは一切触れていません。

単純に動かすことだけに特化した記事となります。

また、すでに公開済みのGitHubからただ動かすだけでは面白くないので、webカメラからでも動くようにカスタマイズしたソースコードも合わせて紹介します。

興味がある方は試してみてください。

 

成功すれば以下の画像のように、物体の輪郭にそった物体検出ができるようになります。

いよいよ映画のターミネーターばりの画像処理が現実的になってきました。

開発環境

なんでもそうですが、この開発環境の準備が一番苦労します。

筆者もここが一番苦労します。

ただし、開発環境さえ揃えてしまえば、後はソースを動かすだけで試すことができますので頑張ってみましょう。

以下に、筆者の開発環境をゴチャゴチャと記載しておきます。

  • Mac (27-inch, Late 2012)
  • プロセッサ 2.9 GHz intel Core i5
  • macOS Sierra バージョン 10.12.4
  • conda 4.3.29
  • python 3.5.2
  • keras 2.0.8
  • tensorflow
  • Jupyter Notebook
  • Numpy, skimage, scipy, Pillow, cython, h5py 1.3.0

GitHubからMask R-CNNのソースコードをダウンロード

まずはMask R-CNNを紹介しているGitHubからソースコードをダウンロードしましょう。

ダウンロードしたフォルダ内に、「demo.ipynb」があるので、何も考えずにjupyter notebookで実行してみましょう。

まずは動かしてみるという気持ちが、何をやるにも重要な姿勢かと思います。

実行すると以下のようなエラーが出ます。

このエラーを解消するにはCOCOAPIのインストールが必要になりますので、GitHubからダウンロードしてインストールしましょう。

GitHubからダウンロードが完了したら、

cocoapi-master>PythonAPI>setup.py

のsetup.pyを実行してインストールしましょう。

以下のコマンドのみで作業は完了します。

これで先ほどのエラーが解消されるはずです。

 

では再度、「demo.ipynb」を起動しましょう。

続いて以下のようなエラーが出た方は、kerasのバージョンが古い可能性があります。

というか古いから出力されるエラーです。

kerasを2.0.8にバージョンアップしましょう。

筆者は何も考えず、以下のコマンドでkerasのバージョンアップを実施しました。

 

続いてtensorflowのバージョンアップも必要です。

以下のコマンドでtensorflowもバージョンアップしましょう。

 

さて、この状態で再度「demo.ipynb」を実行しても、以下のエラーが発生します。

なんじゃこりゃっ!て感じのエラーですが、エラーメッセージをよく確認すると”mask_rcnn_coco.h5″のダウンロードができなかったよ!というようなエラーメッセージがあることが分かるかと思います。

ということで、”mask_rcnn_coco.h5″を手動でダウンロードしましょう。

ちなみに、”mask_rcnn_coco.h5とは学習モデルのことを指します。

“mask_rcnn_coco.h5″もGitHubで公開されています。

GitHubにアクセスし、上記画像の赤枠で囲ってあるh5ファイルをダウンロードしましょう。

ダウンロードしたら、「demo.ipynb」を同じディレクトリに保存します。

これで環境準備が整いました。

実行結果

3度目の正直で「demo.ipynb」を起動してみましょう。

今度はうまく行くはずです。

無事処理が終了すると、以下のようが画像がjupyter notebook上に表示されます。(画像はランダムに選ばれて表示されます)

すげー!!

感動です。

今までは、矩形で囲んだだけの物体検出でしたが、Mask R-CNNでは輪郭まで検出できています。

この分野はみるみる進化するので、追っていて楽しいですね。

 

映像からのMask R-CNN

続いてカメラ映像からのMask R-CNNを試してみましょう。

PC内蔵カメラからでも動画からでも実行できます。

ソースコードを適当に作成してみました。

とりあえず動けばなんでも良い感じで作成しています。

cap = cv2.VideoCapture(0)を指定していますので、PC内臓のwebカメラが起動するはずです。

動画にしたい場合は、cap = cv2.VideoCapture(‘move.mp4’)といった指定をすれば、動画でもMask R-CNNを試せます。

興味がある方はぜひ挑戦してみてください。

 

それではまた。

About The Author

Hideki
東京大学発AIスタートアップ企業でロボット開発室室長、画像解析室室長、動画解析室室長を務め、AIエンジニアとしても画像認識関連の特許を在籍中に3つ取得。その後、KDDIグループ内でプロダクトリーダーとして自然言語処理パッケージの自社開発を経て、現在はAGRISTのテックリードとして農業の人手不足の解決に向けた収穫ロボットの開発にチャレンジしている。ロボットは技術の総合格闘技との考え方から、AIだけでなく、ハードやエレキ、通信からクラウド、IOTまで幅広く手掛けることができる。最近では人とロボットの共存を目指すべく、性能だけを追い求める開発から「感動やワクワク体験」をデザインできるロボットの研究を進めており、人とロボットがうまく共存できる世界を作り出したいと日々行動している。

COMMENTS & TRACKBACKS

  • Comments ( 1 )
  • Trackbacks ( 0 )
  1. 【開発環境】Windows10,Python3.6.8
          NEC NS150/D

    映像からのMask R-CNNを行うために、貴殿サイト
    http://ai-coordinator.jp/mask-r-cnn
    に掲載されているプログラムを実行しました。
    当初いくつかのエラーが出てそれはつぶしたので
    ですが、まだ以下のエラーが発生します。

    【発生エラー】AttributeError
    module ‘coco’ has no attribute ‘CocoConfig’

    なぜ’coco’が’CocoConfig’の属性を持たないのか
    意味がわかりません。理由はともかく、修正法に
    ついてご教示いただけますと幸いです。

    ソースを以下に示します。

    import os
    import sys
    import random
    import math
    import numpy as np
    import skimage.io
    import matplotlib
    import matplotlib.pyplot as plt
    #sys.path.insert(0, ‘/path/to/samples/coco’)
    #from pycocotools.coco import coco
    import pycocotools.coco
    import coco
    import utils
    import mrcnn.model as modellib
    import cv2
    import colorsys

    ROOT_DIR = os.getcwd()
    MODEL_DIR = os.path.join(ROOT_DIR, “logs”)

    COCO_MODEL_PATH = os.path.join(ROOT_DIR, “mask_rcnn_coco.h5″)
    if not os.path.exists(COCO_MODEL_PATH):
    utils.download_trained_weights(COCO_MODEL_PATH)

    class InferenceConfig(coco.CocoConfig):
    GPU_COUNT = 1
    IMAGES_PER_GPU = 1

    config = InferenceConfig()
    config.display()
    model = modellib.MaskRCNN(mode=”inference”, model_dir=MODEL_DIR, config=config)
    model.load_weights(COCO_MODEL_PATH, by_name=True)

    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’]

    #cap = cv2.VideoCapture(“1.mp4″)
    cap = cv2.VideoCapture(0)

    height = 720
    width = 1280

    def random_colors(N, bright=True):
    brightness = 1.0 if bright else 0.7
    hsv = [(i / N, 1, brightness) for i in range(N)]
    colors = list(map(lambda c: colorsys.hsv_to_rgb(*c), hsv))
    random.shuffle(colors)
    return colors

    def apply_mask(image, mask, color, alpha=0.5):
    for c in range(3):
    image[:, :, c] = np.where(mask == 1,
    image[:, :, c] *
    (1 – alpha) + alpha * color[c] * 255,
    image[:, :, c])
    return image

    def display_instances(image, boxes, masks, class_ids, class_names,
    scores=None, title=””,
    figsize=(16, 16), ax=None):
    N = boxes.shape[0]
    if not N:
    print(“\n*** No instances to display *** \n”)
    else:
    assert boxes.shape[0] == masks.shape[-1] == class_ids.shape[0]

    colors = random_colors(N)

    masked_image = image.copy()
    for i in range(N):
    color = colors[i]

    # Bounding box
    if not np.any(boxes[i]):
    continue
    y1, x1, y2, x2 = boxes[i]
    camera_color = (color[0] * 255, color[1] * 255, color[2] * 255)
    cv2.rectangle(masked_image, (x1, y1), (x2, y2), camera_color , 1)

    # Label
    class_id = class_ids[i]
    score = scores[i] if scores is not None else None
    label = class_names[class_id]
    x = random.randint(x1, (x1 + x2) // 2)
    caption = “{} {:.3f}”.format(label, score) if score else label
    camera_font = cv2.FONT_HERSHEY_PLAIN
    cv2.putText(masked_image,caption,(x1, y1),camera_font, 1, camera_color)

    # Mask
    mask = masks[:, :, i]
    masked_image = apply_mask(masked_image, mask, color)

    return masked_image.astype(np.uint8)

    def main():
    while(True):

    # 動画ストリームからフレームを取得
    ret, frame = cap.read()

    # カメラ画像をリサイズ
    image_cv2 = cv2.resize(frame,(width,height))

    results = model.detect([image_cv2])

    r = results[0]
    camera = display_instances(image_cv2, r[‘rois’], r[‘masks’], r[‘class_ids’],
    class_names, r[‘scores’])

    cv2.imshow(“camera window”, camera)

    # escを押したら終了。
    if cv2.waitKey(1) == 27:
    break

    #終了
    cap.release()
    cv2.destroyAllWindows()

    if __name__ == ‘__main__’:
    main()

    お手数ですが、宜しくお願い致します。
    【引用】http://ai-coordinator.jp/mask-r-cnn

LEAVE A REPLY

*
*
* (公開されません)