This question is very similar to this one however it's on Linux ARM ( Raspberry Pi).
I've compiled OpenCV 4.4.0 from source along with the Java bindings and tried something like this hack (that worked on Windows):
import org.opencv.core.*;
public class CVTest {
public static void main(String[] args) {
System.out.println("setup");
// loading the typical way fails :(
// System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
System.load("/home/pi/eclipse/CVTest/lib/libopencv_core.so");
////System.load("/home/pi/opencv/build/lib/libopencv_core.so");
System.load("/home/pi/eclipse/CVTest/lib/libopencv_imgproc.so");
System.load("/home/pi/eclipse/CVTest/lib/libopencv_imgcodecs.so");
System.load("/home/pi/eclipse/CVTest/lib/libopencv_img_hash.so");
////System.load("/home/pi/eclipse/CVTest/lib/opencv_core.so");//videoio_ffmpeg440_64.dll
//System.load("/home/pi/eclipse/CVTest/lib/libopencv_videoio.so");
System.load("/home/pi/eclipse/CVTest/lib/libopencv_photo.so");
System.load("/home/pi/eclipse/CVTest/lib/libopencv_xphoto.so");
System.load("/home/pi/eclipse/CVTest/lib/libopencv_flann.so");
System.load("/home/pi/eclipse/CVTest/lib/libopencv_features2d.so");
System.load("/home/pi/eclipse/CVTest/lib/libopencv_calib3d.so");
System.load("/home/pi/eclipse/CVTest/lib/libopencv_phase_unwrapping.so");
System.load("/home/pi/eclipse/CVTest/lib/libopencv_structured_light.so");
System.load("/home/pi/eclipse/CVTest/lib/libopencv_xfeatures2d.so");
System.load("/home/pi/eclipse/CVTest/lib/libopencv_video.so");
System.load("/home/pi/eclipse/CVTest/lib/libopencv_ximgproc.so");
System.load("/home/pi/eclipse/CVTest/lib/libopencv_aruco.so");
System.load("/home/pi/eclipse/CVTest/lib/libopencv_bgsegm.so");
System.load("/home/pi/eclipse/CVTest/lib/libopencv_bioinspired.so");
System.load("/home/pi/eclipse/CVTest/lib/libopencv_objdetect.so");
System.load("/home/pi/eclipse/CVTest/lib/libopencv_face.so");
System.load("/home/pi/eclipse/CVTest/lib/libopencv_dnn.so");
System.load("/home/pi/eclipse/CVTest/lib/libopencv_tracking.so");
System.load("/home/pi/eclipse/CVTest/lib/libopencv_plot.so");
System.load("/home/pi/eclipse/CVTest/lib/libopencv_ml.so");
System.load("/home/pi/eclipse/CVTest/lib/libopencv_ml.so");
System.load("/home/pi/eclipse/CVTest/lib/libopencv_text.so");
// crashes here!
System.load("/home/pi/eclipse/CVTest/lib/libopencv_java440.so");
Mat m = Mat.eye(new Size(3,3), CvType.CV_8UC1);
System.out.println("done");
}
}
However, depending on the Raspberry Pi, I get different crashes at the same line, loading libopencv_java440
(after the other dependant libraries have loaded):
On a Raspberry Pi 3B running Raspian stretch I get errors like this one:
#
# A fatal error has been detected by the Java Runtime Environment:
#
# SIGBUS (0x7) at pc=0x6360f644, pid=9730, tid=0x64eba470
#
# JRE version: Java(TM) SE Runtime Environment (8.0_202-b08) (build 1.8.0_202-b08)
# Java VM: Java HotSpot(TM) Client VM (25.202-b08 mixed mode linux-arm )
# Problematic frame:
# C [libopencv_core.so+0x258644] cv::Ptr<std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >::~Ptr()+0x38
#
# Failed to write core dump. Core dumps have been disabled. To enable core dumping, try "ulimit -c unlimited" before starting Java again
#
# If you would like to submit a bug report, please visit:
# http://bugreport.java.com/bugreport/crash.jsp
#
--------------- T H R E A D ---------------
Current thread (0x76162400): VMThread [stack: 0x64e3b000,0x64ebb000] [id=9733]
siginfo: si_signo: 7 (SIGBUS), si_code: 1 (BUS_ADRALN), si_addr: 0x7c1f010e
Registers:
r0 = 0x636e6270
r1 = 0x00000000
r2 = 0x000011f8
r3 = 0x7c1f010e
r4 = 0x7c1f00f2
r5 = 0x636e6270
r6 = 0x76ee84ac
r7 = 0x00000001
r8 = 0x6470c600
r9 = 0x000003ec
r10 = 0x000003ec
fp = 0x64eb9c0c
r12 = 0x76fa4ce4
sp = 0x64eb9be8
lr = 0x76ddadd4
pc = 0x6360f644
cpsr = 0x20000010
Top of Stack: (sp=0x64eb9be8)
0x64eb9be8: 76ee8000 00000000 76ee84ac 76ddadd4
0x64eb9bf8: 76129d7c 76ddae34 00000000 76635d7c
0x64eb9c08: 64eb9c2c 768ac3dc 76162270 63736954
0x64eb9c18: 76940000 76129988 76129990 76129d7c
0x64eb9c28: 64eb9ca4 768aaa54 7696a050 76942d14
0x64eb9c38: 64eb9ca4 767f8084 00000000 00000000
0x64eb9c48: 8c365cd8 00000000 76909901 76966044
0x64eb9c58: 76163208 00000000 00000000 7696a050
Instructions: (pc=0x6360f644)
0x6360f624: 0a00000d e59f20c4 e7933002 e3530000
0x6360f634: 0a00000b e284301c ee070fba e1932f9f
0x6360f644: e2421001 e1830f91 e3500000 1afffffa
0x6360f654: e3520001 ee070fba 0a00000f e1a00005
Register to memory mapping:
r0 = 0x636e6270
On a Raspberry Pi ZeroW also running Raspian Stretch I a beefy log: example.
Any tips on getting OpenCV Java bindings to work on arvm6/armv7 CPUs ?
Update Thanks to the comment from @Catree I've ran the tests as well. As you can see in opencv_cpp_tests.txt mosts tests run, excluding ones where asset loading is required (Must've botched running the asset part).
I did try running the Java tests as well, however I'm missing something obvious because the java.library.path
argument I pass to the lib folder containing opencv's shared libraries doesn't seem to work. You can view the output in opencv_java_tests.txt
I've also tried the old-school 2.4 Introduction to Java Development OpenCV Tutorial specifying the correct java class paths and library path, but got greeted by a segfault :/
java -Djava.library.path=/home/pi/opencv/build/lib -classpath /home/pi/opencv/build/bin/opencv-440.jar:/home/pi/opencv/build/build/jar/SimpleSample.jar SimpleSample -verbose
Segmentation fault
Any hints/tips to progress are greatly appreciated
Update 2
Following @moyeen52's advice I've compiled OpenCV static libs (-DBUILD_SHARED_LIBS=OFF
) and noticed libopencv_java.so
goes from 2.1MB to 31MB.
Unfortunately I still get the same segfault :(
I also had a look at the other post which unfortunately doesn't apply as OpenCV compiles libopencv_java440.so
already (no need to rename).
Update 3 To ease testing for anyone out there with a Raspberry PI 3 B+ I've uploaded the following:
Mat
and print it), opencv-440.jar, libopencv_java440.so (static build) and compile.sh and run.sh which should call javac
/java
with the right arguments, locally referencing the java and c++ libraries.Additionally I will try recompiling without libatomic nor NEON
and VPF3
CPU optimisations and will post updates
Your advice/tips are very much appreciated ! Thank you
By default, OpenCV uses ARMv7 instruction set as a minimal baseline — it is a modern architecture and enables the execution on a wide spectrum of hardware. Old Raspberry Pi 1 and Raspberry Pi Zero use older ARMv6 architecture and do not have much scope for acceleration. Your Raspberry may well support more than ARMv7 baseline.
The OpenCV library provides an integration with several ARM-specific acceleration libraries. OpenCV HAL (Hardware Abstraction Layer) is an interface for platform-specific and low-level architecture-specific implementations. OpenCV contains NVIDIA Carotene — it implements HAL for ARMv7 and ARMv8 architectures and uses NEON instructions.
Compiling from source (takes longer, but gives you the full OpenCV install/optimizations) The pip method to install OpenCV 4 is by far the easiest way to install OpenCV (and the method I recommend for 90% of projects). It is especially great for beginners too. If you need the full install of OpenCV, you must compile from source.
Check to see which version of OpenCV you have installed. Now, go to the Python IDE in your Raspberry Pi by clicking the logo -> Programming -> Thonny Python IDE. Write the following code to capture a live video feed.
Thank you everyone for the comments: they have been instrumental in narrowing down the issue and finding a solution.
The c++ errors might hava been due to the difference between C++ compilers (and support for c++ 11 or higher). Although I found a few resources on updating g++
(from 6.3.0 to 8.3.0) I didn't want to risk running into other issues.
I've used completely fresh installs of Raspian OS (Buster) for each system (PiZeroW (armv6) and Pi3B+ (armv7)) which worked with no issues at all. Additionally I've used OpenJDK 8 instead of 11 for my project needs.
I have stored prebuild binaries (full contents of the install folder) here:
Additionally, there are minimal zips for the java wrapper with a Hello world test and compile/run bash scripts:
(Note the Java wrapper is compiled with OpenJDK 8)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With