java - 如何在 Raspberry PI(armv6 和 armv7 Raspian)上使用 Java 中的 OpenCV 4?

标签 java opencv raspberry-pi arm

这个问题与 this one 非常相似,但它在 Linux ARM(Raspberry Pi)上。
我已经从源代码编译了 OpenCV 4.4.0 以及 Java 绑定(bind),并尝试了类似这样的 hack(在 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");
        }
        
}
但是,取决于 Raspberry Pi,我在同一行遇到不同的崩溃,加载 libopencv_java440(在加载其他依赖库之后):
在运行 Raspian 拉伸(stretch)的 Raspberry Pi 3B 上,我收到如下错误:
#
# 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
在同样运行 Raspian Stretch I 的 Raspberry Pi ZeroW 上,有一个强大的日志: example
关于让 OpenCV Java 绑定(bind)在 arvm6/armv7 CPU 上工作的任何提示?
更新
感谢@Catree 的评论,我也进行了测试。
正如您在 opencv_cpp_tests.txt 中看到的大多数测试运行,不包括需要加载 Assets 的那些(必须在运行 Assets 部分时搞砸了)。
我也尝试过运行 Java 测试,但是我遗漏了一些明显的东西,因为我传递给包含 opencv 共享库的 lib 文件夹的 java.library.path 参数似乎不起作用。可以在opencv_java_tests.txt查看输出
我也尝试过指定正确的 java 类路径和库路径的老式 2.4 Introduction to Java Development OpenCV Tutorial,但遇到了段错误:/
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
非常感谢任何进步的提示/提示
更新2
按照@moyeen52 的建议,我编译了 OpenCV 静态库( -DBUILD_SHARED_LIBS=OFF )并注意到 libopencv_java.so 从 2.1MB 变为 31MB。
不幸的是,我仍然遇到相同的段错误:(
我还查看了另一篇文章,不幸的是它不适用,因为 OpenCV 已经编译了 libopencv_java440.so(无需重命名)。
更新3
为了方便使用 Raspberry PI 3 B+ 的任何人进行测试,我上传了以下内容:
  • HelloCV.tar.gz:包含Hello.java(它只是试图加载库,创建一个Mat并打印它),opencv-440.jar,libopencv_java440.so(静态构建)和compile.sh和run.sh应该调用javac/java 具有正确的参数,本地引用 java 和 c++ 库。
  • opencv440_static_rpi3b.tar.gz:静态库构建
  • opencv440_shared_rpi3b.tar.gz:共享库构建

  • 此外,我将尝试在没有 libatomic 或 NEONVPF3 CPU 优化的情况下重新编译,并将发布更新
    非常感谢您的建议/提示!谢谢

    最佳答案

    感谢大家的评论:他们在缩小问题范围和寻找解决方案方面发挥了重要作用。
    c++ 错误可能是由于 C++ 编译器(以及对 c++ 11 或更高版本的支持)之间的差异造成的。虽然我找到了一些关于更新的资源 g++ (从 6.3.0 到 8.3.0)我不想冒险遇到其他问题。
    我为每个系统(PiZeroW (armv6) 和 Pi3B+ (armv7))使用了全新安装的 Raspian OS (Buster),完全没有问题。此外,我使用 OpenJDK 8 而不是 11 来满足我的项目需求。
    我在这里存储了预构建二进制文件(安装文件夹的全部内容):

  • opencv_440_pi0w.tar.gz -> 在树莓派零 W
  • 上编译
  • opencv_440_pi3b.tar.gz -> 在树莓派 3 B+ 上编译
  • opencv_440_pi4.tar.gz -> 在树莓派 4 上编译

  • 此外,带有 Hello world 测试和编译/运行 bash 脚本的 java 包装器有最小的 zip:
  • HelloCVPI0W.tar.gz对于 armv6:在 Raspberry Pi Zero 上测试
  • HelloCVPI3B+.tar.gz对于 armv7:在 Raspberry Pi 3 B+ 上测试
  • HelloCVPI4.tar.gz对于 armv7:在 Raspberry Pi 4 上测试

  • ( 注意 Java 包装器是使用 OpenJDK 8 编译的)

    关于java - 如何在 Raspberry PI(armv6 和 armv7 Raspian)上使用 Java 中的 OpenCV 4?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62505966/

    相关文章:

    android - 使用 http 服务器显示来自连接到 Android 上的树莓派的网络摄像头的图像流

    发送图像时出现 Python 套接字错误。无法解码字节/意外的 EOF

    Java ArrayList 转换为 C++

    java - Hadoop mapReduce 如何在 HDFS 中只存储值

    java - Play 框架应用的监控工具

    c++ - 调用 OpenCV 方法 cvLoadImage() 时 CoInitializeEx 失败

    c++ - 从另一台计算机运行 opencv 可执行文件

    python-3.x - OpenCV 库(Python 中)的 VideoCapture 方法是否处理每一帧,或者在进行大量处理时是否也会跳过帧?

    java - activemq - 等待所有消息被消费

    raspberry-pi - 使用 VPN 在网络命名空间中运行传输守护进程