【python】opencvで物体を検出してみる – mask R-CNN

画像認識といえば、物体検出や顔認識を思い浮かべる方も少なくないと思います。一方で、実際にプログラムから物体検出や顔認識が自分でできるのかと思っている方も少なくないと思います。

実際はどうなんでしょうか。確かに、課題に対して最適なモデルを構築して物体検出などをするにはかなりのハードルがあります。しかし、「とりあえずどんな感じで物体検出ができるのか試してみたい」といった程度であれば、簡単に実践することができます。

Pythonでは、物体検出や顔認識などのモデルが構築されたソースコードがインターネット上で無料配布されていたりします。今回はそのソースコードを用いて、サクッと物体検出をやってみようと思います。

ソースコードのダウンロード

learnopencvというサイトがGithub上で提供するソースコードをダウンロードします。

https://github.com/spmallick/learnopencv

このサイト自体もOpenCVにおける画像処理の手順を体系的にまとめており、非常にわかりやすいです(英語ですが)。

ダウンロードすると、数多くのプログラムが用意されています。

今回はMask-RCNNを使います。

Mask-RCNNとは

Mask-RCNNとは深層学習のモデルの1つで、入力された画像に対して決められた(予め指定した)種類の物体を認識し、画像中のどこに物体が写っているかを特定するものです。

今回はお試し物体検出なので細かい原理には触れませんが、画像中の物体領域を特定するロジックだと考えてください。

プログラムを実行してみる

Mask-RCNNのフォルダを見てみると、ソースコードとモデル情報を保持したファイルおよびサンプルの画像、動画が用意されています。

Mask-RCNNのフォルダ内容

メインのコードはmask_rcnn.pyです。実行するためには、http://download.tensorflow.org/models/object_detection/mask_rcnn_inception_v2_coco_2018_01_28.tar.gzをダウンロードし、同階層に展開する必要があります。

http://download.tensorflow.org/models/object_detection/mask_rcnn_inception_v2_coco_2018_01_28.tar.gzを展開する

Windowsを使っていてtar.gzファイルの開き方に困っている方は、下記サイトから7-Zipをインストールすると、tar.gzファイルも解凍できるようになります。

https://sevenzip.osdn.jp/

画像

まずは画像の物体検出を試してみます。デフォルトの画像は以下のような車の画像です。

cars.jpg

コマンドプロンプトから実行します。

python mask_rcnn.py --image=cars.jpg

実行結果はcars_mask_rcnn_out_py.jpgというファイルで保存されているようです。

このように車が検出されました。さらに、右側の車では座席の人まで検出しています。

動画

続いては動画で物体検出を試します。元の動画は以下のようなものです。

python mask_rcnn.py --video=cars.mp4

実行した結果が以下の動画です。物体が動いていてもきちんと検出されています。ちなみ、動画は画像の連続として扱われます。各フレーム画像ごとに物体検出を行い、それを連続的に描画することで動画にしています。

このプログラムでは、動画も画像も指定しない場合にはウェブカメラ(USB接続のカメラ)画像を処理するような仕様になっています。

mscoco_labels.namesには、検出する物体のラベル情報(物体の名称)を保持しています。少なくとも、ここに記載されている物体はデフォルトで検出することができます。なので、いろいろな画像や動画で物体検出を試すことができます。

MP4で出力したい場合

デフォルトでは動画の処理結果はAVIファイルで出力されますが、やはりMP4の方が使い勝手が良かったりします。出力動画をMP4にしたい場合は、ソースコードの130行目および144行目の.aviを.mp4に変更します。

#元のソースコードの130行目~
outputFile = "mask_rcnn_out_py.mp4"
if (args.image):
    # Open the image file
    if not os.path.isfile(args.image):
        print("Input image file ", args.image, " doesn't exist")
        sys.exit(1)
    cap = cv.VideoCapture(args.image)
    outputFile = args.image[:-4]+'_mask_rcnn_out_py.jpg'
elif (args.video):
    # Open the video file
    if not os.path.isfile(args.video):
        print("Input video file ", args.video, " doesn't exist")
        sys.exit(1)
    cap = cv.VideoCapture(args.video)
    outputFile = args.video[:-4]+'_mask_rcnn_out_py.mp4'
else:
    # Webcam input
    cap = cv.VideoCapture(0)

また、151行目の設定をMP4にします。

# Get the video writer initialized to save the output video
if (not args.image):
    vid_writer = cv.VideoWriter(outputFile, cv.VideoWriter_fourcc('m', 'p', '4', 'v'), 49, (round(cap.get(cv.CAP_PROP_FRAME_WIDTH)),round(cap.get(cv.CAP_PROP_FRAME_HEIGHT))))

OpenCVの学習におすすめ書籍

PythonでOpenCV始めてみようという方におすすめなのが以下書籍です。実装例も豊富なので、1からコードを書かずとも学習を進めることができます。

オライリーの1冊は読み物というより辞書としての利用におすすめです。お値段結構しますが、細かい情報までしっかりと詰め込まれています。

まとめ

Mask-RCNNを使った物体検出をお手軽に試す方法を紹介しました。オープンソースでは最も作成が大変なモデルも用意されているので、画像や動画を用意するだけで簡単に物体検出を試すことができます。

必要に応じてコードをカスタマイズすることで、目的に応じた画像処理を実現できるかもしれません。

Mask-RCNN以外にも様々な画像処理ソリューションが用意されているので、色々と試してみたいですね。

OpenCVの基礎を身につけるためのロードマップは以下を参考にしてください。

ではでは👋