So I built a vision library on windows, and I've ran it on Windows and it ran okay. I used the command:
java -jar LiftTracker.jar
I transferred the .jar file I built on windows over to a Raspberry Pi, and did a make install to install the opencv libraries. Once I did that, I tried to do the same command as above and came up with the error:
java.lang.UnsatisfiedLinkError: no opencv_java310 in java.library.path.
I did some research and found that I could run this command along side the -jar command
java -Djava.library.path=/path/to/dir
That still did not work. Is it the way that I am importing the system library? The way I'm importing it in the code is by:
static{
System.loadLibrary("opencv_java310");
}
I think the main reason that it's not working is because of the way I installed opencv. Any ideas?
Thanks!
You need to add "libopencv_java320.so" to your java project libs. It is around 1mb additional library.
You can generate this .so file from sources as per documentation: https://opencv-java-tutorials.readthedocs.io/en/latest/01-installing-opencv-for-java.html#install-opencv-3-x-under-linux
another way is to build sources manually using terminal cmake (it will download around 4gb of opencv sources), should be easy: download the source from opencv: http://opencv.org/releases.html Unzip it and inside unpacked directory create a /build directory like this ../opencv-3.2.0/build/. Make sure you have cmake installed (Debian/Ubuntu apt get install cmake). Open terminal in previously created /build folder and type: cmake -DBUILD_SHARED_LIBS=OFF .. after operation finishes type make -j8 and after that "libopencv_java_320" should be generated for 3.2.0 version - copy this .so into your java project. Last type make install from the same build directory to install 3.2.0 libs on the system (you might want to previously remove older version if necessary). More info here: https://elbauldelprogramador.com/en/compile-opencv-3.2-with-java-intellij-idea/
same as above approach but automated will be by using this script: https://github.com/milq/milq/blob/master/scripts/bash/install-opencv.sh Script does also install opencv on the linux system. Took it from this source: http://milq.github.io/install-opencv-ubuntu-debian/ It does much more then 2nd approach, should be easiest to make.
After installing opencv libs in system and copying libopencv_java320.so into your java project you can remove sources (it is almost 4gb after all).
Then you can use below code in your main method to load windows .dll (if you previously added it too) and linux .so:
String libName = "";
if (SystemUtils.IS_OS_WINDOWS) {
libName = "opencv_java320.dll";
} else if (SystemUtils.IS_OS_LINUX) {
libName = "libopencv_java320.so";
}
System.load(new File("./libs/".concat(libName)).getAbsolutePath());
if you builded OpenCV on OS;
1) set opencv and java variable
JAVA_HOME = the directory containing your JDK
ANT_HOME = the directory in which Apache Ant is installed
OPENCV_HOME = the directory in which all of OpenCV is installed
OPENCV_LIB = the directory containing all native JNI libraries
OPENCV_JAR = the path to the JAR file containing the java interface
to OpenCV (typically named something like "opencv-320.jar" )
OPENCV_HOME will be at /home/opencv-3.2.0
OPENCV_JAR will be at ${OPENCV_HOME}/build/bin/opencv-320.jar
OPENCV_LIB will be at ${OPENCV_HOME}/build/lib
2) Load Native Library
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
3) Run your application
java -Djava.library.path=${OPENCV_LIB} -jar myapp.jar
https://github.com/WPIRoboticsProjects/GRIP-code-generation/tree/master/java
Related
I've got a java script that uses OpenCV 4.6.0 to modify some pics. I use Eclipse to edit the java project. I downloaded the OpenCV library (a opencv_460.jar file) which is used inside Eclipse. When I run the code, it works just fine. So I export the java project as a runnable jar.
The thing is that I want to use the jar on a different machine (ubuntu 18.04). When I run java -jar TheExportedJar.jar, I get the following error:
Exception in thread "main" java.lang.UnsatisfiedLinkError: no opencv_java460 in java.library.path: /usr/java/packages/lib:/usr/lib/x86_64-linux-gnu/jni:/lib/x86_64-linux-gnu:/usr/lib/x86_64-linux-gnu:/usr/lib/jni:/lib:/usr/lib
I installed OpenCV 4.6.0 on the machine using CMake
wget -O opencv.zip https://github.com/opencv/opencv/archive/4.6.0.zip
unzip opencv.zip
mkdir opencv-4.6.0/build
cd opencv-4.6.0/build
cmake -D CMAKE_BUILD_TYPE=Release -D CMAKE_INSTALL_PREFIX=/usr/local -D BUILD_PKGCONFIG=ON ..
make -j$(nproc)
sudo make install
The version is ok, everything looks fine, except it doesn't actually get installed. Things that should exist, like alternative path /usr/local/lib/pkgconfig/opencv4.pc, don't actually exist
How does java work? Why can Eclipse use a jar as a library, but I can't once the project is packed? Is there a way to skip the installation process (as every type of install I've tried was just a waste of time) and import a jar from a specified path as a library inside the java code?
What other solutions could there be?
I have some c++ code which i use as shared library in a java application.My c++ code uses some libraries like ffmpeg and boost. and ffmpeg libraries in turn depend on libx264. my first question is - can i build my c++ into a "fat" shared library which contains all the symbols from all libraries used so that on a new machine if i just copy the fat .so file everything works.
If thats not possible then can you help me fix my current build process. This is what i am doing currently -
1)on a local VM(ubuntu 64) i compile ffmpeg code using -fPIC flag and install h264 and boost using apt-get commands.
2) on the same VM i compile my code using make file which looks like this-
INCLUDES = -I/opt/ffmpeg/include -I/usr/lib/jvm/java-7-openjdk- amd64/include -I/usr/lib/jvm/java-7-openjdk-amd64/include/linux
LDFLAGS = -L/home/ubuntu/ffmpeg_shared
LIBRARIES = -lavformat -lavcodec -lswscale -lavutil -lpthread -lx264 -lboost_system -lboost_thread -lboost_chrono
CC = g++ -std=c++11 -fPIC
all:clean final
final:Api.o ImageSequence.o OverlayAnimation.o Utils.o ImageFrame.o
$(CC) -o final.so Api.o ImageSequence.o OverlayAnimation.o Utils.o ImageFrame.o $(LDFLAGS) $(LIBRARIES) -shared
3) on a new machine where java app will run. i install h264 and boost using apt-get commands and copy ffmpeg's compiled library files to /usr/local/lib.
4) copy the final.so file to this new machine. but when the java code tries to use the final.so file i see it tries to use wierdly named files. for example - it tries to find libavcodec.so.57 , libavformat.so.57 etc. to fix this i just created a copy of these files ie libavcodec.so copied to libavcodec.so.57.
5)But these ffmpeg libraries in turn uses a differently named lib264.so file. on my new machine the apt-get command for x264 installed a file named libx264.so.148 but one of ffmpeg libraries is searching for file libx264.so.142 even if i rename this libx264.so file i get new errors where ffmpeg libraries tries to call libx264's methods which has these numbers attached.
6) at this time the only working option for me is to bring the c++ code on every new machine and build final.so file locally. this is something i want to avoid since i want to distribute the .so file along with jar file to my clients which they can easily use without having to build and install stuff.
I may have a solution for a 'fat' library, but I'm not 100% sure if it will work.
In general, it is possible to link together static libraries into a shared library by specifying these linker flags.
g++ -Wl,--whole-archive some_static_lib.a -Wl,--no-whole-archive
Therefore you would have to compile all your libraries into static libraries. If you think it's worth the effort to do this, you can give it a try.
To the second part:
It seems that your other machine is using different versions of the libraries. In example libx264.so.148 might be reffering to version 1.4.8 or something like that.
Therefore your libx264.so should be a symbolic link to libx264.so.148. You can verify that with
ln -l
to visualize, where your symbolic link is reffering to.
I recommend to manually compile all needed libraries on both machines. Then these problems should be solved.
I have been trying to find a way to integrate java code, generated by google-protobuf's protoc compiler, into an Android Studio project.
protoc --java_out=. Navigation.proto
where Navigation.proto contains:
syntax = "proto3";
option java_generic_services = true;
message Navigation {
string name = 1;
string url = 2;
}
service NavRPC {
rpc putNavigation(Navigation) returns (Navigation);
};
will generate a java class (Navigation.java), but that class references packages that are not present in the list of libraries (application or external) within Android Studio.
I tried installing the libraries from maven central through the dependencies tab of Project Structure, in Android Studio - but I keep getting error messages that include:
Error:(116, 79) error: incompatible types: IOException cannot be converted to String
Error:(261, 36) error: cannot find symbol method parseWithIOException(Parser<NavDrawerElement>,InputStream)
Error:(266, 36) error: cannot find symbol method parseWithIOException(Parser<NavDrawerElement>,InputStream,ExtensionRegistryLite)
Error:(269, 36) error: cannot find symbol method parseDelimitedWithIOException(Parser<NavDrawerElement>,InputStream)
Error:(274, 36) error: cannot find symbol method parseDelimitedWithIOException(Parser<NavDrawerElement>,InputStream,ExtensionRegistryLite)
Error:(278, 36) error: cannot find symbol method parseWithIOException(Parser<NavDrawerElement>,CodedInputStream)
Being somewhat new to Java, Android Studio, and Maven -- I am not sure why the errors are happening. The libraries show up in the external-libraries list but I keep getting unresolved dependencies and errors that would seem to indicate otherwise.
One solution I found that actually works for me is to build the google-protobuf jar files and then add to my project libraries.
To build these jar files in MacOS, there were several technologies/packages that had to be installed, configured, and set up correctly.
JDK 1.8
In MacOSX there is a utility (/usr/libexec/java_home) that can be
used to generate the correct JAVA_HOME environment variable.
I modified my .bashrc file to include:
export JAVA_HOME=`/usr/libexec/java_home -v 1.8`
If the version of MacOSX installed on your system is based on 10.6,
then the default jdk is version 1.6. New versions of java and jdk
can be installed from the system preferences/java/java applet, but
once installed, it is still necessary to set JAVA_HOME to point
to the version you want to use.
This is because multiple versions of java can exist on a mac, and
the update utility doesn't try to guess whether or not you want the
latest versions.
Maven 3.3.8
I use MacPorts for the installation of maven3. In the process of
installing maven3, I had to update ports and all of the related
packages in order to get rid of warnings [regarding out-of-date
packages].
I tried to do the updates installations with 'sudo ports' but kept
running in to problems. So I ended up using 'sudo bash'.
The commands executed:
sudo bash
ports selfupdate
ports install maven3
ports update
google-protobuf
I downloaded protobuf-master from google and built protoc.
I couldn't figure out why the jar files that I expected to be built
weren't, which is what prompted the installation and updates (above)
Once I had the correct jdk and maven was installed, I was able to
change into the java directory and install maven3
The commands executed:
mvn3 install
mvn3 package
I don't know if/what the differences between install and package -
but it didn't seem to hurt anything by running both.
Compiling the .proto files
I used a simple .proto file with several message types and the
definition of an RPC service:
syntax = "proto3";
option java_generic_services = true;
message Navigation {
string name = 1;
string url = 2;
};
service NavRPC {
rpc putMessage(Navigation) returns (Navigation);
}
To compile
protoc --java_out=$PROJECT_DIR/path/to/package/Navigation.java \
Navigation.proto
Android Studio
In order to get the protocol-buffer generated class to compile:
I copied these files into my lib directory:
protobuf-master/java/core/target/protobuf-java-3.0.0-beta-2.jar
protobuf-master/java/util/target/protobuf-java-util-3.0.0-beta-2.jar
With those files copied, I had to put the name of the package that the source file was being added to.
There are still some questions i have (like how to make Android
Studio automaticall compile a .proto file), but everything works!
I am using tess4J ocr library in eclipse and is working fine in my windows. But when i want to run that java program in linux it is giving an error "Unable to load library 'tesseract': libtesseract.so: cannot open shared object file: No such file or directory".
I dont have any permissions on linux to install the tesseract or any other software . Just i can use the jar files and run the java program by calling the shell script.Please help me on this . As I am thinking my problem will be solved by getting libtesseract.so file or help me how to get libtesseract.so in windows so that i will use that in linux . Please help and thank in advance
It is enough to install Tesseract for Linux using command:
sudo apt-get install tesseract-ocr
now you can check tesseract version, using command:
tesseract -v
Please note, that for Tesseract 3.03 you can use Tess4j version 2.0.
Another version may give you errors because of incompatibility.
You can get more info about different version compatibility in Change Log, or here.
In My case (centos) I copied all the files (having lept or teesseract keyword in file name) from folder
/usr/local/lib
to folder
/usr/lib64
and it solved my problem
On Linux, Tess4J calls on Tesseract native library libtesseract.so to work. If you can't build or install Tesseract on Linux, you're in tough luck. Maybe if you can cross-compile to a .so on Windows using Cygwin or Mingw.
You have to set -Djava.library.path so the file can be found or tweak your standard library path to include the location of the .so in .bashrc by extending system's LD_LIBRARY_PATH
You need to install without root and specify the path of your libtesseract.so
Install elsewhere / without root
Tesseract can be configured to install anywhere, which makes it possible to install it without root access.
To install it in $HOME/local:
./autogen.sh
./configure --prefix=$HOME/local/
make install
To install it in $HOME/local using Leptonica libraries also installed in $HOME/local:
./autogen.sh
LIBLEPT_HEADERSDIR=$HOME/local/include
./configure \ --prefix=$HOME/local/ --with-extra-libraries=$HOME/local/lib
make install
I also had same problem. Tesseract libraries was aslo present under /usr/local/lib directory.Still I was getting this error. Actually this is linking problem. so you have to provide the /usr/local/lib path to the resolver path in the /etc/ld.so.conf.d/libc.conf file. make entry of path in this file or you can create any new conf file in the same dir.
I want to import and compile FBReaderJ on eclipse. I have downloaded the latest source code from their website. Is it necessary to install NDK and cygwin for compiling FBRreaderJ.
If you can suggest me any tutorial OR helpful link.
FYI:
OS – Windows vista
Eclipse – [Helios 3.6]
Android OS – 1.6
In the HowToBuild text file in the root dir, it gives instructions.
It mentions the requirements:
Android SDK >= 1.6
Android NDK >= r4b
Apache Ant >= 1.7.0
python
And since the NDK requires cygwin 1.7 on Windows, it looks like you'll have some downloading to do.
So yes, you need the NDK, Cygwin, and Python
The text file also gives build instructions:
EDIT new instructions:
To build:
Create 'local.properties' file containing sdk.dir && ndk.dir definitions: sdk.dir= ndk.dir= E.g., on my computer 'local.properties'
consists of 2 lines: sdk.dir=/Users/geometer/android-sdk-mac_86
ndk.dir=/Users/geometer/android-ndk-r4b
If you use Linux or MacOS, just run 'ant package' and go to step 3. For debugging purposes, you might want to run 'ant dbg' for building
the package in debug mode, signing with your debug key (in this case,
you can skip step 3).
If you are Windows user 2a. Run ndk-build (a program from Android
NDK directory) in your project catalog;
This program only runs from Cygwin >= 1.7, please read NDK docs for details.
Read and try config cygwin using 'cygwin_installation_and_configuration.pdf' 2b. Run 'ant release'.
Sign your package manually.
To make FBReaderJ working you can refer to the following link:
https://github.com/geometer/FBReaderJ/raw/maste/docs/cygwin_installation_and_configuration.pdf
it tells you all about how to download and intstall cygwin.
There is highest possibility of getting error: "NDK command not found". In that case refer to this link:: http://mindtherobot.com/blog/452/android-beginners-ndk-setup-step-by-step/