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.
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].
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.
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.
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
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.
[** 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.
Just in case, I will leave the basic setting procedure from the installation of IntelliJ.
Select the OS from the Installation page and download the Community Edition (students can also download licensed).
(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 (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.
Set the SDK (Software Development Kit) from "* Configure-> Structure for New Projects *". You can do this by following this document.
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
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.
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.
static{ System.loadLibrary(Core.NATIVE_LIBRARY_NAME); }
If you get an error in, this means that "* Native Library Locations *" has not been set properly, so it means that the settings have not been set properly at the stage of the second 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