带有 OpenCV start/pause 网络摄像头的 JavaFX。 FXML加载器

JavaFX with OpenCV start/pause webcam. FXMLLoader

我正在尝试通过 OpenCV 库学习 JavaFX 以获得我的学位。我想制作一个检测人的程序。我们可以将其命名为人员计数器。我已经看过一些视频了,我也想这样做。

问题是我必须开始学习 JavaFX 和库 OpenCV。 所以我开始创建一个简单的项目来启动/暂停网络摄像头并拍摄快照。我在 youtube 上看到有人这样做,我开始重新制作它。

问题是我有这个错误:

Exception in Application start method
java.lang.reflect.InvocationTargetException

我的代码是:

主要

package application;

import javafx.application.Application;
import javafx.stage.Stage;
import javafx.stage.WindowEvent;
import javafx.scene.Scene;
import javafx.scene.layout.BorderPane;
import javafx.fxml.FXMLLoader;

public class Main extends Application {
    @Override
    public void start(Stage primaryStage) {
        try {
            BorderPane root = (BorderPane) FXMLLoader.load(getClass().getResource("Camera.fxml"));
            Scene scene = new Scene(root, 400, 400);
            scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
            primaryStage.setScene(scene);
            primaryStage.show();
        } catch(Exception e) {
            e.printStackTrace();
        }
    }
    
    public static void main(String[] args) {
        launch(args);
    }
}

相机控制器

package application;

import java.awt.Graphics;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;

import javax.imageio.ImageIO;

import javafx.embed.swing.SwingFXUtils;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.image.ImageView;

import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.core.MatOfByte;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.videoio.VideoCapture;

public class CameraController {
    // definitions
    @FXML
    private Button btn_start, btn_pause, btn_snapshot;
    @FXML
    private ImageView imgView;

    private DaemonThread myThread = null;
        int count = 0;
        VideoCapture webSource = null;

        Mat frame = new Mat();
        MatOfByte mem = new MatOfByte(); /// start button 

        @FXML
        protected void startClick(ActionEvent event) {
            webSource =new VideoCapture(0);
            myThread = new DaemonThread();
            Thread t = new Thread(myThread);
            t.setDaemon(true);
            myThread.runnable = true;
            t.start();
            btn_start.setDisable(true);
            btn_pause.setDisable(false); // stop button
        }

        @FXML
        protected void pauseClick(ActionEvent event) {}

        @FXML
        protected void snapshotClick(ActionEvent event) {}
   
        class DaemonThread implements Runnable {
            protected volatile boolean runnable = false;

            @Override
            public  void run() {
                synchronized (this) {
                    while (runnable) {
                        if (webSource.grab()) {
                            try {
                                webSource.retrieve(frame);
                                Imgcodecs.imencode(".bmp", frame, mem);
                                Image im = ImageIO.read(new ByteArrayInputStream(mem.toArray()));

                                BufferedImage buff = (BufferedImage) im;
                                imgView.setImage(SwingFXUtils.toFXImage(buff, null));
                
                                if (!runnable) {
                                    System.out.println("Going to wait()");
                                    this.wait();
                                }
                            } catch (Exception ex) {
                                System.out.println("Error");
                            }
                        }
                    }
                }
            }
        }
        /////////////////////////////////////////////////////////
    }
}

问题出在这一行:

BorderPane root = (BorderPane) FXMLLoader.load(getClass().getResource("Camera.fxml"));
Scene scene = new Scene(root,400,400);

完整的控制台错误:

Exception in Application start method
java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:389)
    at com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:328)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at sun.launcher.LauncherHelper$FXHelper.main(Unknown Source)
Caused by: java.lang.RuntimeException: Exception in Application start method
    at com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:917)
    at com.sun.javafx.application.LauncherImpl.lambda$launchApplication5(LauncherImpl.java:182)
    at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.UnsatisfiedLinkError: org.opencv.core.Mat.n_Mat()J
    at org.opencv.core.Mat.n_Mat(Native Method)
    at org.opencv.core.Mat.<init>(Mat.java:24)
    at application.CameraController.<init>(CameraController.java:34)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
    at java.lang.reflect.Constructor.newInstance(Unknown Source)
    at java.lang.Class.newInstance(Unknown Source)
    at sun.reflect.misc.ReflectUtil.newInstance(Unknown Source)
    at javafx.fxml.FXMLLoader$ValueElement.processAttribute(FXMLLoader.java:927)
    at javafx.fxml.FXMLLoader$InstanceDeclarationElement.processAttribute(FXMLLoader.java:971)
    at javafx.fxml.FXMLLoader$Element.processStartElement(FXMLLoader.java:220)
    at javafx.fxml.FXMLLoader$ValueElement.processStartElement(FXMLLoader.java:744)
    at javafx.fxml.FXMLLoader.processStartElement(FXMLLoader.java:2707)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2527)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2441)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3214)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3175)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3148)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3124)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3104)
    at javafx.fxml.FXMLLoader.load(FXMLLoader.java:3097)
    at application.Main.start(Main.java:15)
    at com.sun.javafx.application.LauncherImpl.lambda$launchApplication12(LauncherImpl.java:863)
    at com.sun.javafx.application.PlatformImpl.lambda$runAndWait5(PlatformImpl.java:326)
    at com.sun.javafx.application.PlatformImpl.lambda$null3(PlatformImpl.java:295)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.javafx.application.PlatformImpl.lambda$runLater4(PlatformImpl.java:294)
    at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
    at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
    at com.sun.glass.ui.win.WinApplication.lambda$null8(WinApplication.java:191)
    ... 1 more
Exception running application application.Main

提前致谢!

我通过添加 System.loadLibrary(Core.NATIVE_LIBRARY_NAME):

解决了这个问题
public static void main(String[] args) {        
    System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
    launch(args);
}

试试这个对我有用 nu.pattern.OpenCV.loadShared();