概要です。
ScalaでOpenCVを使って画像処理 http://t.co/dn1jvLDstM これを参考にClojureからOpenCVを、誰かがやってくれると思う
— 島風/天江衣分類器作成マン (@AntiBayesian) April 8, 2014
上の記事の流れを全く無視して、二次元絵の顔の検出をします。
試した環境です。
- 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
楽しい! ✌(’ω’✌ )三✌(’ω’)✌三( ✌’ω’)✌
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
楽しい! ✌(’ω’✌ )三✌(’ω’)✌三( ✌’ω’)✌
終わりに
参考情報です。