It's the first day of learning JavaCV for me. And this is the first test example which I use just to make sure that my setup is done correctly. Unfortunately I can't run the example and I barely understand the code and all dependencies so it's really hard for me to find out what is missing. Below I'll post my project setup and also the errors I get.
Also the example I use is from: http://ganeshtiwaridotcomdotnp.blogspot.com/2011/12/javacv-capture-save-flip-show-live.html
code
import static com.googlecode.javacv.cpp.opencv_core.cvFlip;
import static com.googlecode.javacv.cpp.opencv_highgui.cvSaveImage;
import com.googlecode.javacv.CanvasFrame;
import com.googlecode.javacv.FrameGrabber;
import com.googlecode.javacv.VideoInputFrameGrabber;
import com.googlecode.javacv.cpp.opencv_core.IplImage;
public class GrabberShow implements Runnable
{
//final int INTERVAL=1000;///you may use interval IplImage image;
CanvasFrame canvas = new CanvasFrame("Web Cam");
public GrabberShow()
{
canvas.setDefaultCloseOperation(javax.swing.JFrame.EXIT_ON_CLOSE);
}
#Override
public void run()
{
FrameGrabber grabber = new VideoInputFrameGrabber(0); // 1 for next camera
int i = 0;
try
{
grabber.start();
IplImage img;
while (true)
{
img = grabber.grab();
if (img != null)
{
cvFlip(img, img, 1);// l-r = 90_degrees_steps_anti_clockwise
cvSaveImage((i++) + "-aa.jpg", img); // show image on window
canvas.showImage(img);
}
//Thread.sleep(INTERVAL);
}
}
catch (Exception e)
{
}
}
}
I use Eclipse and it seems like all imports are there.
Here is a print screen of my project as it looks like in Eclipse:
So this is it for the setup. I try to get something out of this. When I right click on the project and try to Run it as Java Application the following windows is showing up:
You can see my choice at the top of the window. The I get an error window A Java Exception has occurred and here is part of the error I get in the console window:
Exception in thread "main" java.lang.UnsatisfiedLinkError: C:\Users\Xman\AppData\Local\Temp\javacpp4929678155627\jniopencv_core.dll: Can't find dependent libraries
at java.lang.ClassLoader$NativeLibrary.load(Native Method)
at java.lang.ClassLoader.loadLibrary0(Unknown Source)
at java.lang.ClassLoader.loadLibrary(Unknown Source)
at java.lang.Runtime.load0(Unknown Source)
at java.lang.System.load(Unknown Source)
at com.googlecode.javacpp.Loader.loadLibrary(Loader.java:422)
at com.googlecode.javacpp.Loader.load(Loader.java:372)`
I've read the error, it seems like the problem is caused by missing libraries but I'm not sure, also I have followed the instructions (which weren't that many in fact) and from the comments below the example code it seems that it actually works. So I guess the problem is somewhere here - in my project, code, setup, but I can't find what I'm missing or doing wrong.
This error occurs when your opencv dll are not set in System path.
If you have extracted your opencv folder in C:\ directory then set your path as following
For 32 bit:
C:\opencv\build\x86\vc10\bin;C:\opencv\build\common\tbb\ia32\vc10\
For 64 bit:
C:\opencv\build\x64\vc10\bin;C:\opencv\build\common\tbb\intel64\vc10\
If you have extracted in different location then change the path accordingly.
In order to set path you can go to Control Panel > System Security > System > Advanced System Settings > Environment Variables. In System variable select path and click on Edit and insert above locations and restart windows.
you can find detailed instructions at http://opencvlover.blogspot.in/2012/04/javacv-setup-with-eclipse-on-windows-7.html
Download and install : Microsoft Visual C++ redistributable package (32-bit): vcredist_x86.exe
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.
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");
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.
public void loadStdImage() throws IOException
{
Image image = ImageIO.read(this.getClass().getResource("/Resources/Images/Student/Capture.png")); //Line 350
ImageIcon icon = new ImageIcon(image);
JLabel lblImage = new JLabel(icon);
lblImage.setIcon(icon);
lblImage.setBounds(753, 50, 149, 171);
add(lblImage);
}
I tried many things... but nothing works out. Continuously showing the following run-time error
Exception in thread "AWT-EventQueue-0" java.lang.IllegalArgumentException: input == null!
at javax.imageio.ImageIO.read(Unknown Source)
at View.Student.loadStdImage(Student.java:350)
Project folder structure is:
edit:
Found the solution. See the change of icon of the resource folder in the following picture and the above image. I added my resource folder to Java Build Path. Right click on your project, go to properties, then select 'Java Build Path', from there add your folder to java build path.
Cheers
enter image description here
welcome to SO. As you are new here, please read this - https://stackoverflow.com/help/mcve
Let me help you with this for now.
I have standard Eclipse project:
and my test class looks like (minimal):
package q34460547;
import java.awt.Image;
import java.io.IOException;
import javax.imageio.ImageIO;
public class LoadTest {
public static void main(String[] args) throws IOException {
new LoadTest().loadStdImage();
}
public void loadStdImage() throws IOException {
Image image = ImageIO.read(this.getClass().getResource("/ScreenShot005.png"));
}
}
and now, when I used
ImageIO.read(this.getClass().getResource("/ScreenShot005.png"));
image is loaded from res so called source folder in Eclipse.
When I used
ImageIO.read(this.getClass().getResource("ScreenShot005.png"));
image s loaded from the folder in which LoadTest.java file is (to be precise it is also compiled to same folder - in Eclipse it's bin).
You can find more info for example here - What is the difference between Class.getResource() and ClassLoader.getResource()?
edit:
The image has to be on classpath (when using Class.getResource), that's why it was not loaded from Resources folder. There are two options, use another version of ImageIO.read() or make your Resources folder a source folder:
It looks like I cannot use Desktop.open() on PDF files regardless of location. Here's a small test program:
package com.example.bugs;
import java.awt.Desktop;
import java.io.File;
import java.io.IOException;
public class DesktopOpenBug {
static public void main(String[] args)
{
try {
Desktop desktop = null;
// Before more Desktop API is used, first check
// whether the API is supported by this particular
// virtual machine (VM) on this particular host.
if (Desktop.isDesktopSupported()) {
desktop = Desktop.getDesktop();
for (String path : args)
{
File file = new File(path);
System.out.println("Opening "+file);
desktop.open(file);
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
If I run DesktopOpenBug with arguments c:\tmp\zz1.txt c:\tmp\zz.xml c:\tmp\ss.pdf (3 files I happen to have lying around) I get this result: (the .txt and .xml files open up fine)
Opening c:\tmp\zz1.txt
Opening c:\tmp\zz.xml
Opening c:\tmp\ss.pdf
java.io.IOException: Failed to open file:/c:/tmp/ss.pdf. Error message:
The parameter is incorrect.
at sun.awt.windows.WDesktopPeer.ShellExecute(Unknown Source)
at sun.awt.windows.WDesktopPeer.open(Unknown Source)
at java.awt.Desktop.open(Unknown Source)
at com.example.bugs.DesktopOpenBug.main(DesktopOpenBug.java:21)
What the heck is going on? I'm running WinXP, I can type "c:\tmp\ss.pdf" at the command prompt and it opens up just fine.
edit: if this is an example of Sun Java bug #6764271 please help by voting for it. What a pain. >:(
I never knew about this Desktop command, untill recently through this post:
would Java's Runtime.getRuntime().exec() run on windows 7?
Previously i have been using:
Runtime.getRuntime().exec("rundll32 SHELL32.DLL,ShellExec_RunDLL "+ myfile);
And it has always worked for me. If your method does not work, may be you can think about try this command.
If you switch the order of your arugments does that cause one of the other files to get that same error. I wonder if you need to trim the end of the path before calling the File constructor.
umm...yeah ignore that... check the documentation of Desktop.open. open throws an IO exception "if the specified file has no associated application or the associated application fails to be launched " ... also from the top of the page... "The mechanism of registereing, accessing, and launching the associated application is platform-dependent. "
code for the Desktop class: http://fuseyism.com/classpath/doc/java/awt/Desktop-source.html
The open method calls DesktopPeer.open.
DesktopPeer source: http://www.jdocs.com/javase/7.b12/java/awt/peer/DesktopPeer.html
DesktopPeer is implementation specific.
Here is source for a Windows-specific implementation:
http://www.java2s.com/Open-Source/Java-Document/6.0-JDK-Platform/windows/sun/awt/windows/WDesktopPeer.java.htm
open->ShellExecute->(Native)ShellExecute
Native ShellExecute is a wrapper for Win32 ShellExecute. Here is info on the function.
http://msdn.microsoft.com/en-us/library/bb762153(VS.85).aspx
My suggestion for a work around would be to write your own implmentation of the ShellExecute function. Here is source from someone who did it. http://www.heimetli.ch/shellexec.html