我正在制作一个使用计算机视觉(OpenCV)的跨平台Java应用程序。我需要从网络摄像头接收视频。当前使用标准OpenCV方法:
VideoCapture videoCapture = new VideoCapture();
videoCapture.open(cameraIndex);
...
videoCapture.read(frame);
当然,本机OpenCV库是在访问相机之前加载的:
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
库是用这些参数构建的:
-D WITH_IPP=OFF
-D BUILD_opencv_java=ON
-D CMAKE_BUILD_TYPE=RELEASE
-D CMAKE_INSTALL_PREFIX=../../opencv-4.5.3/build/install
-D OPENCV_EXTRA_MODULES_PATH=../../opencv_contrib-4.5.3/modules
-D BUILD_opencv_python2=OFF
-D BUILD_opencv_python3=OFF
-D INSTALL_PYTHON_EXAMPLES=OFF
-D INSTALL_C_EXAMPLES=OFF
-D OPENCV_ENABLE_NONFREE=ON
-D BUILD_EXAMPLES=OFF
-D OPENCV_JAVA_SOURCE_VERSION=1.8
-D OPENCV_JAVA_TARGET_VERSION=1.8
-D BUILD_SHARED_LIBS=OFF
-D BUILD_FAT_JAVA_LIB=ON
-D WITH_MATLAB=OFF
-D BUILD_ZLIB=OFF
-D BUILD_TIFF=OFF
-D BUILD_JASPER=OFF
-D BUILD_JPEG=OFF
-D BUILD_PNG=OFF
-D WITH_JPEG=OFF
-D WITH_PNG=OFF
-D WITH_OPENEXR=OFF
-D BUILD_PERF_TESTS=OFF
-D BUILD_TESTS=OFF
相机在Windows 10 (x64)和Kali Linux (amd64)上工作。但是不是在macOS。
videoCapture.open(cameraIndex)
功能完成后,控制台中出现错误信息,并关闭应用程序:
OpenCV: not authorized to capture video (status 0), requesting...
OpenCV: can not spin main run loop from other thread, set OPENCV_AVFOUNDATION_SKIP_AUTH=1 to disable authorization request and perform it in your application.
OpenCV: camera failed to properly initialize!
我尝试了很多事情,如export OPENCV_AVFOUNDATION_SKIP_AUTH=0
或Thread.sleep(1000)
后videoCapture.open()
或在另一个线程打开相机。我还添加了Info.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSCameraUsageDescription</key>
<string>Application needs permission to access the camera to capture images</string>
</dict>
</plist>
到我的。jar的SRC文件夹。
我读过这些:
- https://github.com/opencv/opencv/issues/16255
- https://developer.apple.com/forums/thread/109057
- OpenCV命令行应用程序停下来# 39;t访问摄像头在macOS莫哈韦
- https://answers.opencv.org/question/225281/videocapture-0-does-not-work-in-mac-catalina-the-program-crashed/
和许多其他资源,但仍然没有答案。
我甚至尝试使用OpenPVP-capture-java (https://github.com/openpnp/openpnp-capture-java)库,但没有帮助。
objc[2116]: Class PlatformAVCaptureDelegate is implemented in both /private/var/folders/zz/zyxvpxvq6csfxvn_n0000000000000/T/jna-3506402/jna6724263821710587077.tmp (0x14fac7cd8) and /private/var/folders/zz/zyxvpxvq6csfxvn_n0000000000000/T/jna-3506402/jna1573965830287255196.tmp (0x14faf9cd8). One of the two will be used. Which one is undefined.
2021-10-09 20:44:39.093 java[2116:99975] Requesting permission, bundle path for Info.plist: /Library/Java/JavaVirtualMachines/adoptopenjdk-8.jdk/Contents/Home/bin
zsh: abort java -Djava.library.path=. -jar CamTest.jar
在系统设置中,终端可以访问摄像机. 此外,Ubuntu上的相机也有一个问题(在videoCapture.open()
之后,程序会冻结)。但这是另一个问题的话题。
是否有一种方法可以访问macOS上的OpenCV (Java)相机?也许使用某种第三方跨平台库…
我再一次回答我自己的问题…
谢谢@ChristophRackwitz !在你问相机是否可以用python工作之后,我检查了一下(我不知道为什么我之前没有这样做)。因此,python中的相机(使用opencv-contrib-python)工作没有问题,所以我意识到问题出在Java (JDK)本身。
我已经用下面的命令安装了JDK 8:
brew tap adoptopenjdk/openjdk
brew install --cask adoptopenjdk8
所以,我的JAVA_HOME是/Library/Java/JavaVirtualMachines/adoptopenjdk-8.jdk/Contents/Home
我不知道它是否坏了Java或其他东西,但当我安装Java11与:brew install java11
和设置JAVA_HOME
为/usr/local/Cellar/openjdk@11/11.0.12/
它终于工作了!
我花了这么多时间在这个问题上,解决方案只是在错误的Java版本…这很奇怪,因为我的应用程序(和.jar文件)是用JDK 8编译的。在其他操作系统(Windows、Linux)上,Java 8可以正常工作。无论如何,现在当我从终端启动应用程序时,它请求访问相机,一切都很好!