OpenCV的Java开发介绍

OpenCV的Java开发介绍

自从OpenCV2.4.4它开始支持Java桌面开发,与Android开发使用非常相似的接口。这个教程将帮助你创建自己的第一个使用Java开发(or Scala)的OpenCV应用程序。我们将使用Apache Ant或者Simple Build Tool(SBT)中的一个来编译应用程序。

我们在这个教程中能学到什么?

在这个教程中我们将会:
- 获得OpenCV对桌面Java的支持。
- 创建一个Ant或者SBT项目。
- 使用Java或Scala创建一个Java应用程序。
相同的方式也用于创建OpenCV repository中sample/java里面的小示例程序,如果还没被删除的话,就去看看吧。

得到正确的Opencv

从OpenCV 2.4.4版本开始绑定桌面Java。

下载

最简单的方式就是去OpenCV SourceForge repository下载合适的包,2.4.4版本或者更高。

注意:Windows版本用户可以在opencv/build/java目录找到Java开发的预置文件。对于其他操作系统需要编译源码才能获得。

另一种得到OpenCV源码的方式是clone OpenCV git repository。编译OpenCV绑定的Java部分,你需要安装JDK(Java Delelopment Kit)(我们推荐Oracle/Sun JDK 6 or 7), Apache Ant and 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 option)Java绑定的动态库就足够使用了,不需要其他的OpenCV库了,里面已经包含了所有的OpenCV代码。

检查CMake的输出并确认java模块被建立,如果没有似乎是缺少了它的依赖。需要完整的检查CMake的输出,那些Java相关的工具没有被安装。
这里写图片描述

注意:
如果你的CMake没能在你的系统中找到Java,需要设置JAVA_HOME环境变量,指明JDK的安装目录,再运行CMake:
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.so or bin/Release/opencv_java244.dll respectively),稍后我们将使用这些文件。

使用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应用程序上。它在2-12行描述了一个常见的目录结构以及应用程序编译、运行的目标。当再次使用这个XML文件的时候不要忘记修改第一行的项目名称,这也是main class(14行)的名称。OpenCV的Jar包和Jni库的路径为了参数 (“ ocvJarDir"" {ocvLibDir第37行}”,为了方便也可以将路径写死。查看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());
    }
    }
  • 在终端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
    命令行应当可以编译并运行例子程序。你应当在屏幕上看到如下内容:
    这里写图片描述

使用SBT的Java和Scala项目

注意:下面的例子需要使用OpenCV3.x版本。否则Java库不完整。

现在我们将使用SBT创建一个简单的Java程序。这是对这个不常用使用的编译工具的一个简单介绍。我们使用SBT的原因是它特别简单和强大。
第一步,通过web site的介绍,下载并安装SBT。
第二步,选择一个您愿意为应用程序创建源代的路径,创建一个新目录(opencv之外)。我们给它起名为他“JavaSample”并且为他创建目录。

 cd <somewhere outside opencv>
    2 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")

如果你还没有安装sbteclipse请参考这里,后面的‘2.1.0’使其对应的版本号。
现在在JavaSample的根目录应用sbt并且在SBT内容运行eclipse生成eclipse项目:

sbt # Starts the sbt console
eclipse # Running "eclipse" from within the sbt console

你会看到如下内容:
这里写图片描述
你现在可以导入SBT项目到Eclipse中了, Import… -> Existing project into workspace。你是否这样做都是本教程的可选方案,因为我们将使用SBT编译项目,所以选择Eclipse它仅能提供作为代码编辑器使用。
测试开发环境是否一切正常,创建一个“Hello OpenCV”的应用程序。创建src/main/java/HelloOpenCV.java,填充如下内容:

public class HelloOpenCV {
      public static void main(String[] args) {
      System.out.println("Hello, OpenCV");
     }
 }

现在通过sbt的终端运行程序,或者使用更简单方式在终点以命令行的方式运行:

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

下一步,创建一个目录并将这个Lena的照片放入其中。
这里写图片描述
确认图片的名字是“lena.peng”。资源目录中的所有资源在Java应用程序运行的时候都是有效的。
再下一步,从opencv/data/lbpcascades/目录拷贝lbpcascade_frontalface.xml到资源目录:

cp <opencv_dir>/data/lbpcascades/lbpcascade_frontalface.xml src/main/resources/

现在我们修改src/main/java/HelloOpenCV.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). 这行命令必须在Java每次运行的时候都调用,而且要优先于OpenCV的native方法。如果你没有调用它你会收到UnsatisfiedLink错误。成功调用后再次调用也会报错。
现在运行面部视频程序:

sbt run

你应当看大如下内容:
这里写图片描述

最终会生成如下所示的图片faceDetection.png。
这里写图片描述
你已经完成!你现在已经有一个通过OpenCV工作的简单Java应用程序,所以你可以开始你自己的工作了。我们祝你好运和许多年的快乐生活!

出处:http://docs.opencv.org/master/d9/d52/tutorial_java_dev_intro.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值