1
5

More than 5 years have passed since last update.

Julia + PyCall + OpenCvを使ってアニメ顔認識

Last updated at Posted at 2019-05-01

今日は、Juliaでアニメ顔認識の実装したのでアウトプットしていきます。
今回は、私が愛してやまない「やはり俺の青春ラブコメはまちがっている」のキャラたちの顔を識別していきます。
とはいえ、JuliaにはまだOpenCVの良さげなラッパーがないので、PyCallでPythonのopencv3を呼んで実装しました。

おしながき

  • PyCallについて
  • アニメ顔認識実装

PyCallについて

PyCallはその名の通りJuliaからPythonの関数を呼び出すためのパッケージです。
画像処理や機械学習ではやはりPythonの方がパッケージが充実しているので、
for loopなどの処理はJuliaで書いて、使いたいとこだけPyCallを呼び出すのがスマートかなと思います。

PyCallのインストールはREPLから行います。


$ julia
#PyCallはデフォルトでPython2が指定されているので、
#必要に応じて以下のコマンドを打つ必要があります。
julia>ENV["PYTHON"] = "path/to/your/python"

#]を入力することでPkgモードに切り替えられます
julia>] 
Pkg> add PyCall

アニメ顔認識実装

続いて、アニメ顔認識の実装に移ります。
もし、opencv3をインストールしていない場合は事前にインストールをしてください。

まずはPyCallとopencvをインポートし、パスや変数を宣言します。

using PyCall: pyimport
cv2 = pyimport("cv2")

cascade_path = "/path/to/lbpcascade_animeface.xml"
video_path = "/Users/to/***.mp4"

frame_num = 0
faceframe_num = 0

OpencvのVideoCaptureを呼び出します。

cap = cv2[:VideoCapture](video_path)

cv2[:VideoCapture]はPythonの記述だとcv2.VideoCaptureと同じです。

画像のグレースケール化とヒストグラムの均一化と顔認識を関数化して実装します。
detectMultiScaleのscaleFactorとminNeighborsの調整で精度に差が出るようです。

function detectFace(image)
    image_gray = cv2[:cvtColor](image, cv2[:COLOR_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))

    if length(facerect) != 0
        println("face rectangle")
        println(facerect)
    end
    return facerect
end

最後に、while loopで1フレームごとに画像を処理する実装をします。

while cap[:isOpened]()
    global frame_num += 1
    ret, image = cap[:read]()

    if ret == false
        break
    end

    if frame_num % 100 == 0
        facerect = detectFace(image)
        if length(facerect) == 0
             continue
        end
        if facerect[2]+facerect[4] > 720 || facerect[1]+facerect[3] > 1152
            continue
        end
        croped = image[facerect[2]:facerect[2]+facerect[4], facerect[1]:facerect[1]+facerect[3], :]
        cv2[:imwrite]("1_" * repr(faceframenum) * ".jpg", croped)
        global faceframe_num += 1
    end
end
cap[:release]()

実行結果

pics.png

パラメーターの調整をしていないので、いくつかミスがありますが概ね綺麗に認識できていると思います。
どうでもいいですけど、しゅんっとした由比ヶ浜はめちゃくちゃ可愛いですね😌

まとめ

PyCallを使ってOpenCVを呼び出して、顔認識を実装しました。
OpenCV自体はPythonですが、その他の処理はJuliaで書ける事で、
実行速度を簡単にあげられるんじゃないかなと期待しています。

あまり、今回の実装では実行速度を気にせず実装しましたが、実行速度を考慮した実装にもチャレンジしたいところです。

最後に、世界の挨拶は「やっはろー」に統一すべきだと思います。

最後まで駄文を読んでいただきありがとうございました。

1
5
2

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
1
5