しまてく

学んだ技術を書きためるブログ

OpenCV 3.1 をsbt / Scala で使ってみた。

今日はいままでやろうやろうと思っていた系の技術、OpenCVを触ってみようと思います。

www.buildinsider.net

ここを見るといろいろなことができるんですね、驚きました。

不要なオブジェクト消去とかPhotoshop CCで話題になったアノ機能も作れちゃうんですね!
それでは早速やってみましょう。

基本的に公式のドキュメントに書いてある通りに進めていきます。
OpenCV: Introduction to Java Development

今回の環境

Get proper OpenCV (最新のOpenCVを取得)

まずOpenCVをインストールします。
私はbrew派なので以下のコマンドでまずOpenCVを探します。

brew search opencv

その結果二つのopencvが見つかりました。今回は3.1を使いたいので下の方でいきます。

homebrew/science/opencv
homebrew/science/opencv3

Scalaから使いたいので、with-javaオプションをつけてインストールします。
初めはwith-contribオプションは無しでやったんですが、実際に使う時にエラーになってしまったのでつけました。

brew tap homebrew/science
brew install opencv3 --with-contrib --with-java

※with-contrib無しで出たエラー。

[error] (run-main-0) java.lang.UnsatisfiedLinkError: no opencv_java310 in java.library.path
java.lang.UnsatisfiedLinkError: no opencv_java310 in java.library.path
	at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1864)
	at java.lang.Runtime.loadLibrary0(Runtime.java:870)
	at java.lang.System.loadLibrary(System.java:1122)
	at DetectFaceDemo$.delayedEndpoint$DetectFaceDemo$1(DetectFaceDemo.scala:7)
	at DetectFaceDemo$delayedInit$body.apply(DetectFaceDemo.scala:6)
	at scala.Function0$class.apply$mcV$sp(Function0.scala:34)
	at scala.runtime.AbstractFunction0.apply$mcV$sp(AbstractFunction0.scala:12)
	at scala.App$$anonfun$main$1.apply(App.scala:76)
	at scala.App$$anonfun$main$1.apply(App.scala:76)
	at scala.collection.immutable.List.foreach(List.scala:381)
	at scala.collection.generic.TraversableForwarder$class.foreach(TraversableForwarder.scala:35)
	at scala.App$class.main(App.scala:76)
	at DetectFaceDemo$.main(DetectFaceDemo.scala:6)
	at DetectFaceDemo.main(DetectFaceDemo.scala)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:497)

ビルドなどしてくれているのでしばらく待つと無事インストールできました。

==> Reinstalling homebrew/science/opencv3 with --with-java, --with-contrib
==> Using Homebrew-provided fortran compiler.
This may be changed by setting the FC environment variable.
==> Downloading https://github.com/Itseez/opencv/archive/3.1.0.tar.gz
Already downloaded: /Library/Caches/Homebrew/opencv3-3.1.0.tar.gz
==> Downloading https://github.com/Itseez/opencv_contrib/archive/3.1.0.tar.gz
Already downloaded: /Library/Caches/Homebrew/opencv3--contrib-3.1.0.tar.gz
==> Downloading https://downloads.sourceforge.net/project/opencvlibrary/3rdparty/ippicv/ippicv_macosx_20141027.tgz
Already downloaded: /Library/Caches/Homebrew/opencv3--icv-macosx-20141027.tgz
==> cmake .. -DCMAKE_C_FLAGS_RELEASE= -DCMAKE_CXX_FLAGS_RELEASE= -DCMAKE_INSTALL_PREFIX=/usr/local/Cellar/opencv3/3.1.0_1 -DCMAKE_BU
==> make
==> make install
==> Caveats
This formula is keg-only, which means it was not symlinked into /usr/local.

opencv3 and opencv install many of the same files.

Generally there are no consequences of this for you. If you build your
own software and it requires this formula, you'll need to add to your
build variables:

    LDFLAGS:  -L/usr/local/opt/opencv3/lib
    CPPFLAGS: -I/usr/local/opt/opencv3/include

If you need Python to find bindings for this keg-only formula, run:
  echo /usr/local/opt/opencv3/lib/python2.7/site-packages >> /usr/local/lib/python2.7/site-packages/opencv3.pth
==> Summary
🍺  /usr/local/Cellar/opencv3/3.1.0_1: 397 files, 134M, built in 14.2 minutes

インストールは「/usr/local/Cellar/opencv3/3.1.0_1/」にされたようです。

Java sample with Ant (AntでのJavaサンプル)

私はantは使いませんので今回はここはスキップします。

SBT project for Java and Scala (Java/Scala向けsbtプロジェクト)

この公式ドキュメントのタイトルが「Introduction to Java Development」なんですが
ここからScalaも登場します。

sbtプロジェクトの作成

もろもろ下の感じで作っていきます。

cd <<src-dir>> # ~/src とか

# プロジェクトのディレクトリ作成
mkdir -p opencv31_test && cd opencv31_test

# sbtのbuild.propertiesを作成
mkdir project
echo "sbt.version=0.13.8" > project/build.properties

# OpenCVのライブラリをコピー
mkdir lib
cp /usr/local/Cellar/opencv3/3.1.0_1/share/OpenCV/java/opencv-310.jar ./lib/opencv-310.jar
cp /usr/local/Cellar/opencv3/3.1.0_1/share/OpenCV/java/libopencv_java310.so ./lib/libopencv_java310.dylib

# リソース用のディレクトリ作成
mkdir -p ./src/main/resources

# OpenCVで顔認識するための検出器データコピー
cp /usr/local/Cellar/opencv3/3.1.0_1/share/OpenCV/lbpcascades/lbpcascade_frontalface.xml ./src/main/resources/

# OpenCVで顔認識するための元データ
wget http://docs.opencv.org/master/lena.png -P ./src/main/resources

# ソース用のディレクトリ作成
mkdir -p ./src/main/scala

※なぜsbtを使っているのにlibディレクトリにライブラリをコピーするということをかというと、
まだmavenリポジトリに3.1が登録されてないんですよね。残念。

  • 顔認識するためのデータは顔認識界のマドンナ、レナさんですね。

f:id:cimadai:20160127200443p:plain

build.sbtとソースコード

./src/main/scala/DetectFaceDemo.scala に配置してください。

この時点でtreeをすると以下のようになっているはずです。

$ tree
.
├── build.sbt
├── lib
│   ├── libopencv_java310.dylib
│   └── opencv-310.jar
├── project
│   └── build.properties
└── src
    └── main
        ├── resources
        │   ├── lbpcascade_frontalface.xml
        │   └── lena.png
        └── scala
            └── DetectFaceDemo.scala
いよいよ実行
sbt run

こんな感じのログがでて実行が終了します。

[info] Loading global plugins from /Users/daisuke-shimada/.sbt/0.13/plugins
[info] Loading project definition from /Users/daisuke-shimada/src/opencv31_usage_scala/project
[info] Set current project to opencv31_usage_scala (in build file:/Users/daisuke-shimada/src/opencv31_usage_scala/)
[info] Compiling 1 Scala source to /Users/daisuke-shimada/src/opencv31_usage_scala/target/scala-2.11/classes...
[info] Running DetectFaceDemo
[info] Detected 1 faces
[info] Writing faceDetection.png
[success]

画像認識の結果

f:id:cimadai:20160127200449p:plain

できました!

まとめ

思ったより簡単にできましたね!
これからいろんなサンプルあそんでみよー