OpenCV  4.10.0
开源计算机视觉库
加载中...
搜索中...
无匹配项
Java 开发入门

上一篇教程: 图像监视器:在 Visual Studio 调试器中查看内存中的图像
下一篇教程: 在 Eclipse 中使用 OpenCV Java

原始作者Eric Christiansen 和 Andrey Pavlenko
兼容性OpenCV >= 3.0
警告
本教程可能包含过时信息。

从 OpenCV 2.4.4 开始,OpenCV 支持使用与 Android 开发几乎相同的接口进行桌面 Java 开发。本指南将帮助您使用 OpenCV 创建第一个 Java(或 Scala)应用程序。我们将使用 Apache AntSimple 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 开发所需的预构建文件。对于其他操作系统,需要从源代码构建 OpenCV。

另一种获取 OpenCV 源代码的方法是克隆 OpenCV git 代码库。为了使用 Java 绑定构建 OpenCV,您需要安装 JDK(Java 开发工具包)(我们建议使用 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 是“要构建的”模块之一。如果不是,则可能是缺少依赖项。您应该通过查看 CMake 输出中未找到的任何 Java 相关工具并安装它们来进行故障排除。

注意
如果 CMake 无法在您的系统中找到 Java,请在运行它之前使用已安装 JDK 的路径设置 JAVA_HOME 环境变量。例如:
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 接口的 jar 文件 (bin/opencv-244.jar) 和一个包含 Java 绑定和所有 OpenCV 内容的本机动态库 (lib/libopencv_java244.sobin/Release/opencv_java244.dll)。我们将在后面使用这些文件。

使用 Ant 的 Java 示例

注意
所描述的示例与 OpenCV 库一起提供,位于 opencv/samples/java/ant 文件夹中。
  • 创建一个文件夹,您将在其中开发此示例应用程序。
  • 在这个文件夹中,使用任何文本编辑器创建 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 库的路径作为参数(第 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("欢迎使用 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 数据:\n" + m.dump());
    }
    }
    int main(int argc, char *argv[])
    定义 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 <opencv 目录之外的某个位置>
mkdir JavaSample

现在我们将创建必要的文件夹和 SBT 项目

cd JavaSample
mkdir -p src/main/java # 这是 SBT 预期找到 Java 源代码的位置
mkdir project # 这是构建定义所在的位置

现在,在您喜欢的编辑器中打开 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 # 启动 sbt 控制台
eclipse # 在 sbt 控制台中运行“eclipse”

您应该看到类似以下内容

您现在可以使用“导入” - > “将现有项目导入工作区”将 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.xmlopencv/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;
//
// 在图像中检测人脸,在其周围绘制方框,并将结果
// 写入 "faceDetection.png"。
//
class DetectFaceDemo {
public void run() {
System.out.println("\nRunning DetectFaceDemo");
// 从 resources 目录中的级联文件创建一个人脸检测器。
// 目录。
CascadeClassifier faceDetector = new CascadeClassifier(getClass().getResource("/lbpcascade_frontalface.xml").getPath());
Mat image = Imgcodecs.imread(getClass().getResource("/lena.png").getPath());
// 在图像中检测人脸。
// MatOfRect 是一个专门用于 Rect 的容器类。
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 运行人脸检测应用程序

sbt run

您应该看到类似以下内容

它还应该将以下图像写入 faceDetection.png

您完成了!现在您已经有了使用 OpenCV 的示例 Java 应用程序,因此您可以开始进行自己的工作。我们祝您一切顺利,并拥有许多年快乐的生活!