ラズベリーパイで電子工作 – 第2回 OpenCVで画像認識

こんにちは、ES部のA.Sです。

今回は、ラズベリーパイにOpenCVをインストールして、
画像認識(顔、正面)を行う手順を紹介します。

RaspbianへのOpenCV導入は、想像以上にてこずりました。
後述しますが、導入する環境やタイミングで手順変わると思います。
(WindowsやUbuntuはまだ楽らしい。)

OpenCVとは

OpenCV(Open Source Computer Vision Library)とは、
BSDライセンスのオープンソースで、画像処理では多く使われています。

カスケード型分類器(簡単に言えば特徴を値化して分類するもの)を利用し、
画像解析を行うことができます。

カスケード型分類器に読み込ませる特徴値は、
OpenCVの公式サイトから取得できるので、ダウンロードしてきてテンプレとしても使えます。

OpenCVのインストール

※下記手順は、2019/09時点のRasbian,Python3.5.3の環境にて、
OpenCV-3.4.4.19を利用した手順となります。

OpenCVの取得は、gitからソース取得して自分でコンパイルする方法と、
インストールコマンドでモジュールを取得する方法があります。

ここではコンパイルと比べれば気軽なインストールコマンドによる取得について記載します。
(手軽とは言い切れないですが。)

パッケージリストの更新

sudo apt-get update

上記のパッケージリストを基にアップデート実行

sudo apt-get upgrade

opencv-pythonのインストール

下記でopencvとnumpyがインストールできます。(アンインストールの時は別々。)
(※そしてこれが、、前述した導入時点と環境だと落とし穴となります。)
pip3 install opencv-python
ちなみに上記は、タイムアウトでエラーになることがあります。
できない場合は、下記をお試しください。
pip3 --default-timeout=3000 install opencv-python
  • せっかくなので拡張モジュールもインストール
pip3 install opencv-contrib-python
通常であれば、これで導入が終わりです。

インストールの確認

import cv2だけを実行しインストールが正常にできたか確認。
import cv2

この後、エラーが乱発します。
モジュール不足1
下記インストールコマンドで対処
sudo apt-get install libcblasdev
モジュール不足2
下記インストールコマンドで対処
sudo apt-get install libatlas-base-dev
モジュール不足3
下記インストールコマンドで対処
sudo apt-get install libqt4-test
キリがないので、下記も導入
sudo apt-get install libjasper-dev
sudo apt-get install libopencv-dev
numpyでエラー
ちなみにnumpyとは、数値計算を効率的に行うための拡張モジュール。
多次元配列による、数学関数ライブラリ。(要は画像を多次元配列で表現するもの)

エラーを調べるにあたり、
「このエラーは、numpyが古いから」とか、
「別バージョンのpythonがある場合、そこにnumpyがあれば削除して対応。(どこで紐づいているかわからないから)」
という対応方法が他のサイトに書いていました。

しかし、Pythonのパスを見ても問題はなさそうで、
numpyのアンインストール、インストールを繰り返しましたが解消できない。
仕切りなおそうとnumpyではなく、OpenCVをアンインストールして、
再度インストールしたときに原因に気付きました。

pip3 install opencv-pythonに問題があると。。

これ、、cv2とnumpyのパッケージをセットでインストールされるのに、
これらが噛み合わないバージョンのものがインストールされていることが原因でした。
pi@raspberrypi:~ $ pip3 install opencv-python
Collecting opencv-python
Using cached https://www.piwheels.org/simple/opencv-python/opencv_python-3.4.4.19-cp35-cp35m-linux_armv7l.whl
Collecting numpy>=1.12.1 (from opencv-python)
Using cached https://www.piwheels.org/simple/numpy/numpy-1.17.2-cp35-cp35m-linux_armv7l.whl
Installing collected packages: numpy, opencv-python
Successfully installed numpy-1.17.2 opencv-python-3.4.4.19
opencvは、3.4.4.19がインストールされ、numpyは、1.17.2がインストールされています。
しかし、正解のnumpyのバージョンは、1.12.1。

なので、numpyだけアンインストール。
pip3 uninstall numpy
numpyのバージョンを指定して、インストール
pip3 install numpy==1.12.1
この事象の調査中にQiitaにて、おそらく同じ事象の人を発見。
import numpyで確認した時のエラーが一緒で日付が最近で同じラズパイで発生していた。
まだ未解決だったので、同じラズビリストとしてすぐにQiitaで回答。 https://qiita.com/kazuppp/items/ceee999aef8cddbb252c

OpenCVの利用

導入が完了したので、早速使ってみます。

公式サイトからカスケード型分類器で使用するxmlを取得

カスケード型分類器に読み込ませる特徴値を公式サイトから取得します。
https://opencv.org
「Releases」→対象バージョンの「source」をクリックするとzipファイルが取得できます。

zipファイルを解凍し、
data/haarcascadesフォルダにカスケード分類機で使うxmlファイルがあるので入手。

今回は、正面・顔の特徴値である”haarcascade_frontalface_default.xml”を利用。
顔だけでなく、目なども解析できますが、今回は顔・正面で試します。

OpenCVを実行

弊社メンバーがボランティアでごみ掃除した時の集合写真を利用します。
みんな正面を見て、画質もよかったので解析向き。
  • 下記ソースコードを実行
import cv2

#公式サイトで入手したカスケードxmlファイルを指定。今回は、顔、正面のみ。
face_cascade = cv2.CascadeClassifier('/home/pi/temp_face/data/haarcascades/haarcascade_frontalface_default.xml')
#対象の写真を入力データとして使用
pic = cv2.imread('/home/pi/DSC0081.JPG')

#今回の画像では、グレースケールにしなくても解析可能だが、
#グレースケールにするのが一般的のようなので入れておく。
gray = cv2.cvtColor(pic, cv2.COLOR_BGR2GRAY)
#解析する幅。小さくすれば正確だが時間がかかる。
faces = face_cascade.detectMultiScale(gray, 1.3, 5)

for x,y,w,h in faces:
  #検出した領域の枠を描画、「(255,0,0),2」は()の左から青、緑、赤。右端は線の太さ。
    pic = cv2.rectangle(pic,(x,y),(x+w,y+h),(255,0,0),2)

#解析後の画像出力
cv2.imwrite('/home/pi/after.jpg', pic)

#いらないけどすぐ確認したい場合のためプレビュー
#下記の場合、5秒後にプレビューを閉じる。
cv2.imshow('pic',pic)
cv2.waitKey(5000)
cv2.destroyAllWindows()
  • 実行結果
顔を検出。一応全員認識できました。

終わりに

スクレイピングで画像を収集し、顔だけ抜き出したりもできるようです。
顔を検出し、顔部分を抜き出して(顔データはnumpyで扱って)AIに読み込ませて認識させるということもできそう。

次回は、上記か、もしくは物理的に何か動くものを作ってみようと思います。

おまけ

pip3コマンドが使えなくなった時の対処 下記でpip3コマンドのアップデートを行ったところ、
pip3 install --upgrade pip
pip3コマンドを叩こうとすると、延々とこれがでてきた。。。
Traceback (most recent call last):
File "/usr/bin/pip3", line 9, in <module>
 from pip import main
ImportError: 
cannot import name 'main'
どうやらRasbianのpip3コマンドとpythonのpipコマンドが競合するからのよう。
(Ubuntuでも起きるみたい)

今後もpip3コマンドを利用したい場合は、下記でpip3コマンドを利用できるようになります。
python3 -m pip uninstall pip
こちらも、同じ状況になっている方が結構いるみたいなので、ご参考ください。

投稿者: エムシバ君

エムフィールドのイメージキャラクター えむしば君です。 気になったり、興味が湧いた記事があったら、なんでもコメントしてみてね。 コーポレートサイトの問い合わせ欄からでも大丈夫だよ。