I'm trying to load a video file in OpenCV Java, and have narrowed down my issue to the following code:
import org.opencv.core.Core;
import org.opencv.videoio.VideoCapture;
public class OpenCVTest {
public static void main(String[] args) {
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
System.loadLibrary("opencv_videoio_ffmpeg455_64");
VideoCapture capture = new VideoCapture("myVideoFile.avi");
System.out.println(capture.isOpened());
}
}
Of course, this always prints out "false". Accessing my computer's camera with new VideoCapture(0) works fine. After scouring the internet, I'm thoroughly confused as to why loading a video won't work. I followed guides that suggested I needed to add "opencv_videoio_ffmpeg455_64.dll" to my path variable and call System.loadLibrary. I'm new to this, and to be honest, I don't understand what loadLibrary does, or what could be wrong with my setup and code. Any ideas? Thanks in advance.
Here is the answer from similar problem
load the ffmpeg library System.loadLibrary("opencv_ffmpeg300_64");
Open the file:
VideoCapture vC = new VideoCapture("res/video.mp4");
Copy opencv_ffmpeg300_64.dll from opencv\build\x64\vc11\bin to
opencv\build\java\x64
Please note that 64 and .dll may differ from an OS to another, those are for Windows x64
As it turns out, I was using the wrong file path. I (wrongly) assumed that new VideoCapture("my file") would search for "my file" in the directory where the compiled .class files are placed, when in fact it searches in the project root directory. There is no need to call System.loadLibrary("opencv_videoio_ffmpeg455_64");
Related
ok i am a new one here and tried to write an awesome program:
package f;
import javax.swing.*;
public class dasMain {
public static void main(String[] args) {
ImageIcon img = new ImageIcon("pics/daFaq.png");
JOptionPane.showMessageDialog(null, img, "u r heck", JOptionPane.PLAIN_MESSAGE);
}
}
the thing is that if I run the program from Intellij Idea, then everything works fine, but after compilation the picture disappears
here are the source files of the project:
https://i.ibb.co/Njc8jYp/screen.png
i want to run this awesome code with pictures on other computers, but i only know this way and it doesn't work :(
You probably do not know where your program expects the picture to be. If you modify your code slightly, this information would be evident. Make use of
ImageIcon(URL)
File.toURI()
URI.toURL()
With that your code can look like this:
package f;
import javax.swing.*;
import java.io.File;
public class dasMain {
public static void main(String[] args) {
File png = new File("pics/daFaq.png");
System.out.println("Loading image from " + png.getAbsolutePath());
ImageIcon img = new ImageIcon(png.toURI().toURL());
JOptionPane.showMessageDialog(null, img, "u r heck", JOptionPane.PLAIN_MESSAGE);
}
}
Also I am pretty sure you intend to ship the png together with your code, so you better load it as a resource from the classpath. Here is an example.
I also investigated a bit why you would not see any error message or exception. This is documented in ImageIcon. So you might want to verify the image was loaded using getImageLoadStatus().
If you access the resource with the path like pics/file_name.png, then the pics - is the package name. And it must be located in the directory, marked as resource type. For example, create the directory, named resources in your project root, mark this directory as resource type, and move the pics there:
P. S. I would advise to use Maven or Gradle build system for managing project builds. As it is commonly accepted build management systems for the JVM projects. IDE New Project Wizard has the option to create Maven or Gradle based projects.
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.
hey guys i just make some changes to the previous one ....
that is
import java.io.*;
import java.nio.*;
public class Test1234{
public static void main(String args[]){
File inputF = new File(Test1234.class.getProtectionDomain().getCodeSource().getLocation().getFile());
File outputF = new File("D:\\test.class");
FilePermission adb = new FilePermission(inputF.getPath(),"write,read,execute");
Files.copy(inputF.toPath(),outputF.toPath(),REPLACE_EXISTING);
}
}
for simplicity the inputF points to the class file itself. And it compiles perfect. but when i found the file test.class it only is an empty folder.
so please guys help me !!! I'm stuck with this problem.
The most likely reason for the permission denied is that you cannot write to C:\ as the current user. Chose a folder you can write to or run as administrator.
Since you are running a plain main method there is very probably no SecurityManager, plus you would get a SecurityException if that was the problem. Also, it does not matter whether you read the current code source, only on Windows you cannot delete or write to it since this would be locked by the OS.
If that is not the problem, you need to verify Test1234.class.getProtectionDomain().getCodeSource().getLocation().getPath() points to what you actually want to copy. A stack trace would help in that case.
i just found out the solution by building my class file to jar file. then when i run it, it created a cloned jar file named test.jar. by when i just say this one you must change the outputF path to "d:\test.jar". :)
I can run programs which do not have a package without any hitch. If I try and add a package then java simply cannot find them. I have set the class path and I have tried running - java packagename.ProgramName.
I have found a number of similar threads on here and have spent four hours going through all of them and trying everything and nothing works for me.
Yet as soon as I edit the .java file and recompile without a package heading - it immediately works perfectly. Why? And how can I fix it? I would like to be able to have my classes organised in packages!
This is the code I am using (I normally use eclipse and just wrote this to try out cmd out of curiosity).
package hello;
public class HelloWorldApp{
public static void helloWorld(){
System.out.println("Hello world");
}
}
and
package hello;
public class HelloBackApp{
public static void helloBack(){
System.out.println("Hello back");
}
public static void main(String[] args){
HelloWorldApp.helloWorld();
helloBack();
}
}
As I say if I delete both the package heading java HelloBackApp runs just fine.
And my path to my program is
c:\Users\sam\javastuff\hello
I have of course tried java hello.HelloBackApp from both the javastuff dir and the hello dir. No joy
It works immediately if I delete both the package headings and type java HelloBackApp from the hello directory.
try as follows,
create folder structure as your package and place java file in that folder
For ex, my java file is under
c:\code\com\test\Test.java and package is "package com.test".
I compiled and run code from
c:\code>
c:\code> javac com\test\Test.java
c:\code> java com.test.Test
Ok after much research I realised what my problem was and have fully resolved it. I think I see why I have been unable to find an "answer" to this question in forums. It is not a simple quick fix - my whole understanding of how to correctly get the class path set up and get a proper compile done was very poor. It becomes a whole new subject if you switch from compiling/running on an IDE to doing so from the command line. I think it is an excellent thing for new programmers to do though as I believe the improved understanding of CLASSPATH is going to be something that will stand us all in good stead for the future.
I found all the answers to my questions here : http://www.ibm.com/developerworks/java/library/j-classpath-windows/
and recommend anyone having similar problems I was having to read through this excellent document. Best wishes to all the other guys struggling with this out there! :)
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