未来を創る、テックコミュニティー

OpenCVで機械学習をさせてみた!! 実装編第3回

シンラボ編集部
2019/09/16

※本記事は、未来技術推進協会ホームページにて2018年1月9日に掲載されたものです。

みなさんこんにちは。
松下忍です。
前回実装編第2回の記事では、OpenCVが搭載している分類機と、既に存在する学習済みデータを使えば、写真から人間の顔や目を検知できることがわかりました。

今回は、OpenCVに機械学習をさせて、実際に学習データが出来るまでの過程について追っていきたいと思います。


OpenCVには「opencv_traincascade」という機械学習を行う機能があります。
学習データを作るためには、物として正解となるものが含まれている画像(ポジティブ画像)と不正解となるものが含まれている画像(ネガティブ画像)が、数百、数千、…とたくさん必要になります。

今回は、10枚ほどの「猫」の画像を学習させて学習データを作成し、別の画像から猫を検知させる様子を追ってみます(余談ですが、学習データは、「カスケード情報ファイル」または「classificationファイル」とも呼ばれます)。


実行環境を整える

「miniconda」という、インストールをするだけでpythonスクリプトとOpenCVが使える便利な環境があるようです。

minicondaはこちらからダウンロードできます(windows、mac、Linuxで対応しています。実際はAnacondaという名前でインストールされます)。
http://conda.pydata.org/miniconda.html

ここでは、miniconda2の場合を例に取ります。

インストールしたらminicondaを起動します。
miniconda2の画面上で以下の3行を1行ずつ入力しEnterキーで実行します。

$ conda create -n cv_env numpy jupyter matplotlib
$ conda install -c https://conda.anaconda.org/menpo opencv3
activate cv_env

学習データを生成する

学習データの生成は、次のようなステップとなっています。

  • 正解画像(ポジティブ画像)を用意する
  • 前回までの記事では、画像から物体を抽出して機械学習として扱うための方法について話しましたが、実際に抽出した画像をここで正解画像として使用します。膨大な数のデータを用意すれば検知率があがりますが、ここでは10枚ほどのデータを扱います。

  • 不正解画像(ネガティブ画像)を用意する
  • 不正解画像は、自分で用意します。猫の場合は、ライオンなどを不正解画像としてみるのも面白いかもしれません。

  • 正解画像の情報を羅列したファイルを用意する
  • 以下の情報を画像1枚ごとに1行ずつ羅列したファイルを用意します。

    – 画像ファイルの場所
    – 1枚の画像の中に正解となる対象物が存在する枚数
    – 正解となる対象物それぞれの位置とサイズ(x, y, 幅, 高さ)
    ファイルは、windowsの場合はdat形式です。ここではpositive.datとしました。

    cat1.jpg 1 142 45 320 320
    cat2.jpg 3 110 120 130 140 270 90 120 150 430 50 130 130

    cat10.jpg 1 180 210 250 150

  • 不正解画像の情報を羅列したファイルを用意する
  • 不正解画像も同じように用意しますが、画像ファイルの場所だけで構いません。ファイル名はnegative.datとします。

    error1.jpg
    error2.jpg

    error10.jpg

  • 学習データを生成するためのファイルを用意する
  • create_cascade.batというファイルを作成し、以下の2行を入力します。

    $ opencv_createsamples -info ./positive.dat -vec ./positive.vec -num 10 -w 50 -h 50
    $ opencv_traincascade -data ../model -vec ./positive.vec -bg ./negative.dat -numPos 10 -numNeg 10 -featureType Haar-Like -maxFalseAlarmRate 0.1 -w 50 -h 50 -minHitRate 0.97 -numStages 17

    opencv_createsamplesでは、入力された正解画像(positive.dat)を合成して、正解となるサンプル画像を作成します。

    opencv_traincascadeでは、サンプルとなる正解画像、不正解画像、特徴量のタイプ、boosting学習手法の設定などをして、カスケード学習をさせます。
    boosting学習手法とは、機械学習における教師あり学習のアルゴリズム(手法)のことで、OpenCV本家では、ニューラルネットワーク単体よりも強力であると見解しているようです。代表的なものに、adaboostというのがあります。
    また、特徴量のタイプには、HOG、Haarなどが選択が可能です。HOGとは、Histograms of Oriented Gradientsの略で、画像の隣合うピクセル同士の色の変化を画像の特徴として識別する手法です。HaarはHaar-Like特徴量と呼ばれ、線やエッジといったパターンの含有量で識別する手法です。

    miniconda上で create_cascade.bat と入力すれば学習が始まり、学習完了後、学習データとなるカスケードファイル cascade.xml が出来上がります。

  • 作成した学習データを元に猫を認識させる
  • 猫が映っている適当な画像を用意し、学習データを使って猫を認識させます。手順は前回の記事にもあるように、画像をグレースケール化し、検出器にかけ、結果を青枠で表示します。
    以下に手順を組み立てたプログラムコードを記載します。これをtest.pyという名前で保存し、miniconda上で python test.pyと入力して実行すれば猫が検出されます。

    $ import cv2
    $
    $ #show cascaded image
    $ def show_cascaded_image(img_path, cascade_path):
    $ cascade = cv2.CascadeClassifier(cascade_path)
    $ img = cv2.imread(img_path, cv2.IMREAD_COLOR)
    $ grayed = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    $ objs = cascade.detectMultiScale(grayed, 1.1, 3)
    $ print(len(objs))
    $ for (x, y, w, h) in objs:
    $ img = cv2.rectangle(img, (x, y), (x + w, y + h), (255, 0, 0), 2)
    $ cv2.imshow(‘window’, img)
    $
    $ TARGET_URL = ‘images/cat_test1.jpg’
    $ CASCADE_URL = ‘model/cascade.xml’
    $ img = show_cascaded_image( TARGET_URL, CASCADE_URL )
    $
    $ cv2.waitKey(0)
    $ cv2.destroyAllWindows()

    猫が複数正面を向いて写っている画像を用意して検出させて見ました。結果、せいぜい1体検知できる程度でした。また、検出できた青枠の位置や大きさも、猫の一部のみを指している程度であり、正解画像の数が10枚程度では検出精度は微々たる結果となりました。膨大な画像データがあれば世の中のあらゆる猫が検知できると思います。
    猫に限らず、世の中のあらゆる対象物について学習させたデータを持った人工知能が登場すれば、世の中に多大や影響を及ぼすことになるでしょう。
    次回は、AIの未来について話していきたいと思います。

参考

この記事を書いた人
シンラボ編集部
エディター