LoginSignup
10
18

More than 3 years have passed since last update.

RaspberryPiで機械学習をやってみた

Last updated at Posted at 2019-12-20

RaspberryPiで機械学習をやってみた

Raspberry Pi Advent Calendar 2019の21日目です。

なんとなく機械学習を触ってみたい方、
画像処理に機械学習を取り入れてみたい方、
ラズパイ4を買ってみたけど特にすることがない方向けに記事を書きます。

画像処理に初めて機械学習を使った時に「dlib」というライブラリを使ったのですが、
これが中身を理解しなくても使いやすかったのでご紹介させていただきます。

概要

ラズパイにwebカメラをつなげ、取得した画像データから任意の物体の位置を検出します。

物体の位置は物体の形状(エッジ)を学習することで検出します。

形状認識で用いられる特徴量にはHOG・SIFT・SURFなどがあるのですが、
dlibではHOG特徴量を用いています。

  • 特徴
    • HOG(Histograms of Oriented Gradients)…輪郭がはっきりと映っている画像に有効
    • SIFT…ぼやけている画像にも有効。回転・スケールの変更にも強く、ロバスト性が高い。
    • SURF…ぼやけている画像にも有効。SIFTの高速処理バージョン。

以下にHOG特徴量の例を示します。

(なんとなくエッジが見えると思うのですが、これが輝度の勾配をベクトルで示したものとなります)

icon.png

これをヒストグラム化して物体の特徴とするのですが、今回は説明しません.

機械学習のフレームワークにはSVM(Support Vector Machine)を用いています。

  • 特徴
    • SVM…いい感じの判別器(雑)。先ほどの作成したHOG特徴量を元に物体を判別する。

環境

  • ラズパイ4(メモリ4GB)

    • OS:Raspbian GNU/Linux 10
    • python(3.7.3)…使用言語
    • OpenCV(3.2.0)…画像処理用のライブラリ
    • dlib(19.0.0)…機械学習用のライブラリ
  • C270n HD Webcam…お手頃なロジクールのカメラですが、USBカメラならなんでもいいです。

作業

  1. 写真を取る
  2. 写真からターゲットを学習させる
  3. 学習させる
  4. 学習した結果を使う

process.png

環境構築

python3のインストール

Raspberry piにPython3.6を入れてみた(Raspberry Pi Advent Calendar 2019 1日目)

上記にもあるように、pythonは3系を入れましょう!!

OpenCV…画像処理用のライブラリ

$ pip install opencv-contrib-python

dlib…機械学習用のライブラリ

$ pip install dlib

確認(重要)

$ python
>import cv2
>import dlib

pythonと打ち込んでインタラクティブモードに入ればOKです。cv2とdlibのimport時もエラーが出なければOKです。

画像を撮影する

webcam_take_picture.py
# -*- coding: utf-8 -*-
import numpy as np
import cv2
import os  # rename用モジュール

i = 0 #  保存した写真名の初期値番号。

cap = cv2.VideoCapture(0)

while(True):
    # フレームをキャプチャする
    ret, frame = cap.read()

    # 画面に表示する
    cv2.imshow('frame',frame)

    # キーボード入力待ち
    key = cv2.waitKey(1) & 0xFF

    # [q]が押された場合は終了する
    if key == ord('q'):
        break

    # [s]が押された場合は保存する
    if key == ord('s'):
        i = i + 1
        path = str("{0:06d}".format(i)) + '.jpg'

        cv2.imwrite(path,frame)

# キャプチャの後始末と,ウィンドウをすべて消す
cap.release()
cv2.destroyAllWindows()
使い方
1. 写真を撮影するプログラムを実行。
    $ python3 webcam_take_picture.py
2. 学習させたい対象にカメラを向け[s]キーで写真を撮る(Save)。撮影枚数は50枚程度でいい。
3. [q]キーでウインドウを閉じる(Quit)。

homeの直下に「/owl」というフォルダを作り、
撮影した画像を「owl」に置く。

物体を選択する

写真中の物体はimglabを使って選択します。

imglabをビルドする

$ cd ~/dlib/tools/imglab/
$ sudo mkdir build
$ cd build
$ sudo cmake ..
$ sudo cmake --build . --config Release

撮影したowl内の写真をxmlにまとめる。
$ ./imglab -c ~/owl/all.xml ~/owl

imglabの起動
$./imglab ~/owl/all.xml

  1. Labelをつける
  2. 対象を選択する
  3. 「training.xml」として保存する。

imglab.png

学習させる

webcam_dlib_learning.py
import dlib

if __name__ == "__main__":

    TrainingXml = "~/owl/training.xml"
    SvmFile = "~/owl/detector.svm"
    options = dlib.simple_object_detector_training_options()
    options.add_left_right_image_flips = True
    options.C = 5
    options.num_threads = 4
    options.be_verbose = True

    dlib.train_simple_object_detector(TrainingXml, SvmFile, options)
1. 学習させる
    $ webcam_dlib_learning.py

学習結果はdetector.svmとして出力されます。

今回は学習に150枚の画像を用いたのですが、
ラズパイ4で学習させたら6分15秒で終わりました。
(ちなみにPC(core i7)で学習すると27秒で終わりました。PCで学習させて、学習させたものをラズパイで使うことも可能です)

学習した結果を使う

webcam_dlib.py
import dlib
import cv2

if __name__ == "__main__":

    SvmFile = "~/owl/detector.svm"
    detector = dlib.simple_object_detector(SvmFile)
    cap = cv2.VideoCapture(0)
    if cap.isOpened() is not True:
        raise("IO Error")

    WinName = "Capture"
    cv2.namedWindow(WinName, cv2.WINDOW_AUTOSIZE)
    win_det = dlib.image_window()
    win_det.set_image(detector)

    while True:
        ret, img = cap.read()

        if ret:
            rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
            dets = detector(rgb)
            if len(dets):
                d = dets[0]
                cv2.rectangle(img, (d.left(), d.top()), (d.right(), d.bottom()), (0, 0, 255), 2)
                x = (d.left()+d.right())/2
                y = (d.top()+d.bottom())/2
                cv2.putText(img,"Ex:"+str(x),(40,70),2,0.8,(0,255,0))
                cv2.putText(img,"Ey:"+str(y),(160,70),2,0.8,(0,255,0))
            cv2.imshow(WinName, img)

        key = cv2.waitKey(1)
        if key & 0x00FF  == ord('q'):
            break

    cap.release()
    cv2.destroyAllWindows()

1. 学習結果を使って、任意の物体を検出する。
    $ python3 webcam_dlib.py

処理が重すぎる

参考

HOG特徴とSVMによる物体検出/有限会社 石島電子技研
pythonによる機械学習入門/株式会社システム計画研究所

10
18
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
18