概要です。

上の記事の流れを全く無視して、二次元絵の顔の検出をします。

 試した環境です。

  • Mac OSX 10.11.6
  • OpenCV 3.2.0
  • Clojure 1.8.0
  • Java 1.8.0_121

準備

 インストールの様子です。

# Homebrew
$ ruby -e "$(curl -fsSL https://raw.github.com/Homebrew/homebrew/go/install)"
$ brew update

# Leiningen
$ brew install leiningen

# OpenCV
$ brew install homebrew/science/opencv3 --with-java

$ ls /usr/local/Cellar/opencv3/3.2.0/share/OpenCV/java/
libopencv_java320.dylib opencv-320.jar

 プロジェクト作成の様子です。

# プロジェクトをつくる
$ lein new karen
$ cd karen

# 先に生成したファイルをプロジェクトにコピーしてくる
$ mkdir lib
$ cp /usr/local/Cellar/opencv3/3.2.0/share/OpenCV/java/libopencv_java320.dylib lib/
$ cp /usr/local/Cellar/opencv3/3.2.0/share/OpenCV/java/opencv-320.jar lib/

project.clj を編集します。

(defproject karen "0.1.0-SNAPSHOT"
  :description "FIXME: write description"
  :url "http://example.com/FIXME"
  :license {:name "Eclipse Public License"
            :url "http://www.eclipse.org/legal/epl-v10.html"}
  :dependencies [[org.clojure/clojure "1.8.0"]]

  ;; 以下を追記、適宜変更すること
  :jvm-opts ["-Djava.library.path=lib/"]
  :resource-paths ["./lib/opencv-320.jar"]
  :injections [(clojure.lang.RT/loadLibrary org.opencv.core.Core/NATIVE_LIBRARY_NAME)]
  :main karen.core)

:jvm-opts:resource-paths でパスの設定、:injections でプロジェクト実行の度に dylib を読むように設定、という感じです。

グレースケール変換

 画像のグレースケール変換やります。適当な画像を用意してください。

$ lein repl
karen.core=> (org.opencv.core.Core/VERSION)
"3.2.0"
karen.core=> (import [org.opencv.imgcodecs Imgcodecs])
org.opencv.imgcodecs.Imgcodecs
karen.core=> (import [org.opencv.imgproc Imgproc])
org.opencv.imgproc.Imgproc
karen.core=> (def image (Imgcodecs/imread "karen.jpg"))
#'karen.core/image
karen.core=> (Imgproc/cvtColor image image Imgproc/COLOR_RGB2GRAY)
nil
karen.core=> (Imgcodecs/imwrite "karen_gray.jpg" image)
true

D進どうですか

楽しい! ✌(’ω’✌ )三✌(’ω’)✌三( ✌’ω’)✌

ClassNotFoundException が出るときは jar のパス、UnsatisfiedLinkError が出るときは dylib のパスに不備がある、と思われます。

顔の検出

 二次元絵の顔の検出やります。OpenCV 用のアニメ顔分類器(lbpcascade_animeface.xml)をダウンロードして適当な場所に置いてください。

src/karen/core.clj を編集します。

(ns karen.core
  (:import [org.opencv.core Mat MatOfRect Point Scalar])
  (:import [org.opencv.imgcodecs Imgcodecs])
  (:import [org.opencv.imgproc Imgproc])
  (:import [org.opencv.objdetect CascadeClassifier]))

(defn -main [& args]
  (let [filename (first args)
        image (Imgcodecs/imread filename)
        gray (Mat.)
        faces (MatOfRect.)]

    ;; 画像をグレースケール変換したあと、ヒストグラムを均一化する
    (Imgproc/cvtColor image gray Imgproc/COLOR_RGB2GRAY)
    (Imgproc/equalizeHist gray gray)

    ;; アニメ顔分類器を使って顔を検出する
    (doto (CascadeClassifier.)
          (.load "lbpcascade_animeface.xml")
          (.detectMultiScale gray faces))

    ;; 検出した顔の位置に四角形を描画する
    (doseq [face (.toList faces)]
      (let [src (Point. (.x face) (.y face))
            dst (Point. (+ (.x face) (.width face)) (+ (.y face) (.height face)))]
        (Imgproc/rectangle image src dst (Scalar. 144 48 255) 2)))

    ;; 結果をファイルに出力する
    (let [[_ base extension] (re-find #"(.*)\.([A-Za-z]*)$" filename)]
      (Imgcodecs/imwrite (str base "_result." extension) image))))
$ lein run karen.jpg

See You Next Time

楽しい! ✌(’ω’✌ )三✌(’ω’)✌三( ✌’ω’)✌

終わりに

 参考情報です。