使用 JavaFX 访问网络摄像头

j d*_*vis 5 java webcam opencv javafx

我一直在寻找从 java 或 javaFX 应用程序访问内置网络摄像头的解决方案。我已经看到很多其他帖子指向 OpenCV 和 JavaCV、Sarxos 的库和其他一些。我遇到了一些困难,例如较新版本的 OpenCV 无法使用发布在各种网站上的旧代码,并且使用 OpenCV 3.0 的较新代码很难找到或无法满足我的需求,这只是一个客户应用程序,它节省了从网络摄像头拍摄的图像到变量(或文件)。希望有人能指出我正确的方向。提前致谢

Rol*_*and 5

你很幸运。上周末我玩了一下 OpenCV,遇到了和你一样的问题。下面是一个有关如何执行此操作的示例。该示例打开相机,使用 AnimationTimer(有点过大,但对于原型设计来说是一个快速解决方案)定期抓取垫子图像,将垫子图像转换为 JavaFX 图像,执行面部检测并将其绘制在画布上。

这是您需要的:

下载OpenCV,例如在我的例子中是 Windows 版本。将 opencv-3.0.0.exe 重命名为 opencv-3.0.0.exe.zip 并打开它。提取 build/java 的内容。

创建一个新的 JavaFX 项目。将jar和dll放入lib文件夹中,例如:

lib/opencv-300.jar
lib/x64/opencv_java300.dll
Run Code Online (Sandbox Code Playgroud)

将 jar 添加到您的构建路径。

在 src 文件夹中创建一个路径 opencv/data/lbpcascades 并将文件 lbpcascade_frontalface.xml 放入其中(在 etc/lbpcascades 中找到)。这仅适用于人脸检测,如果不需要,可以取消注释代码。

创建应用程序类,代码:

import java.io.ByteArrayInputStream;
import java.lang.reflect.Field;
import java.net.URISyntaxException;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;

import javafx.animation.AnimationTimer;
import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.geometry.Rectangle2D;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.image.Image;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
import javafx.stage.WindowEvent;

import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.core.MatOfByte;
import org.opencv.core.MatOfRect;
import org.opencv.core.Rect;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.objdetect.CascadeClassifier;
import org.opencv.videoio.VideoCapture;

public class Camera extends Application {

    private static final int SCENE_W = 640;
    private static final int SCENE_H = 480;

    CascadeClassifier faceDetector;
    VideoCapture videoCapture;

    Canvas canvas;
    GraphicsContext g2d;
    Stage stage;
    AnimationTimer timer;

    @Override
    public void start(Stage stage) {

        this.stage = stage;

        initOpenCv();

        canvas = new Canvas(SCENE_W, SCENE_H);
        g2d = canvas.getGraphicsContext2D();
        g2d.setStroke(Color.GREEN);

        Group group = new Group(canvas);

        Scene scene = new Scene(group, SCENE_W, SCENE_H);

        stage.setScene(scene);
        stage.setResizable(false);
        stage.show();

        timer = new AnimationTimer() {

            Mat mat = new Mat();

            @Override
            public void handle(long now) {

                videoCapture.read(mat);

                List<Rectangle2D> rectList = detectFaces(mat);

                Image image = mat2Image(mat);

                g2d.drawImage(image, 0, 0);

                for (Rectangle2D rect : rectList) {
                    g2d.strokeRect(rect.getMinX(), rect.getMinY(), rect.getWidth(), rect.getHeight());
                }

            }
        };
        timer.start();

    }

    public List<Rectangle2D> detectFaces(Mat mat) {

        MatOfRect faceDetections = new MatOfRect();
        faceDetector.detectMultiScale( mat, faceDetections);

        System.out.println(String.format("Detected %s faces", faceDetections.toArray().length));

        List<Rectangle2D> rectList = new ArrayList<>();
        for (Rect rect : faceDetections.toArray()) {

            int x = rect.x;
            int y = rect.y;
            int w = rect.width;
            int h = rect.height;

            rectList.add(new Rectangle2D(x, y, w, h));
        }

        return rectList;
    }

    private void initOpenCv() {

        setLibraryPath();

        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);

        videoCapture = new VideoCapture();
        videoCapture.open(0);

        System.out.println("Camera open: " + videoCapture.isOpened());

        stage.setOnCloseRequest(new EventHandler<WindowEvent>() {
            public void handle(WindowEvent we) {

                timer.stop();
                videoCapture.release();

                System.out.println("Camera released");

            }
        });

        faceDetector = new CascadeClassifier(getOpenCvResource(getClass(), "/opencv/data/lbpcascades/lbpcascade_frontalface.xml"));

    }

    public static Image mat2Image(Mat mat) {
        MatOfByte buffer = new MatOfByte();
        Imgcodecs.imencode(".png", mat, buffer);
        return new Image(new ByteArrayInputStream(buffer.toArray()));
    }

    private static void setLibraryPath() {

        try {

            System.setProperty("java.library.path", "lib/x64");

            Field fieldSysPath = ClassLoader.class.getDeclaredField("sys_paths");
            fieldSysPath.setAccessible(true);
            fieldSysPath.set(null, null);

        } catch (Exception ex) {
            ex.printStackTrace();
            throw new RuntimeException(ex);
        }

    }

    public static String getOpenCvResource(Class<?> clazz, String path) {
        try {
            return Paths.get( clazz.getResource(path).toURI()).toString();
        } catch (URISyntaxException e) {
            throw new RuntimeException(e);
        }
    }

    public static void main(String[] args) {
        launch(args);
    }
}
Run Code Online (Sandbox Code Playgroud)

当然,一旦获得 JavaFX 映像,您就可以对其进行任何您想要的操作(例如保存)。


Krz*_*cki 0

对于 sarxos,伪代码,我无法发布整个类:

import com.sleepingdumpling.jvideoinput.Device;
import com.sleepingdumpling.jvideoinput.VideoFrame;
import com.sleepingdumpling.jvideoinput.VideoInput;

Device choosenDevice;
for (Device device : VideoInput.getVideoDevices()) {
// select your choosenDevice webcam  here
if (isMyWebcam(device)) {
choosenDevice = device;
break;

}
}
// eg. VideoInput(640,480,25,choosenDevice );
VideoInput videoInput = new VideoInput(frameWidth, frameHeigth,
                                frameRate, choosenDevice );
VideoFrame vf = null;
while (grabFrames) {
            vf = videoInput.getNextFrame(vf);
            if (vf != null) {
                frameReceived(vf.getRawData());
                // or vf.getBufferedImage();
            }

}
videoInput.stopSession();
Run Code Online (Sandbox Code Playgroud)