Python(Anaconda)とOpenCVを使って動画から顔画像を抽出してみる
2015/07/15
今話題のディープラーニングをやってみたい。
いろいろ見た感じCaffeというフレームワークが良さそう。
ただ、学習用データを用意する必要がある。
クラウドワークス的なやつで外注するのもアリ。
個人的にやってみたいことがエロ系なので、なんか外注するのもレピュテーションリスク(笑)がありそうなのでアレ。
動画から画像を切り出してデータを用意するのが良さそう。
下記が参考になる気がする。
http://kivantium.hateblo.jp/entry/2015/02/20/214909
OpenCVを使って顔画像のくり抜きを自動化してる
OSXで。
Contents
Pyenvをインストール
homebrewを使った。
1 |
brew install pyenv |
Anacondaをインストール
1 2 3 |
pyenv install anaconda-2.1.0 pyenv global anaconda-2.1.0 pyenv rehash |
OpenCVをインストール
1 |
conda install -c https://conda.binstar.org/jjhelmus opencv |
たったこれだけw
OpenCVを動かしてみる
http://qiita.com/wwacky/items/98d8be2844fa1b778323
pyenvでanacondaを導入しているので、cascade_pathが違う場所になる。
素直にインストールしていれば.pyenv/versions/anaconda-2.1.0以下にshareフォルダがあるはず。
動画中の顔画像を検出する
動画ファイルを読み込んで一定フレームごとに顔画像検出処理を行い、顔らしき領域をくりぬいて保存するスクリプト
detectFaceで顔領域を抽出して返してる。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
import cv2 cascade_path = "/Path/To/.pyenv/versions/anaconda-2.1.0/share/OpenCV/haarcascades/haarcascade_frontalface_alt.xml" def detectFace(image): image_gray = cv2.cvtColor(image, cv2.cv.CV_BGR2GRAY) image_gray = cv2.equalizeHist(image_gray) cascade = cv2.CascadeClassifier(cascade_path) facerect = cascade.detectMultiScale(image_gray, scaleFactor=1.1, minNeighbors=3, minSize=(50, 50)) print "face rectangle" print facerect return facerect ### main ### video_path = "bbb.mp4" # 何かしらの動画ファイル。 cap = cv2.VideoCapture(video_path) framenum = 0 faceframenum = 0 color = (255, 255, 255) while(1): framenum += 1 ret, image = cap.read() if not ret: break if framenum%10==0: facerect = detectFace(image) if len(facerect) == 0: continue for rect in facerect: croped = image[rect[1]:rect[1]+rect[3],rect[0]:rect[0]+rect[2]] cv2.imwrite("detected" + str(faceframenum) + ".jpg", croped) faceframenum += 1 cap.release() |
いいかんじ。
【追記】
大量の画像から顔画像だけをくりぬいて別ディレクトリに保存する
下記のようなスクリプトを用意する。
↑の動画でやってる内容とほぼ同じ。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
import cv2 import argparse CASCADE_PATH = "/path/to/.pyenv/versions/anaconda-2.1.0/share/OpenCV/haarcascades/haarcascade_frontalface_alt.xml" def detectFace(image): image_gray = cv2.cvtColor(image, cv2.cv.CV_BGR2GRAY) image_gray = cv2.equalizeHist(image_gray) cascade = cv2.CascadeClassifier(CASCADE_PATH) facerect = cascade.detectMultiScale(image_gray, scaleFactor=1.1, minNeighbors=3, minSize=(50, 50)) return facerect parser = argparse.ArgumentParser(description='clip face-image from imagefile.') parser.add_argument('-f', required=True, help='set imagefile. for find face.', metavar='imagefile_name') args = parser.parse_args() imagefile_name = args.f image = cv2.imread(imagefile_name) facerect_list = detectFace(image) if len(facerect_list) == 0: exit count = 0 for facerect in facerect_list: croped = image[facerect[1]:facerect[1]+facerect[3],facerect[0]:facerect[0]+facerect[2]] cv2.imwrite("detected" + str(count) + "_" + imagefile_name, croped) count += 1 |
適当な画像置き場で下記のような(汚い)ワンライナーを実行する。
1 |
anal% mkdir -p clip && ls | grep .jpg | xargs -I % python /path/to/face_cliper.py -f % && ls | grep detected | xargs -I % mv % clip/% |
clipというフォルダに顔画像だけが格納されてるはず。