opencvで顔認識しようとしたらカスケードファイルが見つからなかった
opencvのカスケードで顔認識をしたい!
今回の環境です
こんな感じです.windowsとかUbuntuではどうなるかよくわかりません
モザイクアートをつくっていたら画像の大きさがバラバラだったので,正方形にできたら楽だな〜って思いました. 今回は顔判別をしてトリミングするという目的でやっていきま!
Pythonでopencvを使いたい!
pip install opencv-python # pip3を使っているなら pip3 install opencv-python
これだけでおk!pipは簡単でいいですね
カスケードファイルを取ってくる
opencvで顔認識をするにあたりopen-cv側ですでに用意されている顔認識モデルを使っていきます。
僕はここで結構躓いたんですけど・・・
だいたいのサイトでは
/usr/local/opt/opencv/share/OpenCV/haarcascades/
ここにカスケードファイルが入っているよ!とのことなのですが、僕の場合は仮想環境でインスコしたためかこのディレクトリがそもそも存在しませんでした.そこでcv2のライブラリが入っている場所を調べてみようと思いました.
import cv2 print(cv2)
これでopencvがどこに入っているかがわかります
<module 'cv2.cv2' from 'パスがうんにゃらってかいてある/python3.6/site-packages/cv2/cv2.cpython-36m-darwin.so'>
こんな感じ
どうやら /python3.6/site-packages/cv2/ のなかになにかありそうですね・・・ 僕の場合は/python3.6/site-packages/cv2/dataのなかにカスケードファイルが入っていました〜これ躓きポイントでは・・・?
こうやって詰まるたびに同じ思いを次の自分がして欲しくないのでmyModules.pyみたいなものを作っています.
""" cv2カスケードファイルを探しに行って辞書で返す関数 castom_cascade_pathはカスケードファイルが格納されているディレクトリをさします。 自分の環境に合わせて作ったのでデフォルト引数がdataになっています。 カスケードファイルが見つからなかったらFalseを返します """ def search_cv2_cascade(castom_cascade_path="data"): from os.path import splitext, basename, join, dirname, isdir, isfile from glob import glob import cv2 cv2_path = dirname(str(cv2).split()[-1].strip(">").strip("'")) cascade_dir_path = join(cv2_path, castom_cascade_path) if isdir(cascade_dir_path): cascade_xml_path_list = join(cascade_dir_path, "*.xml") cascade = {splitext(basename(path))[0][12:]:path for path in glob(cascade_xml_path_list)} return cascade else: return False
こんな感じで使えばxmlファイルがどさっと辞書型で返されます.なぜ辞書を使うかは,僕が好きだからです
search_cv2_cascade()
本題の顔認識
import cv2 import matplotlib.pyplot as plt #画像を読み込む src = cv2.imread("画像のパス") #グレースケールにする cv2_img = cv2.cvtColor(src, cv2.COLOR_BGR2GRAY) #黒色で認識した部分を囲む color = (0, 0, 0) #カスケードファイルの読み込み face_cascade = cv2.CascadeClassifier(search_cv2_cascade()["frontalface_default"]) #まほうのことば(コピペソースなので全くまだ調べてないです) facerect = face_cascade.detectMultiScale(cv2_img, scaleFactor=1.1, minNeighbors=1, minSize=(1, 1)) #1つ以上囲む部分があれば元の画像に矩形を付け足す if len(facerect) > 0: #検出した顔を囲む矩形の作成 for rect in facerect: cv2.rectangle(src, tuple(rect[0:2]),tuple(rect[0:2]+rect[2:4]), color, thickness=2) #結果をmatplotlibで表示 plt.imshow(cv2.cvtColor(src, cv2.COLOR_BGR2RGB)) #保存 cv2.imwrite("detected.jpg", src)
Twitterの僕のアイコン
顔認識させて見た結果
微妙で草・・・・
おわりに
なんとなくopencvを触って見ました。画像処理をMNISTでしか(PyTrochでMNISTをDNNで判別しただけ・・)触ったことがなかったので結構面白かったです。なんとかモザイクアートスクリプトを早く完成たせたいところ・・・!!!