Can't get OpenCV to work with Java+Maven+IntelliJ - java

I've seen lots of people asking similar questions to mine but their solutions aren't working for me. Here's what I've got:
I downloaded the latest OpenCV for Windows (2.4.9). I extracted this to C:\opencv-249
I then created a new Maven 3 project in IntelliJ. This works fine and I can run the compile/package goals, etc. I can execute and debug my program. This is all good.
Next, I tried to pull OpenCV into my test app and ended up with the following code:
package com.foo.OpenCVTest;
import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.core.CvType;
/**
* Created by rick on 5/7/2014.
*/
public class RobotCntrl {
static{ System.loadLibrary(Core.NATIVE_LIBRARY_NAME); }
static public void main(String args[]) {
System.out.println("In main!");
System.out.println("Core Lib: " + Core.NATIVE_LIBRARY_NAME);
Mat m = Mat.eye(3, 3, CvType.CV_8UC1);
System.out.println("m = " + m.dump());
}
}
I then added the local OpenCV to my pom.xml:
<dependency>
<groupId>org.opencv</groupId>
<artifactId>opencv</artifactId>
<version>2.4.9</version>
<systemPath>${java.home}/../../../../opencv-249/build/java/opencv-249.jar</systemPath>
<scope>system</scope>
</dependency>
And I added OpenCV as a project library:
And I modified the IntelliJ VM Options (Edit Configurations) to update the java.library.path to point to the OpenCV dlls:
When I run the application appears to load the opencv_java249.dll library just fine (it doesn't complain), but for the line:
Mat m = Mat.eye(3, 3, CvType.CV_8UC1);
It bombs out complaining that it can't find the underlying n_eye() native function:
In main!
Exception in thread "main" java.lang.UnsatisfiedLinkError: org.opencv.core.Mat.n_eye(III)J
Core Lib: opencv_java249
at org.opencv.core.Mat.n_eye(Native Method)
at org.opencv.core.Mat.eye(Mat.java:1467)
at com.aether.Robots.RobotCntrl.main(RobotCntrl.java:25)
Process finished with exit code 1
I'm at a loss now. It's loading the wrapper library but it can't call the dependent functions. For the previous questions on similar issues, it tends to be resolved when people update their java.library.path variable, but mine seems correct:
-Djava.library.path=C:\opencv-249\build\x64\vc10\bin;C:\opencv-249\build\java\x64
or people forget to call System.loadLibrary(), but that call is succeeding (as far as I can tell) for me.
Any ideas?

Related

Error loading OpenCV library from Maven repository

I want to execute a simple OpenCV code to test that the library is well loaded by Maven.
This is the code:
package helloworld;
import org.opencv.core.*;
public class Hello {
public static void main(String[] args)
{
nu.pattern.OpenCV.loadLibrary();
System.out.println("Hey World !");
Mat mat = Mat.eye(3, 3, CvType.CV_8UC1);
}
}
And this is the console output I get, with the two errors, when I try to run it:
java.lang.NoSuchFieldException: sys_paths
at java.base/java.lang.Class.getDeclaredField(Class.java:2417)
at nu.pattern.OpenCV.loadLibrary(OpenCV.java:207)
at helloworld.Hello.main(Hello.java:9)
Hey World !
Exception in thread "main" java.lang.UnsatisfiedLinkError: org.opencv.core.Mat.n_eye(III)J
at org.opencv.core.Mat.n_eye(Native Method)
at org.opencv.core.Mat.eye(Mat.java:1467)
at helloworld.Hello.main(Hello.java:11)
I got the maven repository linking looking at that post.
Would you have any idea about what is causing that?
Thanks!
Try downloading a library from another repository.
<dependency>
<groupId>org.openpnp</groupId>
<artifactId>opencv</artifactId>
<version>3.4.2-1</version>
</dependency>
You can see my answer to the post with a similar problem.

IBM Watson Visual Recognition in Java training classifier error

So I want to make a java application in eclipse which the user i will be able to import .zip files. Each .zip file will represent a cat breed. I will click on a "train" button and my program will contact IBM Watson services and create a classifier. Then from a different window, i will import random cat images and the program will show what cat breed is in the image. Everything with the SDKs is fine since I ran some examples from the official Watson site and everything ran smoothly. Problem comes when I try to create my own classifiers. The code you are about to see is also from their site. For some reason the createClassifier method won't take the CreateClassifierOptions object as an argument.
import java.io.File;
import com.ibm.watson.developer_cloud.http.ServiceCall;
import com.ibm.watson.developer_cloud.speech_to_text.v1.model.RecognitionCallback;
import com.ibm.watson.developer_cloud.visual_recognition.v3.*;
import com.ibm.watson.developer_cloud.visual_recognition.v3.model.*;
public class TrainningClassifier{
public static void main(String[] args) {
VisualRecognition service = new VisualRecognition(
VisualRecognition.VERSION_DATE_2016_05_20
);
service.setApiKey("aca4433597018de62edafdeebceb2bdc1482496a");
CreateClassifierOptions createClassifierOptions = new CreateClassifierOptions.Builder()
.name("dogs")
.addClass("beagle", new File("./beagle.zip"))
.addClass("goldenretriever",new File("./golden-retriever.zip"))
.addClass("husky", new File("./husky.zip"))
.negativeExamples(new File("./cats.zip"))
.build();
Classifier dogs = service.createClassifier(createClassifierOptions).execute();
System.out.println(dogs); /*error is in the above line.
the createClassifier method.*/
}
}
Error: Exception in thread "main" java.lang.Error: Unresolved
compilation problem: The method createClassifier(ClassifierOptions)
in the type VisualRecognition is not applicable for the arguments
(CreateClassifierOptions)
at testVisualRec.ForAssignment.main(ForAssignment.java:31)
Any ideas?
Found the solution. For some reason eclipse wouldn't recommend this solution I had to experiment. I just added throws IOException in main method. I also put inside the main method System.out.println(new File(".").getAbsoluteFile()); to make sure the path was correct, and it was. (SDK used for this project is 4.0.0, not the newest one. SDK found here: https://github.com/watson-developer-cloud/java-sdk/releases)

Java : Reuse a native library already loaded?

Disclaimer Not native English speaker, feel free to edit if needed.
I'm having a similar issue that the one explained here :
java.lang.UnsatisfiedLinkError: Native Library XXX.so already loaded in another classloader
I'm trying to follow the answer of user2543253. But I really lacks of knowledge in Java and the context is a bit different.
Links
.dll already loaded in another classloader? Seems also related to this question.
https://github.com/PatternConsulting/opencv/issues/7 Similar.
https://cycling74.com/articles/mxj-class-loading Explains the class loader behavior of MXJ
Context
Edit : Not sure if that context is really important, it seems to be the same problem described in link 1.
I want to use OpenCV inside an Application called Max/MSP.
To give an idea, it looks like this :
Max/MSP allows user to assemble Patch by cabling some objects together that are called externals, most of them are coded in C but you can also create externals in Java. To do so you need to instantiate them through an object called "mxj". For example, if my Java class is called TestOpenCV, I will create a box and put "mxj TestOpenCV" inside.
OpenCV seems correctly implemented, for exemple, I can instantiate a Mat object and post its content to Max console.
Problems appears when I change the Java code of the mxj object. To update my object, I delete it and recreate it again. Then, the same issue that explained here appears...
Max console return this error message :
java.lang.UnsatisfiedLinkError: Native Library
C:\Windows\System32\opencv_java300.dll already loaded in another
classloader at java.lang.ClassLoader.loadLibrary1(Unknown Source) at
java.lang.ClassLoader.loadLibrary0(Unknown Source) at
java.lang.ClassLoader.loadLibrary(Unknown Source) at
java.lang.Runtime.loadLibrary0(Unknown Source) at
java.lang.System.loadLibrary(Unknown Source) at
OpenCVClassLoad.loadNativeLibrary(OpenCVClassLoad.java:5) at
TestOpenCV.(TestOpenCV.java:22) (mxj) unable to alloc instance
of TestOpenCV
What I tried
I tried to implement the answer of user2543253. He advices to create a tiny classes that import the native library and export it as a JAR. So I created a new Eclipse project added a source file to it
import org.opencv.core.Core;
public class OpenCVClassLoad {
public static void loadNativeLibrary() {
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
}
}
I added the openCV JAR to that project and exported it as a JAR.
Then I changed my code according to what user2543253 explained (there is more code,I kept the essential) :
import com.cycling74.max.*;
import org.opencv.core.Core;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.core.Scalar;
public class TestOpenCV extends MaxObject {
static {
// System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
OpenCVClassLoad.loadNativeLibrary();
}
public TestOpenCV(Atom[] args)
{
// ...
}
public void notifyDeleted()
{
// ...
}
public void bang() {
// Executed when I trig the little bang button you can see
Mat m = new Mat(5, 9, CvType.CV_8UC4, new Scalar(0));
post("OpenCV Mat: " + m);
Mat mr1 = m.row(1);
mr1.setTo(new Scalar(1));
Mat mc5 = m.col(3);
mc5.setTo(new Scalar(5));
post("OpenCV Mat data:\n" + m.dump());
}
}
Of course, but that's a bit weird, in order to build correctly that project I kept the JAR from OpenCV in the build path :
As you can see, I also added the tiny class in the project build path.
After all of theses modifications, the mxj object stille loads correctly the first time and the bang() method still works but the problem still there. In fact it doesn't change anything from the past situation : If I modify the Java code, delete the object in Max and create a new one, error appears...
Question
There is a lot of SO questions addressing the same type of prob but context is always different and its hard to figure out what to do, especially with my basic knowledge of Java.
A workaround should be to simply reuse that library already loaded, no ? but how to achieve this ? Because if I check the library has already being loaded, I do it using a Try / Catch, if I do nothing else. The externals acts like if the library had never been loaded...
How to reuse that native library ? (Of course, any alternative solution to this is welcome)
Just remove the second OpenCVClassLoad.loadNativeLibrary(); in your bang() method. In a plain Java application the code in a static block is only executed once.
Alternatively, you can specify the native library location in Eclipse instead of loading the library through Java source code.

OpenCV + Java = UnsatisfiedLinkError

I need capture a video stream from my USB webcam, for this i use Opencv 2.4.6 for developing in Java. I follow the steps listed in here
I add the "C:\opencv\build\java\x64" dir to my System PATH and include the "opencv-246.jar" file into my libraries on ECLIPSE. When y run the explame
import org.opencv.core.Core;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
public class Main {
public static void main(String[] args) {
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
Mat m = Mat.eye(3, 3, CvType.CV_8UC1);
System.out.println("m = " + m.dump());
}
}
i get
m = [1, 0, 0;
0, 1, 0;
0, 0, 1]
OK =)
but when i run
import org.opencv.highgui.VideoCapture;
public class Main {
public static void main(String[] args) {
VideoCapture vc = new VideoCapture(0);
if(vc.isOpened()){
System.out.println("Works!");
}
}
}
i get
Exception in thread "main" java.lang.UnsatisfiedLinkError: org.opencv.highgui.VideoCapture.n_VideoCapture(I)J
at org.opencv.highgui.VideoCapture.n_VideoCapture(Native Method)
at org.opencv.highgui.VideoCapture.<init>(VideoCapture.java:113)
at Main.main(Main.java:5)
i add all the routes containes in:
C:\opencv\build\x64\vc10
one by one,but doesn`t work.
Finally i create a variable called OPENCV_DIR with C:\opencv\build\x64\vc10 but still getting UnsatisfiedLinkError.
PLEASE HELP ME!
in your second example , you skipped this line
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
so the opencv libs werent loaded, UnsatisfiedLinkError, etc...
[edit]:
thanks to #Jishnu Prathap for highlighting the java.library path issue, if you run into problems setting that, you can still try to use an absolute path to the java wrapper so/dll/dylib like:
System.load("/path to/our/java_wrapper");
I had a similar error while using OpenCV with java.I did 2 things to resolve it.
static{ System.loadLibrary(Core.NATIVE_LIBRARY_NAME); }
I added the path to OpenCV dll or .so to javalibpath or path. which actually didnt work for some reason and i ended up putting the OpenCV dll in the system32 folder.
Try the below code
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import nu.pattern.OpenCV;
public class OpencvMain
{
public static void main( String[] args )
{
OpenCV.loadLocally();
Mat mat = Mat.eye( 3, 3, CvType.CV_8UC1 );
System.out.println( "mat = " + mat.dump() );
}
}
For general users using opencv3.x:
HighGUI module does not exist anymore in Java for opencv 3.0 and above.
import org.opencv.videoio.VideoCapture;
instead of
import org.opencv.highgui.VideoCapture;
videoio includes VideoCapture, VideoWriter.
Similarly:
imgcodecs includes imread/imwrite and friends
Example:
Highgui.imread(fileName)
-->
Imgcodecs.imread(fileName)
So, I was having this problem too and I did what you all suggested, it worked fine in my x64 windows, but in a x86 couldn't make it work.
At last I found a solution by changing:
VideoCapture capture = new VideoCapture(0);
for
VideoCapture capture = new VideoCapture();
capture.open("resources/vid.MP4");
I don't know why this worked but I hope it may help somebody with my same problem.
I tried a lot of tutorials online for the resolution, only one of them have helped me.
There are two steps that are different in this method,
Firstly, while importing the java project from Opencv SDK into the Android studio, make sure to uncheck all the checkboxes presented in the import dialog.
Secondly, make sure you import the OpenCV.mk file that is in the native/jdk of the SDK..
The System.loadLibrary() seems to return true after this, which was a huge relief for me as it took me several hours to figure this out
Here's the link to the tutorial that helped me
https://medium.com/#rdeep/android-opencv-integration-without-opencv-manager-c259ef14e73b

OpenCV for Eclipse

Installation instructions: http://docs.opencv.org/doc/tutorials/introduction/desktop_java/java_dev_intro.html
I have downloaded everything. Everything seems to be working except when I run this sample program:
import org.opencv.core.Core;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
public class Main {
public static void main(String[] args) {
System.out.println("Welcome to OpenCV " + Core.VERSION);
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
Mat m = Mat.eye(3, 3, CvType.CV_8UC1);
System.out.println("m = " + m.dump());
}
}
I get the output:
m = [1, 0, 0;
0, 1, 0;
0, 0, 1]
(which I hope is right).
But I also get these error messages:
objc[63784]: Class CVWindow is implemented in both /Users/.../cv2.so and /Users/... /libopencv_java246.dylib. One of the two will be used. Which one is undefined.
objc[63784]: Class CVView is implemented in both /Users/.../cv2.so and /Users/.../libopencv_java246.dylib. One of the two will be used. Which one is undefined.
objc[63784]: Class CVSlider is implemented in both /Users/.../cv2.so and /Users/.../libopencv_java246.dylib. One of the two will be used. Which one is undefined.
objc[63784]: Class CaptureDelegate is implemented in both /Users/... /cv2.so and /Users/jsuit/opencv/lib/libopencv_java246.dylib. One of the two will be used. Which one is undefined.
I have tried moving the cv2.so file to another folder, but then the program won't compile.
The problem has to do, as far as I can make out, with a reference to the Python libraries (the .so version) that ends up included within the Java libraries themselves. This would seem to be a build configuration error (following the instructions does produce it).
I was able to eliminate the double-definition error by re-building the Java version without support for the Python libraries in it, using the following in the cmake step (all else the same):
cmake -D BUILD_SHARED_LIBS=OFF -D BUILD_NEW_PYTHON_SUPPORT=NO ..
The newly produced Java libraries and .jar work just as before, but without the error message.
(Note that I can't guarantee this won't cause other problems, especially if you want to do some sort of mixed-language programming, but it does produce libraries useful for Java and Eclipse. You can always build multiple versions of OpenCV, too, some with support for Python, some without, and use whichever one you like if you switch languages at some point.)
Hat tip: http://answers.opencv.org/question/16015/mac-opencv-246-java-exception/

Categories

Resources