diff --git a/doc/tutorials/definitions/tocDefinitions.rst b/doc/tutorials/definitions/tocDefinitions.rst index 3faef9dfbe..49ada684eb 100644 --- a/doc/tutorials/definitions/tocDefinitions.rst +++ b/doc/tutorials/definitions/tocDefinitions.rst @@ -8,4 +8,5 @@ .. |Author_FernandoI| unicode:: Fernando U+0020 Iglesias U+0020 Garc U+00ED a .. |Author_EduardF| unicode:: Eduard U+0020 Feicho .. |Author_AlexB| unicode:: Alexandre U+0020 Benoit - +.. |Author_EricCh| unicode:: Eric U+0020 Christiansen +.. |Author_AndreyP| unicode:: Andrey U+0020 Pavlenko diff --git a/doc/tutorials/introduction/desktop_java/images/Java_logo.png b/doc/tutorials/introduction/desktop_java/images/Java_logo.png new file mode 100644 index 0000000000..2114751896 Binary files /dev/null and b/doc/tutorials/introduction/desktop_java/images/Java_logo.png differ diff --git a/doc/tutorials/introduction/desktop_java/images/ant_output.png b/doc/tutorials/introduction/desktop_java/images/ant_output.png new file mode 100644 index 0000000000..a658fd7853 Binary files /dev/null and b/doc/tutorials/introduction/desktop_java/images/ant_output.png differ diff --git a/doc/tutorials/introduction/desktop_java/images/cmake_output.png b/doc/tutorials/introduction/desktop_java/images/cmake_output.png new file mode 100644 index 0000000000..bab140d6a4 Binary files /dev/null and b/doc/tutorials/introduction/desktop_java/images/cmake_output.png differ diff --git a/doc/tutorials/introduction/desktop_java/images/eclipse_main_class.png b/doc/tutorials/introduction/desktop_java/images/eclipse_main_class.png new file mode 100644 index 0000000000..84c152e6da Binary files /dev/null and b/doc/tutorials/introduction/desktop_java/images/eclipse_main_class.png differ diff --git a/doc/tutorials/introduction/desktop_java/images/eclipse_new_java_prj.png b/doc/tutorials/introduction/desktop_java/images/eclipse_new_java_prj.png new file mode 100644 index 0000000000..34e03972e7 Binary files /dev/null and b/doc/tutorials/introduction/desktop_java/images/eclipse_new_java_prj.png differ diff --git a/doc/tutorials/introduction/desktop_java/images/eclipse_run.png b/doc/tutorials/introduction/desktop_java/images/eclipse_run.png new file mode 100644 index 0000000000..2efc8e6715 Binary files /dev/null and b/doc/tutorials/introduction/desktop_java/images/eclipse_run.png differ diff --git a/doc/tutorials/introduction/desktop_java/images/eclipse_user_lib.png b/doc/tutorials/introduction/desktop_java/images/eclipse_user_lib.png new file mode 100644 index 0000000000..11694526ac Binary files /dev/null and b/doc/tutorials/introduction/desktop_java/images/eclipse_user_lib.png differ diff --git a/doc/tutorials/introduction/desktop_java/images/eclipse_user_lib2.png b/doc/tutorials/introduction/desktop_java/images/eclipse_user_lib2.png new file mode 100644 index 0000000000..2b9ec5c3c1 Binary files /dev/null and b/doc/tutorials/introduction/desktop_java/images/eclipse_user_lib2.png differ diff --git a/doc/tutorials/introduction/desktop_java/images/eclipse_user_lib3.png b/doc/tutorials/introduction/desktop_java/images/eclipse_user_lib3.png new file mode 100644 index 0000000000..4bf83ee033 Binary files /dev/null and b/doc/tutorials/introduction/desktop_java/images/eclipse_user_lib3.png differ diff --git a/doc/tutorials/introduction/desktop_java/images/eclipse_user_lib4.png b/doc/tutorials/introduction/desktop_java/images/eclipse_user_lib4.png new file mode 100644 index 0000000000..c3f353155b Binary files /dev/null and b/doc/tutorials/introduction/desktop_java/images/eclipse_user_lib4.png differ diff --git a/doc/tutorials/introduction/desktop_java/images/eclipse_user_lib5.png b/doc/tutorials/introduction/desktop_java/images/eclipse_user_lib5.png new file mode 100644 index 0000000000..ed79d92d41 Binary files /dev/null and b/doc/tutorials/introduction/desktop_java/images/eclipse_user_lib5.png differ diff --git a/doc/tutorials/introduction/desktop_java/images/eclipse_user_lib6.png b/doc/tutorials/introduction/desktop_java/images/eclipse_user_lib6.png new file mode 100644 index 0000000000..3a98e38b1b Binary files /dev/null and b/doc/tutorials/introduction/desktop_java/images/eclipse_user_lib6.png differ diff --git a/doc/tutorials/introduction/desktop_java/images/eclipse_user_lib7.png b/doc/tutorials/introduction/desktop_java/images/eclipse_user_lib7.png new file mode 100644 index 0000000000..019432016a Binary files /dev/null and b/doc/tutorials/introduction/desktop_java/images/eclipse_user_lib7.png differ diff --git a/doc/tutorials/introduction/desktop_java/images/eclipse_user_lib8.png b/doc/tutorials/introduction/desktop_java/images/eclipse_user_lib8.png new file mode 100644 index 0000000000..5650aa79a4 Binary files /dev/null and b/doc/tutorials/introduction/desktop_java/images/eclipse_user_lib8.png differ diff --git a/doc/tutorials/introduction/desktop_java/images/faceDetection.png b/doc/tutorials/introduction/desktop_java/images/faceDetection.png new file mode 100644 index 0000000000..a7c97421e1 Binary files /dev/null and b/doc/tutorials/introduction/desktop_java/images/faceDetection.png differ diff --git a/doc/tutorials/introduction/desktop_java/images/lena.png b/doc/tutorials/introduction/desktop_java/images/lena.png new file mode 100644 index 0000000000..68342fae53 Binary files /dev/null and b/doc/tutorials/introduction/desktop_java/images/lena.png differ diff --git a/doc/tutorials/introduction/desktop_java/images/sbt_eclipse.png b/doc/tutorials/introduction/desktop_java/images/sbt_eclipse.png new file mode 100644 index 0000000000..cd532d7f54 Binary files /dev/null and b/doc/tutorials/introduction/desktop_java/images/sbt_eclipse.png differ diff --git a/doc/tutorials/introduction/desktop_java/images/sbt_run.png b/doc/tutorials/introduction/desktop_java/images/sbt_run.png new file mode 100644 index 0000000000..b2cbdd47e1 Binary files /dev/null and b/doc/tutorials/introduction/desktop_java/images/sbt_run.png differ diff --git a/doc/tutorials/introduction/desktop_java/images/sbt_run_face.png b/doc/tutorials/introduction/desktop_java/images/sbt_run_face.png new file mode 100644 index 0000000000..7e105f1000 Binary files /dev/null and b/doc/tutorials/introduction/desktop_java/images/sbt_run_face.png differ diff --git a/doc/tutorials/introduction/desktop_java/java_dev_intro.rst b/doc/tutorials/introduction/desktop_java/java_dev_intro.rst new file mode 100644 index 0000000000..9e5e9510c3 --- /dev/null +++ b/doc/tutorials/introduction/desktop_java/java_dev_intro.rst @@ -0,0 +1,523 @@ + +.. _Java_Dev_Intro: + + +Introduction to Java Development +******************************** + +Last updated: 12 February, 2013. + +As of OpenCV 2.4.4, OpenCV supports desktop Java development using nearly the same interface as for +Android development. This guide will help you to create your first Java (or Scala) application using OpenCV. +We will use either `Eclipse `_, `Apache Ant `_ or the +`Simple Build Tool (SBT) `_ to build the application. + +For further reading after this guide, look at the :ref:`Android_Dev_Intro` tutorials. + +What we'll do in this guide +*************************** + +In this guide, we will: + +* Get OpenCV with desktop Java support + +* Create an ``Ant``, ``Eclipse`` or ``SBT`` project + +* Write a simple OpenCV application in Java or Scala + +The same process was used to create the samples in the :file:`samples/java` folder of the OpenCV repository, +so consult those files if you get lost. + +Get OpenCV with desktop Java support +************************************ + +Starting from version 2.4.4 OpenCV includes desktop Java bindings. +The most simple way to get it is downloading the appropriate package of **version 2.4.4 or higher** from the +`OpenCV SourceForge repository `_. + +.. note:: Windows users can find the prebuilt files needed for Java development in the + :file:`opencv/build/java/` folder inside the package. + For other OSes it's required to build OpenCV from sources. + +Another option to get OpenCV sources is to clone `OpenCV git repository +`_. +In order to build OpenCV with Java bindings you need :abbr:`JDK (Java Development Kit)` +(we recommend `Oracle/Sun JDK 6 or 7 `_), +`Apache Ant `_ and `Python` v2.6 or higher to be installed. + +Build OpenCV +############ + +Let's build OpenCV: + + .. code-block:: bash + + git clone git://github.com/Itseez/opencv.git + cd opencv + git checkout 2.4 + mkdir build + cd build + +Generate a Makefile or a MS Visual Studio* solution, or whatever you use for +building executables in your system: + + .. code-block:: bash + + cmake -DBUILD_SHARED_LIBS=OFF .. + +or + + .. code-block:: bat + + cmake -DBUILD_SHARED_LIBS=OFF -G "Visual Studio 10" .. + +.. note:: When OpenCV is built as a set of **static** libraries (``-DBUILD_SHARED_LIBS=OFF`` option) + the Java bindings dynamic library is all-sufficient, + i.e. doesn't depend on other OpenCV libs, but includes all the OpenCV code inside. + +Examine the output of CMake and ensure ``java`` is one of the modules "To be built". +If not, it's likely you're missing a dependency. You should troubleshoot by looking +through the CMake output for any Java-related tools that aren't found and installing them. + + .. image:: images/cmake_output.png + :alt: CMake output + :align: center + +Now start the build: + + .. code-block:: bash + + make -j8 + +or + + .. code-block:: bat + + msbuild /m OpenCV.sln /t:Build /p:Configuration=Release /v:m + +Besides all this will create a ``jar`` containing the Java interface (:file:`bin/opencv_2.4.4.jar`) +and a native dynamic library containing Java bindings and all the OpenCV stuff +(:file:`bin/Release/opencv_java244.dll` or :file:`bin/libopencv_java244.so` respectively). +We'll use these files later. + +Create a simple Java sample and an Ant build file for it +******************************************************** + +.. note:: + The described sample is provided with OpenCV library in the :file:`opencv/samples/java/ant` folder. + +* Create a folder where you'll develop this sample application. + +* In this folder create an XML file with the following content using any text editor: + + .. code-block:: xml + :linenos: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + .. note:: + This XML file can be reused for building other Java applications. + It describes a common folder structure in the lines 3 - 12 and common targets + for compiling and running the application. + + When reusing this XML don't forget to modify the project name in the line 1, + that is also the name of the `main` class (line 14). + The paths to OpenCV `jar` and `jni lib` are expected as parameters + (``"${ocvJarDir}"`` in line 5 and ``"${ocvLibDir}"`` in line 37), but + you can hardcode these paths for your convenience. + See `Ant documentation `_ for detailed description + of its build file format. + +* Create an :file:`src` folder next to the :file:`build.xml` file and a :file:`SimpleSample.java` file in it. + +* Put the following Java code into the :file:`SimpleSample.java` file: + .. code-block:: java + + import org.opencv.core.Mat; + import org.opencv.core.CvType; + import org.opencv.core.Scalar; + + class SimpleSample { + + static{ System.loadLibrary("opencv_java244"); } + + public static void main(String[] args) { + 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()); + } + + } + +* Run the following command in console in the folder containing :file:`build.xml`: + .. code-block:: bash + + ant -DocvJarDir=path/to/dir/containing/opencv-244.jar -DocvLibDir=path/to/dir/containing/opencv_java244/native/library + + For example: + + .. code-block:: bat + + ant -DocvJarDir=X:\opencv-2.4.4\bin -DocvLibDir=X:\opencv-2.4.4\bin\Release + + The command should initiate [re]building and running the sample. + You should see on the screen something like this: + + .. image:: images/ant_output.png + :alt: run app with Ant + :align: center + +Create a simple Java project in Eclipse +*************************************** + +Now let's look at the possiblity of using OpenCV in Java when developing in Eclipse IDE. + +* Create a new Eclipse workspace +* Create a new Java project via :guilabel:`File --> New --> Java Project` + + .. image:: images/eclipse_new_java_prj.png + :alt: Eclipse: new Java project + :align: center + + Call it say "HelloCV". + +* Open :guilabel:`Java Build Path` tab on :guilabel:`Project Properties` dialog + and configure additional library (OpenCV) reference (jar and native library location): + + .. image:: images/eclipse_user_lib.png + :alt: Eclipse: external JAR + :align: center + + ` ` + + .. image:: images/eclipse_user_lib2.png + :alt: Eclipse: external JAR + :align: center + + ` ` + + .. image:: images/eclipse_user_lib3.png + :alt: Eclipse: external JAR + :align: center + + ` ` + + .. image:: images/eclipse_user_lib4.png + :alt: Eclipse: external JAR + :align: center + + ` ` + + .. image:: images/eclipse_user_lib5.png + :alt: Eclipse: external JAR + :align: center + + ` ` + + .. image:: images/eclipse_user_lib6.png + :alt: Eclipse: external JAR + :align: center + + ` ` + + .. image:: images/eclipse_user_lib7.png + :alt: Eclipse: external JAR + :align: center + + ` ` + + .. image:: images/eclipse_user_lib8.png + :alt: Eclipse: external JAR + :align: center + + ` ` + +* Add a new Java class (say ``Main``) containing the application entry: + + .. image:: images/eclipse_main_class.png + :alt: Eclipse: Main class + :align: center + +* Put some simple OpenCV calls there, e.g.: + .. code-block:: java + + import org.opencv.core.CvType; + import org.opencv.core.Mat; + + public class Main { + public static void main(String[] args) { + System.loadLibrary("opencv_java244"); + Mat m = Mat.eye(3, 3, CvType.CV_8UC1); + System.out.println("m = " + m.dump()); + } + } + +* Press :guilabel:`Run` button and find the identity matrix content in the Eclipse ``Console`` window. + + .. image:: images/eclipse_run.png + :alt: Eclipse: run + :align: center + +Create an SBT project and samples in Java and Scala +*************************************************** + +Now we'll create a simple Java application using SBT. This serves as a brief introduction to +those unfamiliar with this build tool. We're using SBT because it is particularly easy and powerful. + +First, download and install `SBT `_ using the instructions on its `web site `_. + +Next, navigate to a new directory where you'd like the application source to live (outside :file:`opencv` dir). +Let's call it "JavaSample" and create a directory for it: + + .. code-block:: bash + + cd + mkdir JavaSample + +Now we will create the necessary folders and an SBT project: + + .. code-block:: 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 + +Now open :file:`project/build.scala` in your favorite editor and paste the following. +It defines your project: + + .. code-block:: 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) + } + } + +Now edit :file:`project/plugins.sbt` and paste the following. +This will enable auto-generation of an Eclipse project: + + .. code-block:: scala + + addSbtPlugin("com.typesafe.sbteclipse" % "sbteclipse-plugin" % "2.1.0") + +Now run ``sbt`` from the :file:`JavaSample` root and from within SBT run ``eclipse`` to generate an eclipse project: + + .. code-block:: bash + + sbt # Starts the sbt console + > eclipse # Running "eclipse" from within the sbt console + +You should see something like this: + + .. image:: images/sbt_eclipse.png + :alt: SBT output + :align: center + +You can now import the SBT project to Eclipse using :guilabel:`Import ... -> Existing projects into workspace`. +Whether you actually do this is optional for the guide; +we'll be using SBT to build the project, so if you choose to use Eclipse it will just serve as a text editor. + +To test that everything is working, create a simple "Hello OpenCV" application. +Do this by creating a file :file:`src/main/java/HelloOpenCV.java` with the following contents: + + .. code-block:: java + + public class HelloOpenCV { + public static void main(String[] args) { + System.out.println("Hello, OpenCV"); + } + } + +Now execute ``run`` from the sbt console, or more concisely, run ``sbt run`` from the command line: + + .. code-block:: bash + + sbt run + +You should see something like this: + + .. image:: images/sbt_run.png + :alt: SBT run + :align: center + +Copy the OpenCV jar and write a simple application +******************************************************** + +Now we'll create a simple face detection application using OpenCV. + +First, create a :file:`lib/` folder and copy the OpenCV jar into it. +By default, SBT adds jars in the lib folder to the Java library search path. +You can optionally rerun ``sbt eclipse`` to update your Eclipse project. + + .. code-block:: bash + + mkdir lib + cp /build/bin/opencv_.jar lib/ + sbt eclipse + +Next, create the directory src/main/resources and download this Lena image into it: + + .. image:: images/lena.png + :alt: Lena + :align: center + +Make sure it's called :file:`"lena.png"`. +Items in the resources directory are available to the Java application at runtime. + +Next, copy :file:`lbpcascade_frontalface.xml` from :file:`opencv/data/` into the :file:`resources` +directory: + + .. code-block:: bash + + cp /data/lbpcascades/lbpcascade_frontalface.xml src/main/resources/ + +Now modify src/main/java/HelloOpenCV.java so it contains the following Java code: + +.. code-block:: 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.highgui.Highgui; + 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 = Highgui.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()) { + Core.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)); + Highgui.imwrite(filename, image); + } + } + + public class HelloOpenCV { + public static void main(String[] args) { + System.out.println("Hello, OpenCV"); + + // Load the native library. + System.loadLibrary("opencv_java244"); + new DetectFaceDemo().run(); + } + } + +Note the call to ``System.loadLibrary("opencv_java244")``. +This command must be executed exactly once per Java process prior to using any native OpenCV methods. +If you don't call it, you will get ``UnsatisfiedLink errors``. +You will also get errors if you try to load OpenCV when it has already been loaded. + +Now run the face detection app using ``sbt run``: + + .. code-block:: bash + + sbt run + +You should see something like this: + + .. image:: images/sbt_run_face.png + :alt: SBT run + :align: center + +It should also write the following image to :file:`faceDetection.png`: + + .. image:: images/faceDetection.png + :alt: Detected face + :align: center + +You're done! +Now you have a sample Java application working with OpenCV, so you can start the work on your own. +We wish you good luck and many years of joyful life! diff --git a/doc/tutorials/introduction/table_of_content_introduction/images/Java_logo.png b/doc/tutorials/introduction/table_of_content_introduction/images/Java_logo.png new file mode 100644 index 0000000000..2114751896 Binary files /dev/null and b/doc/tutorials/introduction/table_of_content_introduction/images/Java_logo.png differ diff --git a/doc/tutorials/introduction/table_of_content_introduction/table_of_content_introduction.rst b/doc/tutorials/introduction/table_of_content_introduction/table_of_content_introduction.rst index d918c14972..504e5e5639 100644 --- a/doc/tutorials/introduction/table_of_content_introduction/table_of_content_introduction.rst +++ b/doc/tutorials/introduction/table_of_content_introduction/table_of_content_introduction.rst @@ -101,6 +101,26 @@ Here you can read tutorials about how to set up your computer to work with the O :height: 90pt :width: 90pt +* **Desktop Java** + + .. tabularcolumns:: m{100pt} m{300pt} + .. cssclass:: toctableopencv + + ================ ================================================= + |JavaLogo| **Title:** :ref:`Java_Dev_Intro` + + *Compatibility:* > OpenCV 2.4.4 + + *Authors:* |Author_EricCh| and |Author_AndreyP| + + Explains how to build and run a simple desktop Java application using Eclipse, Ant or the Simple Build Tool (SBT). + + ================ ================================================= + + .. |JavaLogo| image:: images/Java_logo.png + :height: 90pt + :width: 90pt + * **Android** .. tabularcolumns:: m{100pt} m{300pt} @@ -238,10 +258,11 @@ Here you can read tutorials about how to set up your computer to work with the O ../linux_eclipse/linux_eclipse ../windows_install/windows_install ../windows_visual_studio_Opencv/windows_visual_studio_Opencv + ../desktop_java/java_dev_intro ../android_binary_package/android_dev_intro ../android_binary_package/O4A_SDK ../android_binary_package/dev_with_OCV_on_Android ../ios_install/ios_install ../display_image/display_image ../load_save_image/load_save_image - ../how_to_write_a_tutorial/how_to_write_a_tutorial \ No newline at end of file + ../how_to_write_a_tutorial/how_to_write_a_tutorial diff --git a/samples/java/ant/build.xml b/samples/java/ant/build.xml new file mode 100644 index 0000000000..924af1f131 --- /dev/null +++ b/samples/java/ant/build.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/samples/java/ant/src/SimpleSample.java b/samples/java/ant/src/SimpleSample.java new file mode 100644 index 0000000000..990536f2b8 --- /dev/null +++ b/samples/java/ant/src/SimpleSample.java @@ -0,0 +1,19 @@ +import org.opencv.core.Mat; +import org.opencv.core.CvType; +import org.opencv.core.Scalar; + +class SimpleSample { + + static{ System.loadLibrary("opencv_java244"); } + + public static void main(String[] args) { + 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()); + } + +} diff --git a/samples/java/eclipse/HelloCV/.classpath b/samples/java/eclipse/HelloCV/.classpath new file mode 100644 index 0000000000..645263d832 --- /dev/null +++ b/samples/java/eclipse/HelloCV/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/samples/java/eclipse/HelloCV/.project b/samples/java/eclipse/HelloCV/.project new file mode 100644 index 0000000000..b1df1de5e5 --- /dev/null +++ b/samples/java/eclipse/HelloCV/.project @@ -0,0 +1,17 @@ + + + HelloCV + + + + + + org.eclipse.jdt.core.javabuilder + + + + + + org.eclipse.jdt.core.javanature + + diff --git a/samples/java/eclipse/HelloCV/.settings/org.eclipse.jdt.core.prefs b/samples/java/eclipse/HelloCV/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000000..7341ab1683 --- /dev/null +++ b/samples/java/eclipse/HelloCV/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,11 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=1.7 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.debug.sourceFile=generate +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.7 diff --git a/samples/java/eclipse/HelloCV/src/Main.java b/samples/java/eclipse/HelloCV/src/Main.java new file mode 100644 index 0000000000..0e9bb5898f --- /dev/null +++ b/samples/java/eclipse/HelloCV/src/Main.java @@ -0,0 +1,12 @@ +import org.opencv.core.CvType; +import org.opencv.core.Mat; + +public class Main { + + public static void main(String[] args) { + System.loadLibrary("opencv_java244"); + Mat m = Mat.eye(3, 3, CvType.CV_8UC1); + System.out.println("m = " + m.dump()); + } + +} diff --git a/samples/java/sbt/README b/samples/java/sbt/README new file mode 100644 index 0000000000..263ff54749 --- /dev/null +++ b/samples/java/sbt/README @@ -0,0 +1,13 @@ +A demo of the Java wrapper for OpenCV with two examples: +1) feature detection and matching and +2) face detection. +The examples are coded in Scala and Java. +Anyone familiar with Java should be able to read the Scala examples. +Please feel free to contribute code examples in Scala or Java, or any JVM language. + +To run the examples: +1) Install OpenCV and copy the OpenCV jar to lib/. + This jar must match the native libraries installed in your system. + If this isn't the case, you may get a java.lang.UnsatisfiedLinkError at runtime. +2) Go to the root directory and type "sbt/sbt run". + This should generate images in your current directory. diff --git a/samples/java/sbt/lib/copy_opencv_jar_here b/samples/java/sbt/lib/copy_opencv_jar_here new file mode 100644 index 0000000000..e69de29bb2 diff --git a/samples/java/sbt/project/build.scala b/samples/java/sbt/project/build.scala new file mode 100644 index 0000000000..5a7380b964 --- /dev/null +++ b/samples/java/sbt/project/build.scala @@ -0,0 +1,22 @@ +import sbt._ +import Keys._ + +object OpenCVJavaDemoBuild 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 := "OpenCVJavaDemo") + Project(id = "OpenCVJavaDemo", base = file("."), settings = settings) + } +} diff --git a/samples/java/sbt/project/plugins.sbt b/samples/java/sbt/project/plugins.sbt new file mode 100644 index 0000000000..c2371be434 --- /dev/null +++ b/samples/java/sbt/project/plugins.sbt @@ -0,0 +1 @@ +addSbtPlugin("com.typesafe.sbteclipse" % "sbteclipse-plugin" % "2.1.0") diff --git a/samples/java/sbt/sbt/sbt b/samples/java/sbt/sbt/sbt new file mode 100644 index 0000000000..99ae7ec258 --- /dev/null +++ b/samples/java/sbt/sbt/sbt @@ -0,0 +1 @@ +java -Xms512M -Xmx1536M -Xss1M -XX:+CMSClassUnloadingEnabled -XX:MaxPermSize=384M -jar `dirname $0`/sbt-launch.jar "$@" \ No newline at end of file diff --git a/samples/java/sbt/sbt/sbt-launch.jar b/samples/java/sbt/sbt/sbt-launch.jar new file mode 100644 index 0000000000..06ad8d8805 Binary files /dev/null and b/samples/java/sbt/sbt/sbt-launch.jar differ diff --git a/samples/java/sbt/src/main/java/DetectFaceDemo.java b/samples/java/sbt/src/main/java/DetectFaceDemo.java new file mode 100644 index 0000000000..fb08567237 --- /dev/null +++ b/samples/java/sbt/src/main/java/DetectFaceDemo.java @@ -0,0 +1,44 @@ +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.highgui.Highgui; +import org.opencv.objdetect.CascadeClassifier; + +/* + * Detects faces in an image, draws boxes around them, and writes the results + * to "faceDetection.png". + */ +public 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 = Highgui.imread(getClass().getResource( + "/AverageMaleFace.jpg").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()) { + Core.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)); + Highgui.imwrite(filename, image); + } +} \ No newline at end of file diff --git a/samples/java/sbt/src/main/resources/AverageMaleFace.jpg b/samples/java/sbt/src/main/resources/AverageMaleFace.jpg new file mode 100644 index 0000000000..3b96e03b87 Binary files /dev/null and b/samples/java/sbt/src/main/resources/AverageMaleFace.jpg differ diff --git a/samples/java/sbt/src/main/resources/img1.png b/samples/java/sbt/src/main/resources/img1.png new file mode 100644 index 0000000000..93cd5945a7 Binary files /dev/null and b/samples/java/sbt/src/main/resources/img1.png differ diff --git a/samples/java/sbt/src/main/resources/img2.png b/samples/java/sbt/src/main/resources/img2.png new file mode 100644 index 0000000000..41959c66f2 Binary files /dev/null and b/samples/java/sbt/src/main/resources/img2.png differ diff --git a/samples/java/sbt/src/main/scala/Main.scala b/samples/java/sbt/src/main/scala/Main.scala new file mode 100644 index 0000000000..4a68d144a4 --- /dev/null +++ b/samples/java/sbt/src/main/scala/Main.scala @@ -0,0 +1,20 @@ +/* + * The main runner for the Java demos. + * Demos whose name begins with "Scala" are written in the Scala language, + * demonstrating the generic nature of the interface. + * The other demos are in Java. + * Currently, all demos are run, sequentially. + * + * You're invited to submit your own examples, in any JVM language of + * your choosing so long as you can get them to build. + */ +object Main extends App { + // We must load the native library before using any OpenCV functions. + // You must load this library _exactly once_ per Java invocation. + // If you load it more than once, you will get a java.lang.UnsatisfiedLinkError. + System.loadLibrary("opencv_java") + + ScalaCorrespondenceMatchingDemo.run() + ScalaDetectFaceDemo.run() + new DetectFaceDemo().run() +} diff --git a/samples/java/sbt/src/main/scala/ScalaCorrespondenceMatchingDemo.scala b/samples/java/sbt/src/main/scala/ScalaCorrespondenceMatchingDemo.scala new file mode 100644 index 0000000000..30ab0553e3 --- /dev/null +++ b/samples/java/sbt/src/main/scala/ScalaCorrespondenceMatchingDemo.scala @@ -0,0 +1,69 @@ +import org.opencv.highgui.Highgui +import org.opencv.features2d.DescriptorExtractor +import org.opencv.features2d.Features2d +import org.opencv.core.MatOfKeyPoint +import org.opencv.core.Mat +import org.opencv.features2d.FeatureDetector +import org.opencv.features2d.DescriptorMatcher +import org.opencv.core.MatOfDMatch +import reflect._ + +/* + * Finds corresponding points between a pair of images using local descriptors. + * The correspondences are visualized in the image "scalaCorrespondences.png", + * which is written to disk. + */ +object ScalaCorrespondenceMatchingDemo { + def run() { + println(s"\nRunning ${classTag[this.type].toString.replace("$", "")}") + + // Detects keypoints and extracts descriptors in a given image of type Mat. + def detectAndExtract(mat: Mat) = { + // A special container class for KeyPoint. + val keyPoints = new MatOfKeyPoint + // We're using the SURF detector. + val detector = FeatureDetector.create(FeatureDetector.SURF) + detector.detect(mat, keyPoints) + + println(s"There were ${keyPoints.toArray.size} KeyPoints detected") + + // Let's just use the best KeyPoints. + val sorted = keyPoints.toArray.sortBy(_.response).reverse.take(50) + // There isn't a constructor that takes Array[KeyPoint], so we unpack + // the array and use the constructor that can take any number of + // arguments. + val bestKeyPoints: MatOfKeyPoint = new MatOfKeyPoint(sorted: _*) + + // We're using the SURF descriptor. + val extractor = DescriptorExtractor.create(DescriptorExtractor.SURF) + val descriptors = new Mat + extractor.compute(mat, bestKeyPoints, descriptors) + + println(s"${descriptors.rows} descriptors were extracted, each with dimension ${descriptors.cols}") + + (bestKeyPoints, descriptors) + } + + // Load the images from the |resources| directory. + val leftImage = Highgui.imread(getClass.getResource("/img1.png").getPath) + val rightImage = Highgui.imread(getClass.getResource("/img2.png").getPath) + + // Detect KeyPoints and extract descriptors. + val (leftKeyPoints, leftDescriptors) = detectAndExtract(leftImage) + val (rightKeyPoints, rightDescriptors) = detectAndExtract(rightImage) + + // Match the descriptors. + val matcher = DescriptorMatcher.create(DescriptorMatcher.BRUTEFORCE) + // A special container class for DMatch. + val dmatches = new MatOfDMatch + // The backticks are because "match" is a keyword in Scala. + matcher.`match`(leftDescriptors, rightDescriptors, dmatches) + + // Visualize the matches and save the visualization. + val correspondenceImage = new Mat + Features2d.drawMatches(leftImage, leftKeyPoints, rightImage, rightKeyPoints, dmatches, correspondenceImage) + val filename = "scalaCorrespondences.png" + println(s"Writing ${filename}") + assert(Highgui.imwrite(filename, correspondenceImage)) + } +} \ No newline at end of file diff --git a/samples/java/sbt/src/main/scala/ScalaDetectFaceDemo.scala b/samples/java/sbt/src/main/scala/ScalaDetectFaceDemo.scala new file mode 100644 index 0000000000..a35eeb7784 --- /dev/null +++ b/samples/java/sbt/src/main/scala/ScalaDetectFaceDemo.scala @@ -0,0 +1,43 @@ +import org.opencv.core.Core +import org.opencv.core.MatOfRect +import org.opencv.core.Point +import org.opencv.core.Scalar +import org.opencv.highgui.Highgui +import org.opencv.objdetect.CascadeClassifier +import reflect._ + +/* + * Detects faces in an image, draws boxes around them, and writes the results + * to "scalaFaceDetection.png". + */ +object ScalaDetectFaceDemo { + def run() { + println(s"\nRunning ${classTag[this.type].toString.replace("$", "")}") + + // Create a face detector from the cascade file in the resources directory. + val faceDetector = new CascadeClassifier(getClass.getResource("/lbpcascade_frontalface.xml").getPath) + val image = Highgui.imread(getClass.getResource("/AverageMaleFace.jpg").getPath) + + // Detect faces in the image. + // MatOfRect is a special container class for Rect. + val faceDetections = new MatOfRect + faceDetector.detectMultiScale(image, faceDetections) + + println(s"Detected ${faceDetections.toArray.size} faces") + + // Draw a bounding box around each face. + for (rect <- faceDetections.toArray) { + Core.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. + val filename = "scalaFaceDetection.png" + println(s"Writing ${filename}") + assert(Highgui.imwrite(filename, image)) + } +} \ No newline at end of file