返回目录:OpenCV系列文章目录(持续更新中......)
上一篇: 如何在“Microsoft Visual Studio”中使用OpenCV编译应用程序
下一篇:暂无
警告:
本教程可能包含过时的信息。
从 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 或更高版本。
Another option to get OpenCV sources is to clone OpenCV git repository. In order to build OpenCV with Java bindings you need JDK (Java Development Kit) (we recommend Oracle/Sun JDK 6 or 7), Apache Ant and Python v2.6 or higher to be installed.
编译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 是“待构建”模块之一。如果没有,则很可能缺少依赖项。应通过查看 CMake 输出以查找未找到的任何与 Java 相关的工具并安装它们来进行故障排除。
注意
如果 CMake 在系统中找不到 Java,请在运行之前将 JAVA_HOME 环境变量设置为已安装的 JDK 的路径。例如:
export JAVA_HOME=/usr/lib/jvm/java-6-oracle
cmake -DBUILD_SHARED_LIBS=OFF
输入编译命令:
make -j8
或者:
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
<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
中:
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
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
该命令应启动 [re] 生成并运行示例。您应该在屏幕上看到如下内容:
适用于 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
您应该看到如下内容:
现在,您可以使用 Import ... -> Existing projects into workspace 将 SBT 项目导入 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 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/资源
目录:Next, copy lbpcascade_frontalface.xml
from opencv/data/lbpcascades/
into
现在修改 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;
//
// 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”运行人脸检测应用程序:
sbt run
您应该看到如下内容:
它还应该将以下faceDetection.png
图像写入:
大功告成!现在,您已经拥有了一个使用 OpenCV 的示例 Java 应用程序,因此您可以自己开始工作。祝您好运,多年快乐生活!
参考文献:
1.《Introduction to Java Development》-Eric Christiansen and Andrey Pavlenko