前のチュートリアル: Image Watch: Visual Studioデバッガでメモリ上の画像を表示する
次のチュートリアル: EclipseでOpenCV Javaを使う
| |
| 原著者 | Eric Christiansen, Andrey Pavlenko |
| 互換性 | OpenCV >= 3.0 |
- 警告
- このチュートリアルには古い情報が含まれている可能性がある。
OpenCV 2.4.4以降、OpenCVはAndroid開発とほぼ同じインターフェースを使ったデスクトップJava開発をサポートしている。本ガイドはOpenCVを使った最初のJava(またはScala)アプリケーションの作成を手助けする。アプリケーションのビルドには Apache Ant または Simple Build Tool (SBT) のいずれかを使用する。
Eclipseを使いたい場合は EclipseでOpenCV Javaを使う を参照してほしい。本ガイドを読んだ後のさらなる学習には Android開発入門 のチュートリアルを参照するとよい。
本ガイドで行うこと
本ガイドでは、次のことを行う:
- デスクトップJavaサポート付きのOpenCVを入手する
- AntまたはSBTのプロジェクトを作成する
- JavaまたはScalaで簡単なOpenCVアプリケーションを書く
同じ手順がOpenCVリポジトリの samples/java フォルダ内のサンプル作成にも使われているので、迷ったらそれらのファイルを参照するとよい。
適切なOpenCVを入手する
バージョン2.4.4以降、OpenCVはデスクトップJavaバインディングを含んでいる。
ダウンロード
最も簡単な入手方法は、OpenCV SourceForgeリポジトリ から バージョン2.4.4以上 の適切なパッケージをダウンロードすることである。
- 覚え書き
- Windowsユーザーは、パッケージ内の
opencv/build/java/ フォルダにJava開発に必要なビルド済みファイルを見つけられる。その他のOSではソースからOpenCVをビルドする必要がある。
OpenCVのソースを入手するもう一つの方法は、OpenCVのgitリポジトリ をクローンすることである。JavaバインディングつきでOpenCVをビルドするには、JDK(Java Development Kit)(Oracle/Sun JDK 6または7を推奨)、Apache Ant、およびPython v2.6以上がインストールされている必要がある。
ビルド
OpenCVをビルドしよう:
git clone git://github.com/opencv/opencv.git
cd opencv
git checkout 2.4
mkdir build
cd build
MakefileまたはMS Visual Studio*のソリューション、あるいはあなたのシステムで実行ファイルをビルドするのに使うものを生成する:
cmake -DBUILD_SHARED_LIBS=OFF ..
または
cmake -DBUILD_SHARED_LIBS=OFF -G "Visual Studio 10" ..
- 覚え書き
- OpenCVを 静的 ライブラリのセットとしてビルドした場合(-DBUILD_SHARED_LIBS=OFF オプション)、Javaバインディングの動的ライブラリは自己完結しており、つまり他のOpenCVライブラリに依存せず、すべてのOpenCVコードを内部に含む。
CMakeの出力を確認し、javaが「To be built」のモジュールの一つになっていることを確かめる。そうでない場合は、依存関係が不足している可能性が高い。CMakeの出力を見て、見つからなかったJava関連のツールがないか調べ、それらをインストールしてトラブルシューティングするとよい。
- 覚え書き
- CMakeがシステム内でJavaを見つけられない場合は、実行前にJAVA_HOME環境変数にインストール済みのJDKへのパスを設定する。例:
export JAVA_HOME=/usr/lib/jvm/java-6-oracle
cmake -DBUILD_SHARED_LIBS=OFF ..
それではビルドを開始する:
または
msbuild /m OpenCV.sln /t:Build /p:Configuration=Release /v:m
さらにこれにより、Javaインターフェースを含むjar(bin/opencv-244.jar)と、JavaバインディングおよびすべてのOpenCVの内容を含むネイティブ動的ライブラリ(それぞれ lib/libopencv_java244.so または bin/Release/opencv_java244.dll)が作成される。これらのファイルは後で使用する。
Antを使ったJavaサンプル
- 覚え書き
- ここで説明するサンプルは、OpenCVライブラリの
opencv/samples/java/ant フォルダに同梱されている。
- このサンプルアプリケーションを開発するフォルダを作成する。
- In this folder create the
build.xml file with the following content using any text editor: <project name="SimpleSample" basedir="." default="rebuild-run">
<property name="src.dir" value="src"/>
<property name="lib.dir" value="${ocvJarDir}"/>
<path id="classpath">
<fileset dir="${lib.dir}" includes="**/*.jar"/>
</path>
<property name="build.dir" value="build"/>
<property name="classes.dir" value="${build.dir}/classes"/>
<property name="jar.dir" value="${build.dir}/jar"/>
<property name="main-class" value="${ant.project.name}"/>
<target name="clean">
<delete dir="${build.dir}"/>
</target>
<target name="compile">
<mkdir dir="${classes.dir}"/>
<javac includeantruntime="false" srcdir="${src.dir}" destdir="${classes.dir}" classpathref="classpath"/>
</target>
<target name="jar" depends="compile">
<mkdir dir="${jar.dir}"/>
<jar destfile="${jar.dir}/${ant.project.name}.jar" basedir="${classes.dir}">
<manifest>
<attribute name="Main-Class" value="${main-class}"/>
</manifest>
</jar>
</target>
<target name="run" depends="jar">
<java fork="true" classname="${main-class}">
<sysproperty key="java.library.path" path="${ocvLibDir}"/>
<classpath>
<path refid="classpath"/>
<path location="${jar.dir}/${ant.project.name}.jar"/>
</classpath>
</java>
</target>
<target name="rebuild" depends="clean,jar"/>
<target name="rebuild-run" depends="clean,run"/>
</project>
- 覚え書き
- このXMLファイルは他のJavaアプリケーションのビルドにも再利用できる。3〜12行目で共通のフォルダ構成を、またアプリケーションのコンパイルと実行のための共通ターゲットを記述している。このXMLを再利用する際は、1行目のプロジェクト名(これは14行目のメインクラスの名前でもある)を変更するのを忘れないこと。OpenCVのjarとjniライブラリへのパスは引数として渡されることを想定しているが(5行目の "${ocvJarDir}" と37行目の "${ocvLibDir}")、必要に応じてこれらのパスをハードコードしてもよい。ビルドファイル形式の詳細な説明は Antのドキュメント を参照のこと。
build.xml ファイルの隣に src フォルダを作成し、その中に SimpleSample.java ファイルを作成する。
- 次のJavaコードを
SimpleSample.java ファイルに記述する: import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.core.CvType;
import org.opencv.core.Scalar;
class SimpleSample {
static{ System.loadLibrary(Core.NATIVE_LIBRARY_NAME); }
public static void main(String[] args) {
System.out.println("Welcome to OpenCV " + Core.VERSION);
Mat m = new Mat(5, 10, CvType.CV_8UC1, new Scalar(0));
System.out.println("OpenCV Mat: " + m);
Mat mr1 = m.row(1);
mr1.setTo(new Scalar(1));
Mat mc5 = m.col(5);
mc5.setTo(new Scalar(5));
System.out.println("OpenCV Mat data:\n" + m.dump());
}
}
int main(int argc, char *argv[])
Definition highgui_qt.cpp:3
build.xml を含むフォルダで、コンソールから次のコマンドを実行する: ant -DocvJarDir=path/to/dir/containing/opencv-244.jar -DocvLibDir=path/to/dir/containing/opencv_java244/native/library
例えば次のようになる: ant -DocvJarDir=X:\opencv-2.4.4\bin -DocvLibDir=X:\opencv-2.4.4\bin\Release
このコマンドによってサンプルの[再]ビルドと実行が開始される。画面上には次のような表示が現れるはずである:
JavaおよびScala向けのSBTプロジェクト
ここからSBTを使って簡単なJavaアプリケーションを作成する。これはこのビルドツールに馴染みのない人への簡単な入門となる。SBTは特に簡単で強力なため採用している。
まず、SBT を、その ウェブサイト の手順に従ってダウンロードしインストールする。
次に、アプリケーションのソースを置きたい新しいディレクトリ(opencv ディレクトリの外)に移動する。ここでは「JavaSample」と呼ぶことにし、そのためのディレクトリを作成する:
cd <somewhere outside opencv>
mkdir JavaSample
次に、必要なフォルダとSBTプロジェクトを作成する:
cd JavaSample
mkdir -p src/main/java # This is where SBT expects to find Java sources
mkdir project # This is where the build definitions live
次に、お好みのエディタで project/build.scala を開き、以下を貼り付ける。これはプロジェクトを定義するものである:
import sbt._
import Keys._
object JavaSampleBuild extends Build {
def scalaSettings = Seq(
scalaVersion := "2.10.0",
scalacOptions ++= Seq(
"-optimize",
"-unchecked",
"-deprecation"
)
)
def buildSettings =
Project.defaultSettings ++
scalaSettings
lazy val root = {
val settings = buildSettings ++ Seq(name := "JavaSample")
Project(id = "JavaSample", base = file("."), settings = settings)
}
}
次に project/plugins.sbt を編集し、以下を貼り付ける。これによってEclipseプロジェクトの自動生成が有効になる:
addSbtPlugin("com.typesafe.sbteclipse" % "sbteclipse-plugin" % "2.1.0")
次に JavaSample のルートからsbtを実行し、SBT内でeclipseを実行してeclipseプロジェクトを生成する:
sbt # Starts the sbt console
eclipse # Running "eclipse" from within the sbt console
次のような表示が現れるはずである:
これでSBTプロジェクトを Import ... -> Existing projects into workspace を使ってEclipseにインポートできる。実際にこれを行うかどうかはこのガイドでは任意である。プロジェクトのビルドにはSBTを使うので、Eclipseを使う場合はテキストエディタとしてのみ機能する。
すべてが正しく動作することを確認するため、簡単な「Hello OpenCV」アプリケーションを作成する。これは src/main/java/HelloOpenCV.java というファイルを次の内容で作成して行う:
public class HelloOpenCV {
public static void main(String[] args) {
System.out.println("Hello, OpenCV");
}
}
次にsbtコンソールから run を実行する。あるいはより簡潔に、コマンドラインから sbt run を実行する:
次のような表示が現れるはずである:
SBTサンプルの実行
ここからOpenCVを使った簡単な顔検出アプリケーションを作成する。
まず、lib/ フォルダを作成し、その中にOpenCVのjarをコピーする。デフォルトでは、SBTはlibフォルダ内のjarをJavaのライブラリ検索パスに追加する。必要に応じて sbt eclipse を再実行してEclipseプロジェクトを更新してもよい。
mkdir lib
cp <opencv_dir>/build/bin/opencv_<version>.jar lib/
sbt eclipse
次に、ディレクトリ src/main/resources を作成し、その中にこのLena画像をダウンロードする:
ファイル名が "lena.png" であることを確認する。resourcesディレクトリ内の項目は、実行時にJavaアプリケーションから利用できる。
次に、lbpcascade_frontalface.xml を opencv/data/lbpcascades/ から resources ディレクトリにコピーする:
cp <opencv_dir>/data/lbpcascades/lbpcascade_frontalface.xml src/main/resources/
次に、src/main/java/HelloOpenCV.java を変更し、次のJavaコードを含むようにする:
import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.core.MatOfRect;
import org.opencv.core.Point;
import org.opencv.core.Rect;
import org.opencv.core.Scalar;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.objdetect.CascadeClassifier;
class DetectFaceDemo {
public void run() {
System.out.println("\nRunning DetectFaceDemo");
CascadeClassifier faceDetector = new CascadeClassifier(getClass().getResource("/lbpcascade_frontalface.xml").getPath());
Mat image = Imgcodecs.imread(getClass().getResource("/lena.png").getPath());
MatOfRect faceDetections = new MatOfRect();
faceDetector.detectMultiScale(image, faceDetections);
System.out.println(String.format("Detected %s faces", faceDetections.toArray().length));
for (Rect rect : faceDetections.toArray()) {
Imgproc.rectangle(image, new Point(rect.x, rect.y), new Point(rect.x + rect.width, rect.y + rect.height), new Scalar(0, 255, 0));
}
String filename = "faceDetection.png";
System.out.println(String.format("Writing %s", filename));
Imgcodecs.imwrite(filename, image);
}
}
public class HelloOpenCV {
public static void main(String[] args) {
System.out.println("Hello, OpenCV");
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
new DetectFaceDemo().run();
}
}
System.loadLibrary(Core.NATIVE_LIBRARY_NAME) の呼び出しに注意すること。このコマンドは、ネイティブのOpenCVメソッドを使用する前に、Javaプロセスごとに正確に一度だけ実行する必要がある。これを呼び出さないとUnsatisfiedLinkエラーが発生する。また、OpenCVがすでにロードされている状態で再度ロードしようとした場合にもエラーが発生する。
次に `sbt run` を使って顔検出アプリケーションを実行する:
次のような表示が現れるはずである:
また、次の画像が faceDetection.png に書き出されるはずである:
完了である。これでOpenCVを使って動作するサンプルJavaアプリケーションができたので、自分自身の作業を始められる。幸運と、喜びに満ちた長い人生を祈っている。