返回目录:OpenCV系列文章目录(持续更新中......)
上一篇:如何在"Microsoft Visual Studio"中使用OpenCV编译应用程序
下一篇:如何将OpenCV Java 与Eclipse结合使用
警告:
本教程可能包含过时的信息。
从 OpenCV 2.4.4 开始,OpenCV 支持使用与 Android 开发几乎相同的界面进行桌面 Java 开发。本指南将帮助您使用 OpenCV 创建您的第一个 Java(或 Scala)应用程序。我们将使用 Apache Ant 或 Simple Build Tool (SBT) 来构建应用程序。
如果要使用 Eclipse,请前往将 OpenCV Java 与 Eclipse 配合使用。如需在本指南之后进一步阅读,请查看 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 开发所需的预构建文件。对于其他操作系统,需要从源代码构建 OpenCV。
获取 OpenCV 源代码的另一种选择是克隆 OpenCV git 存储库。为了使用 Java 绑定构建 OpenCV,您需要安装 JDK(Java 开发工具包)(我们建议使用 Oracle/Sun JDK 6 或 7)、Apache Ant 和 Python v2.6 或更高版本。
编译OpenCV过程:
bash
git clone git://github.com/opencv/opencv.git
cd opencv
git checkout 2.4
mkdir build
cd build
生成 Makefile 或 MS Visual Studio* 解决方案,或用于在系统中构建可执行文件的任何解决方案:
bash
cmake -DBUILD_SHARED_LIBS=OFF
或者
bash
cmake -DBUILD_SHARED_LIBS=OFF -G "Visual Studio 10"
注意:
当 OpenCV 构建为一组静态库(-DBUILD_SHARED_LIBS=OFF 选项)时,Java 绑定动态库就足够了,即不依赖于其他 OpenCV 库,而是包含所有 OpenCV 代码。
检查 CMake 的输出,并确保 java 是"待构建"模块之一。如果没有,则很可能缺少依赖项。应通过查看 CMake 输出以查找未找到的任何与 Java 相关的工具并安装它们来进行故障排除。
注意
如果 CMake 在系统中找不到 Java,请在运行之前将 JAVA_HOME 环境变量设置为已安装的 JDK 的路径。例如:
bash
export JAVA_HOME=/usr/lib/jvm/java-6-oracle
cmake -DBUILD_SHARED_LIBS=OFF
输入编译命令:
bash
make -j8
或者:
bash
msbuild /m OpenCV.sln /t:Build /p:Configuration=Release /v:m
除此之外,所有这些都将创建一个包含 Java 接口 (bin/opencv-244.jar
) 的 jar 和一个包含 Java 绑定和所有 OpenCV 内容的原生动态库 ( lib/libopencv_java244.so
或 bin/Release/opencv_java244.dll
)。我们稍后会使用这些文件。
使用 Ant 的 Java 示例
注意
所描述的示例随文件夹opencv/samples/java/ant
中的 OpenCV 库一起提供。
-
创建一个文件夹,用于开发此示例应用程序。
-
在此文件夹中,使用文本编辑器创建包含以下内容的文件:
build.xml
html<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 lib 的路径应作为参数(第 5 行中的"{ocvJarDir}"和第 37 行中的"{ocvLibDir}"),但为方便起见,您可以对这些路径进行硬编码。有关其构建文件格式的详细说明,请参阅 Ant 文档。
-
在文件旁边创建一个文件夹
src
,并在其中创建一个文件build.xml``SimpleSample.java
。 -
将以下 Java 代码放入文件
SimpleSample.java
中:
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());
}
}
-
在控制台的文件夹中运行以下命令:
build.xml
bashant -DocvJarDir=path/to/dir/containing/opencv-244.jar -DocvLibDir=path/to/dir/containing/opencv_java244/native/library
例如:
bashant -DocvJarDir=X:\opencv-2.4.4\bin -DocvLibDir=X:\opencv-2.4.4\bin\Release
该命令应启动 [re] 生成并运行示例。您应该在屏幕上看到如下内容:
适用于 Java 和 Scala 的 SBT 项目
现在,我们将使用SBT创建一个简单的Java应用程序。这是对那些不熟悉此构建工具的人的简要介绍。我们之所以使用SBT,是因为它特别简单和强大。
首先,按照其网站上的说明下载并安装SBT。
接下来,导航到希望应用程序源所在的新目录(目录opencv外部)。我们将其命名为"JavaSample",并为其创建一个目录:
bash
cd <somewhere outside opencv>
mkdir JavaSample
现在我们将创建必要的文件夹和一个 SBT 项目:
bash
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
并粘贴以下内容。它定义了您的项目:
java
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 项目的自动生成:
bash
addSbtPlugin("com.typesafe.sbteclipse" % "sbteclipse-plugin" % "2.1.0")
现在从根目录JavaSample
运行 sbt,然后从 SBT 中运行 eclipse 以生成一个 eclipse 项目:
bash
sbt # Starts the sbt console
eclipse # Running "eclipse" from within the sbt console
您应该看到如下内容:
现在,您可以使用 Import ... -> Existing projects into workspace 将 SBT 项目导入 Eclipse。对于指南来说,是否实际执行此操作是可选的;我们将使用 SBT 来构建项目,因此如果您选择使用 Eclipse,它将仅用作文本编辑器。
要测试一切正常,请创建一个简单的"Hello OpenCV"应用程序。为此,请创建包含以下内容的文件src/main/java/HelloOpenCV.java
:
java
public class HelloOpenCV {
public static void main(String[] args) {
System.out.println("Hello, OpenCV");
}
}
现在从 sbt 控制台执行 run,或者更简洁地说,从命令行运行 sbt run:
bash
sbt run
您应该看到如下内容:
运行 SBT 示例
现在,我们将使用 OpenCV 创建一个简单的人脸检测应用程序。
首先,创建一个文件夹lib/
并将 OpenCV jar 复制到其中。默认情况下,SBT 将 lib 文件夹中的 jar 添加到 Java 库搜索路径中。您可以选择重新运行 sbt eclipse 来更新 Eclipse 项目。
bash
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/资源
目录:Next, copy lbpcascade_frontalface.xml
from opencv/data/lbpcascades/
into
现在修改 src/main/java/HelloOpenCV.java,使其包含以下 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;
//
// Detects faces in an image, draws boxes around them, and writes the results
// to "faceDetection.png".
//
class DetectFaceDemo {
public void run() {
System.out.println("\nRunning DetectFaceDemo");
// Create a face detector from the cascade file in the resources
// directory.
CascadeClassifier faceDetector = new CascadeClassifier(getClass().getResource("/lbpcascade_frontalface.xml").getPath());
Mat image = Imgcodecs.imread(getClass().getResource("/lena.png").getPath());
// Detect faces in the image.
// MatOfRect is a special container class for Rect.
MatOfRect faceDetections = new MatOfRect();
faceDetector.detectMultiScale(image, faceDetections);
System.out.println(String.format("Detected %s faces", faceDetections.toArray().length));
// Draw a bounding box around each face.
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));
}
// Save the visualized detection.
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");
// Load the native library.
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
new DetectFaceDemo().run();
}
}
注意:对 System.loadLibrary(Core.NATIVE_LIBRARY_NAME) 的调用。在使用任何本机 OpenCV 方法之前,必须对每个 Java 进程执行一次此命令。如果不调用它,则会收到 UnsatisfiedLink 错误。如果您尝试在已加载 OpenCV 的情况下加载它,您也会收到错误。
现在使用"sbt run"运行人脸检测应用程序:
bash
sbt run
您应该看到如下内容:
它还应该将以下faceDetection.png
图像写入:
大功告成!现在,您已经拥有了一个使用 OpenCV 的示例 Java 应用程序,因此您可以自己开始工作。祝您好运,多年快乐生活!
参考文献:
1.《Introduction to Java Development》-Eric Christiansen and Andrey Pavlenko