Use OpenCV in Java

Introduction

I wanted to use the OpenCV library in Java, but it was unexpectedly difficult, so I will write down the procedure. As a way to organize peripheral knowledge, it also led to an understanding of basic things such as how to use Java libraries and packages, so I will touch on that as well. Both (1) when compiling in the terminal and (2) when compiling using IDE (especially IntelliJ) are described.

environment

Java installation

Just in case, I will leave the Java installation method (macOS). I installed it using Homebrew.

# install Homebrew (if needed)
ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
# update packages, install cask, and allow cask to look up versions
brew update
brew tap homebrew/cask
brew tap homebrew/cask-versions
# install Java
brew cask install java #You can install by specifying the version if you use java13 etc.

This will install Java in / Library /. The hierarchical structure should look like this:

/Library/Java
          |-- Extensions/ #Java extension folder
          `-- JavaVirtualMachine/
               `-- openjdk-13.0.2.jdk/ #Installed JDK
                    `-- Contents/
                         |-- Home/ #JDK home directory
                         |    |--
                         |     ...
                         |-- MacOS/
                         `-- Info.plist

By the way, as usual

java --version

Then you can check the version.

OpenCV You can install OpenCV Java on macOS by following the first site below. As of June 2020, the latest Java is 4.3.0, so if you install it without specifying the version, it will be installed. The installation itself takes an unexpected amount of time.

Hopefully, the libraries will be installed in /usr/local/Cellar/opencv/4.3.0_4/share/java/ with the following hierarchical structure. This should vary depending on the machine and software version.

/java/
  `-- opencv4/
       |-- opencv-430.jar #Static library
       `-- libopencv_java430.dylib* #Dynamic library
            |--
             ...

By the way, the .jar file is a static library, the .dylib file is a dynamic library (abbreviation of dynamic library), and the dynamic library is a library that is referenced at runtime, not at compile time [^ 1]. By the way, the jar file is a compressed file that collects the class files created by compilation into one [^ 2].

Compile and run

Test.java


import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.core.CvType;
import org.opencv.core.Scalar;

public class Test {
    // Compulsory
    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());
    }
}

Create a file like this and compile it. In the directory where the file is located, just like compiling a .java file normally

javac Test.java

When I compile it as, I get a lot of errors as below. Screen Shot 2020-06-08 at 20.16.11.png It says "package org.opencv.core does not exist", which means that the OpenCV library cannot be found. In other words, even though OpenCV was installed, javac could not find the library at compile time. In order to solve this, it is necessary to give it through ** classpath ** as follows. By adding the -classpath or -cp option at compile time, javac will look there.

javac -classpath /usr/local/Cellar/opencv/4.3.0_4/share/java/opencv4/opencv-430.jar Test.java

You also need to specify the dynamic library path at runtime.

java -Djava.library.path="/usr/local/Cellar/opencv/4.3.0_4/share/java/opencv4" -classpath /usr/local/Cellar/opencv/4.3.0_4/share/java/opencv4/opencv-430.jar: Test

By the way, you have to put a colon : after the classpath at runtime (macOS). For Windows, it is a semicolon ;. If done correctly

Execution result


Welcome to OpenCV 4.3.0
OpenCV Mat: Mat [ 5*10*CV_8UC1, isCont=true, isSubmat=false, nativeObj=0x7fd0f2e3f230, dataAddr=0x7fd0f2e3f0c0 ]
OpenCV Mat data:
[  0,   0,   0,   0,   0,   5,   0,   0,   0,   0;
   1,   1,   1,   1,   1,   5,   1,   1,   1,   1;
   0,   0,   0,   0,   0,   5,   0,   0,   0,   0;
   0,   0,   0,   0,   0,   5,   0,   0,   0,   0;
   0,   0,   0,   0,   0,   5,   0,   0,   0,   0]

Is displayed.

More correctly

To create a class in Java in a separate file and use that class in another Java file, use ʻimport or package`. The above example is a single file, but when building a program, the files often depend on each other in this way. In addition to that, this time we want to refer to OpenCV, that is, an external library. In such a case, as before

javac -classpath /usr/local/Cellar/opencv/4.3.0_4/share/java/opencv4/opencv-430.jar Test.java

When I tried to compile as, I got an error with package and import this time.

This means that you specified a classpath and javac went looking for packages and imports from that path and couldn't find it. Java expresses the hierarchical structure of packages and imports with dots . instead of slashes/, but it is written with a relative path from the current directory where compilation is executed in the first place ([Reference site](Reference site). In other words, ** the classpath was the current directory by default **, but I overwrote it with the -classpath option, so I can't find it this time.

One possible solution is to change the package or import path to (1) an absolute path or (2) a relative path from the -classpath option specified at compile time. However, the absolute path is long, and you have to rewrite it each time you move the program to another PC. Also, it is nonsense to change the contents of the file in consideration of the compile options, and the location of the external library differs depending on each PC, so you have to rewrite it each time. After all, it is usually a relative path from the main file.

Therefore, instead of rewriting the classpath, I would like to specify it so that it is added (including the path for the OpenCV library), but if you connect it with a colon :, you can specify multiple classpaths, so use this. .. It means to specify as -classpath.: (OpenCV path) including . of the current directory. By doing this, while preserving the original package dependencies etc., a new classpath for the OpenCV library is also added.

javac -classpath .:/usr/local/Cellar/opencv/4.3.0_4/share/java/opencv4/opencv-430.jar Test.java #compile
java -Djava.library.path="/usr/local/Cellar/opencv/4.3.0_4/share/java/opencv4" -classpath .:/usr/local/Cellar/opencv/4.3.0_4/share/java/opencv4/opencv-430.jar: Test #Run

Now you can compile and run correctly. (Reference site) Java Programming: Package and Classpath

Another way

This method is a method to temporarily specify the classpath at the time of compilation or execution, but since / Library / Extensions / is a Java extension folder, it is said that the path is passed by inserting the jar file and dylib file here. There seems to be a method. In that case, you don't have to specify the -classpath option every time.

Setting method in IntelliJ

[** IntelliJ **](https://www.jetbrains.com/idea/promo/ultimate/?gclid=Cj0KCQjwoPL2BRDxARIsAEMm9y-AFlyJ1PpLvFySDiJJ-ABoUi0xzY9fdK4FnQLvO4dX-6PMt7Md Environment). Earlier I used OpenCV when developing with an editor and terminal, but I will also write down the setting method when using IntelliJ. By the way, the tutorial of IntelliJ itself is below.

basic configuration

Just in case, I will leave the basic setting procedure from the installation of IntelliJ.

Installation

Select the OS from the Installation page and download the Community Edition (students can also download licensed).

Plugin

(If necessary) * Welcome to IntelliJ IDEA * Open the plugin from * Configure-> Plugins * in the window ("Java Visualizer" etc. is convenient). If you install the plugin, you need to restart IntelliJ.

SDK settings

SDK (Software Development Kit) is a software development tool, which is required for software development. The SDK for Java is called JDK (Java Development Kit), which is already installed in the OS, so it is good when developing on the terminal, but IntelliJ also needs to know this, that is, pass it through the path. there is. Screen Shot 2020-06-08 at 12.16.39.png

Set the SDK (Software Development Kit) from "* Configure-> Structure for New Projects *". You can do this by following this document.

OpenCV library settings

You can develop a basic program with the above settings, but when you use an external library like this time, you have to set it. IntelliJ is an IDE that compiles and executes in it, so it is necessary to set in advance something like specifying the classpath when compiling and executing in the terminal. Taking this OpenCV as an example, the flow will be explained.

Select "* File-> Project Structure " to open the window and select " Modules " from the tab on the left. Then select the " Depencencies " field, select " JARs or directories *" from the add button (+ button at the bottom left), and add the .jar file in the installed OpenCV. In my case, it was in the location /usr/local/Cellar/opencv/4.3.0_4/share/java/opencv4/opencv-430.jar. Select that file and it will be added like this Screen Shot 2020-06-08 at 13.09.35.png

Next, double-click the added jar file field to open the window "* Configure Module Library ". From the add button at the bottom left, this time it is in the same directory as the jar file. /usr/local/Cellar/opencv/4.3.0_4/share/java/opencv4/libopencv_java430.dylib Select the file. Then, a column called " Native Library Locations *" will be added as shown in the picture, and this is the end. Screen Shot 2020-06-08 at 12.57.18.png

If you try to run the same test file as above and get the correct result, you have set it correctly. By the way,

--If you get a compile error at the import stage, it means that ʻopencv-430.jar` is not set properly as the External Library, so check the stage of the first photo.

For this procedure, I referred to the one carefully written on the following site. Some modifications may be required depending on the version of OpenCV.

Recommended Posts

Use OpenCV in Java
Use PreparedStatement in Java
Use Redis Stream in Java
[Java] Do not use "+" in append!
Use composite keys in Java Map.
How to use classes in Java?
Java + OpenCV 3.X in IntelliJ IDEA
Do you use Stream in Java?
Partization in Java
Rock-paper-scissors in Java
[Java] Use Collectors.collectingAndThen
Pi in Java
FizzBuzz in Java
Multilingual Locale in Java How to use Locale
Use OpenCV_Contrib (ArUco) in Java! (Part 2-Programming)
[Java] Use cryptography in the standard library
Use "Rhino" which runs JavaScript in Java
I did OpenCV camera calibration in Java
[java] sort in list
Read JSON in Java
Interpreter implementation in Java
Make Blackjack in Java
Rock-paper-scissors app in Java
Constraint programming in Java
Put java8 in centos7
Detect similar videos in Java and OpenCV rev.2
NVL-ish guy in Java
Combine arrays in Java
"Hello World" in Java
Callable Interface in Java
Use java.time in Jackson
Azure functions in java
Simple htmlspecialchars in Java
Boyer-Moore implementation in Java
Use Interceptor in Spring
Hello World in Java
webApi memorandum in java
Detect similar videos in Java and OpenCV rev.3
Type determination in Java
Ping commands in Java
Various threads in java
Heapsort implementation (in java)
Zabbix API in Java
ASCII art in Java
Compare Lists in Java
POST JSON in Java
Use MouseListener in Processing
Use images in Rails
Express failure in Java
Use PostgreSQL in Scala
Create JSON in Java
[JAVA] [Spring] [MyBatis] Use IN () with SQL Builder
Date manipulation in Java 8
What's new in Java 8
Detect similar videos in Java and OpenCV rev.1
Why use setters/getters instead of public/private in Java
What's new in Java 9,10,11
Parallel execution in Java
Initializing HashMap in Java
I want to use ES2015 in Java too! → (´ ・ ω ・ `)
[JAVA] [Spring] [MyBatis] Use GROUP BY in SQL Builder