使用JavaFX进行Web Cam访问

时间:2015-09-15 09:41:41

标签: java opencv javafx webcam

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

2 个答案:

答案 0 :(得分:2)

你很幸运。上周末我和OpenCV一起玩弄了,遇到了和你一样的问题。这是一个关于如何做到这一点的例子。该示例打开相机,使用AnimationTimer(有点矫枉过正,但是原型的快速解决方案)定期抓取mat图像,将mat图像转换为JavaFX图像,执行面部检测并在画布上绘制它。

这就是你需要的:

下载OpenCV,e。 G。在我的情况下,Windows版本。将opencv-3.0.0.exe重命名为opencv-3.0.0.exe.zip并将其打开。解压缩build / java。

的内容

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

lib/opencv-300.jar
lib/x64/opencv_java300.dll

将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);
    }
}

当你拥有JavaFX图像时,你可以做任何你想做的事情(例如保存)。

答案 1 :(得分:0)

对于sarxos,伪代码,我无法发布全班:

'driver' => env('SESSION_DRIVER', 'file')
相关问题