今日は、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]()
実行結果
パラメーターの調整をしていないので、いくつかミスがありますが概ね綺麗に認識できていると思います。
どうでもいいですけど、しゅんっとした由比ヶ浜はめちゃくちゃ可愛いですね😌
まとめ
PyCallを使ってOpenCVを呼び出して、顔認識を実装しました。
OpenCV自体はPythonですが、その他の処理はJuliaで書ける事で、
実行速度を簡単にあげられるんじゃないかなと期待しています。
あまり、今回の実装では実行速度を気にせず実装しましたが、実行速度を考慮した実装にもチャレンジしたいところです。
最後に、世界の挨拶は「やっはろー」に統一すべきだと思います。
最後まで駄文を読んでいただきありがとうございました。