Face input and recognition system for college freshmen based on javafx and hongruan ArcFace

Posted by padams on Thu, 27 Jan 2022 01:12:04 +0100

1, Demand analysis

With the rapid development of face recognition technology, colleges and universities also began to try to collect Freshmen's face information through face recognition related technology and input it into the university face information database. In the future study and life, students who have entered face information can easily conduct personal authentication through face recognition equipment.

Face recognition is also widely used in Colleges and universities, such as dormitory access management, laboratory access management, library access management, book borrowing and so on. The author's school also gave full play to the role of face recognition in the process of information construction, and built a temperature measurement system combined with face recognition during the epidemic.

This project aims to build a simple face information input and recognition system for college freshmen through javafx, webcam and ArcFace technologies.

2, Key technology

JavaFX: JavaFX is an open source next-generation client application platform, which is suitable for desktop, mobile and embedded systems based on Java. It is the result of the joint efforts of many individuals and companies. The purpose is to provide a modern, efficient and fully functional toolkit for developing rich client applications.

webcam: java third-party library, which can call the system camera and take photos

ArcFace: offline face recognition library provided by hongruan, version 3.0.

3, Achieve goals

  • User information (face information, name, student number, professional class) can be entered through the camera, and the data can be stored using mysql.
  • User information can be recognized by face

4, Effect display

1. Face information input

If the user's face has been entered, you will be prompted:

When face information is not detected:

Entered successfully:

Database:

2. Face information recognition

Identification results:

If there is no face information, there is no response:

5, Code implementation and database design

1. Database design

2. Code implementation

Dependency:

<dependencies>
        <!-- https://mvnrepository.com/artifact/com.github.sarxos/webcam-capture -->
        <dependency>
            <groupId>com.github.sarxos</groupId>
            <artifactId>webcam-capture</artifactId>
            <version>0.3.12</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/junit/junit -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13.2</version>
            <scope>test</scope>
        </dependency>
        <!-- https://mvnrepository.com/artifact/cn.hutool/hutool-core -->
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.6.1</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 -->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.12.0</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.6</version>
        </dependency>
        <dependency>
            <groupId>commons-dbutils</groupId>
            <artifactId>commons-dbutils</artifactId>
            <version>1.7</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/com.mchange/c3p0 -->
        <dependency>
            <groupId>com.mchange</groupId>
            <artifactId>c3p0</artifactId>
            <version>0.9.5.2</version>
        </dependency>
    </dependencies>

Tools:

package zzuli.zw.camera;

import com.arcsoft.face.*;
import com.arcsoft.face.enums.DetectMode;
import com.arcsoft.face.enums.DetectOrient;
import com.arcsoft.face.toolkit.ImageFactory;
import com.arcsoft.face.toolkit.ImageInfo;
import java.io.File;
import java.util.ArrayList;
import java.util.List;

import static com.arcsoft.face.toolkit.ImageFactory.getRGBData;

/**
 * @ClassName FaceUtils
 * @Description TODO
 * @Author wu2wen
 * @Date 2021/7/9 15:00
 * @Version 1.0
 */
public class FaceUtils {
    private  FaceEngine faceEngine;
    private ImageInfo imageInfo;
    private FunctionConfiguration functionConfiguration;
    //Configure according to the actual situation
    private static final String configFile = "C:\\Users\\wu2we\\Desktop\\ArcSoft_ArcFace_Java_Windows_x64_V3.0\\libs\\WIN64";
    public FaceUtils(){
        faceEngine = new FaceEngine(configFile);
        //Engine configuration
        EngineConfiguration engineConfiguration = new EngineConfiguration();
        engineConfiguration.setDetectMode(DetectMode.ASF_DETECT_MODE_IMAGE);
        engineConfiguration.setDetectFaceOrientPriority(DetectOrient.ASF_OP_ALL_OUT);
        engineConfiguration.setDetectFaceMaxNum(10);
        engineConfiguration.setDetectFaceScaleVal(16);
        //Function configuration
        functionConfiguration = new FunctionConfiguration();
        functionConfiguration.setSupportAge(true);
        functionConfiguration.setSupportFace3dAngle(true);
        functionConfiguration.setSupportFaceDetect(true);
        functionConfiguration.setSupportFaceRecognition(true);
        functionConfiguration.setSupportGender(true);
        functionConfiguration.setSupportLiveness(true);
        functionConfiguration.setSupportIRLiveness(true);
        engineConfiguration.setFunctionConfiguration(functionConfiguration);
        faceEngine.init(engineConfiguration);
    }
    public FaceUtils(String imageUrl){
        imageInfo = getRGBData(new File(imageUrl));
        faceEngine = new FaceEngine(configFile);
        //Engine configuration
        EngineConfiguration engineConfiguration = new EngineConfiguration();
        engineConfiguration.setDetectMode(DetectMode.ASF_DETECT_MODE_IMAGE);
        engineConfiguration.setDetectFaceOrientPriority(DetectOrient.ASF_OP_ALL_OUT);
        engineConfiguration.setDetectFaceMaxNum(10);
        engineConfiguration.setDetectFaceScaleVal(16);
        //Function configuration
        functionConfiguration = new FunctionConfiguration();
        functionConfiguration.setSupportAge(true);
        functionConfiguration.setSupportFace3dAngle(true);
        functionConfiguration.setSupportFaceDetect(true);
        functionConfiguration.setSupportFaceRecognition(true);
        functionConfiguration.setSupportGender(true);
        functionConfiguration.setSupportLiveness(true);
        engineConfiguration.setFunctionConfiguration(functionConfiguration);
        faceEngine.init(engineConfiguration);
    }

    public FaceEngine getFaceEngine() {
        return faceEngine;
    }

    public void setImageInfo(String imageUrl) {
        this.imageInfo = getRGBData(new File(imageUrl));
    }
    public float compareTo(byte[] byte1,byte[] byte2){
        //Feature comparison
        FaceFeature targetFaceFeature = new FaceFeature();
        targetFaceFeature.setFeatureData(byte1);
        FaceFeature sourceFaceFeature = new FaceFeature();
        sourceFaceFeature.setFeatureData(byte2);
        FaceSimilar faceSimilar = new FaceSimilar();
        int errorCode = faceEngine.compareFaceFeature(targetFaceFeature, sourceFaceFeature, faceSimilar);
        if (errorCode != ResponseCode.MOK)return -1;
        System.out.println("Similarity:" + faceSimilar.getScore());
        return faceSimilar.getScore();
    }
    /**
     * @Date: 2021/7/9 16:43
     * @Author Suo Banjin
     * @Description: Get face information
     * @MethodName:
     */
    public  List<FaceInfo> getFaceInfo(){
        if (imageInfo == null)return null;
        List<FaceInfo> faceInfoList = new ArrayList<>();
        int errorCode = faceEngine.detectFaces(imageInfo.getImageData(), imageInfo.getWidth(), imageInfo.getHeight(), imageInfo.getImageFormat(), faceInfoList);
        if (errorCode != ResponseCode.MOK)return null;
        if (faceInfoList.size() == 0)return null;
        return faceInfoList;
    }
    /**
     * @Date: 2021/7/9 16:43
     * @Author Suo Banjin
     * @Description: Detect whether it is living
     * @MethodName:
     */
    public  boolean isLive(){
        if (imageInfo == null)return false;
        faceEngine.setLivenessParam(0.5f, 0.7f);
        FunctionConfiguration configuration = new FunctionConfiguration();
        configuration.setSupportAge(true);
        configuration.setSupportFace3dAngle(true);
        configuration.setSupportGender(true);
        configuration.setSupportLiveness(true);
        List<FaceInfo> faceInfo = getFaceInfo();
        int errorCode = faceEngine.process(imageInfo.getImageData(), imageInfo.getWidth(), imageInfo.getHeight(), imageInfo.getImageFormat(), faceInfo, configuration);
        if (errorCode != ResponseCode.MOK)return false;
        //In vivo detection
        List<LivenessInfo> livenessInfoList = new ArrayList<>();
        errorCode = faceEngine.getLiveness(livenessInfoList);
        if (errorCode != ResponseCode.MOK)return false;
        if (livenessInfoList.size() == 0)return false;
        return livenessInfoList.get(0).getLiveness() == 1;
    }
    /**
     * @Date: 2021/7/9 15:46
     * @Author Suo Banjin
     * @Description: Get face feature values
     * @MethodName:
     */
    public byte[] getFaceFeature(){
        if (imageInfo == null)return null;
        if (!isLive())return null;
        List<FaceInfo> faceInfoList = getFaceInfo();
        if (faceInfoList == null || faceInfoList.size() == 0)return null;
        //feature extraction 
        FaceFeature faceFeature = new FaceFeature();
        int errorCode = faceEngine.extractFaceFeature(imageInfo.getImageData(), imageInfo.getWidth(), imageInfo.getHeight(), imageInfo.getImageFormat(), faceInfoList.get(0), faceFeature);
        if (errorCode != ResponseCode.MOK)return null;
        return faceFeature.getFeatureData();
    }

    public void unInit(){
        faceEngine.unInit();
    }
}


Face information entry:

package zzuli.zw.camera;

import com.github.sarxos.webcam.Webcam;
import com.github.sarxos.webcam.WebcamResolution;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.concurrent.Task;
import javafx.embed.swing.SwingFXUtils;
import javafx.geometry.Insets;
import javafx.geometry.Orientation;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.FlowPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import org.apache.commons.lang3.StringUtils;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.List;

public class MyCameraGetImage extends Application {
    /**
     * File path for photo storage
     */
    String filePath = "C:/image/";

    private static class WebCamInfo {
        private String webCamName;
        private int webCamIndex;

        public String getWebCamName() {
            return webCamName;
        }

        public void setWebCamName(String webCamName) {
            this.webCamName = webCamName;
        }

        public int getWebCamIndex() {
            return webCamIndex;
        }

        public void setWebCamIndex(int webCamIndex) {
            this.webCamIndex = webCamIndex;
        }
    }

    private FlowPane bottomCameraControlPane;
    private FlowPane topPane;
    private ImageView imgWebCamCapturedImage;
    private Webcam webCam = null;
    private boolean stopCamera = false;
    private BufferedImage grabbedImage;
    private ObjectProperty<Image> imageProperty = new SimpleObjectProperty<>();
    private BorderPane webCamPane;

    @Override
    public void start(Stage primaryStage) {
        primaryStage.setTitle("Camera");
        BorderPane root = new BorderPane();
        topPane = new FlowPane();
        topPane.setAlignment(Pos.CENTER);
        topPane.setHgap(20);
        topPane.setOrientation(Orientation.HORIZONTAL);
        topPane.setPrefHeight(40);
        root.setTop(topPane);
        webCamPane = new BorderPane();
        webCamPane.setStyle("-fx-background-color: #ccc;");
        imgWebCamCapturedImage = new ImageView();
        webCamPane.setCenter(imgWebCamCapturedImage);
        root.setCenter(webCamPane);
        createTopPanel();
        bottomCameraControlPane = new FlowPane();
        bottomCameraControlPane.setOrientation(Orientation.HORIZONTAL);
        bottomCameraControlPane.setAlignment(Pos.CENTER);
        bottomCameraControlPane.setHgap(20);
        bottomCameraControlPane.setVgap(10);
        bottomCameraControlPane.setPrefHeight(40);
        bottomCameraControlPane.setDisable(true);
        createCameraControls();
        root.setBottom(bottomCameraControlPane);
        primaryStage.setScene(new Scene(root));
        primaryStage.setHeight(700);
        primaryStage.setWidth(600);
        primaryStage.centerOnScreen();
        primaryStage.show();
        Platform.runLater(this::setImageViewSize);
    }

    protected void setImageViewSize() {
        double height = webCamPane.getHeight();
        double width = webCamPane.getWidth();
        imgWebCamCapturedImage.setFitHeight(height);
        imgWebCamCapturedImage.setFitWidth(width);
        imgWebCamCapturedImage.prefHeight(height);
        imgWebCamCapturedImage.prefWidth(width);
        imgWebCamCapturedImage.setPreserveRatio(true);
    }

    private void createTopPanel() {
        int webCamCounter = 0;
        Label lbInfoLabel = new Label("Select camera:");
        ObservableList<WebCamInfo> options = FXCollections.observableArrayList();
        topPane.getChildren().add(lbInfoLabel);
        for (Webcam webcam : Webcam.getWebcams()) {
            WebCamInfo webCamInfo = new WebCamInfo();
            webCamInfo.setWebCamIndex(webCamCounter);
            webCamInfo.setWebCamName(webcam.getName());
            options.add(webCamInfo);
            webCamCounter++;
        }

        ComboBox<WebCamInfo> cameraOptions = new ComboBox<>();
        cameraOptions.setItems(options);
        String cameraListPromptText = "Select camera:";
        cameraOptions.setPromptText(cameraListPromptText);
        cameraOptions.getSelectionModel().selectedItemProperty().addListener((ObservableValue<? extends WebCamInfo> arg0, WebCamInfo arg1, WebCamInfo arg2) -> {
            if (arg2 != null) {
                initializeWebCam(arg2.getWebCamIndex());
            }
        });
        topPane.getChildren().add(cameraOptions);
    }

    protected void initializeWebCam(final int webCamIndex) {
        Task<Void> webCamTask = new Task<Void>() {
            @Override
            protected Void call() {
                webCam = Webcam.getWebcams().get(webCamIndex);
                webCam.setViewSize(WebcamResolution.VGA.getSize());
                webCam.open();
                startWebCamStream();
                return null;
            }
        };
        Thread webCamThread = new Thread(webCamTask);
        webCamThread.setDaemon(true);
        webCamThread.start();
        bottomCameraControlPane.setDisable(false);
    }
    protected void startWebCamStream() {
        stopCamera = false;
        Task<Void> task = new Task<Void>() {
            @Override
            protected Void call() {
                while (!stopCamera) {
                    try {
                        if ((grabbedImage = webCam.getImage()) != null) {
                            Platform.runLater(() -> {
                                Image mainImage = SwingFXUtils.toFXImage(grabbedImage, null);
                                imageProperty.set(mainImage);
                            });
                            grabbedImage.flush();
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
                return null;
            }
        };
        Thread th = new Thread(task);
        th.setDaemon(true);
        th.start();
        imgWebCamCapturedImage.imageProperty().bind(imageProperty);
    }
    private void createCameraControls() {
        Button banCameraGetImage = new Button();
        banCameraGetImage.setOnAction(event -> getImagine());
        banCameraGetImage.setText("Photo collection");
        bottomCameraControlPane.getChildren().add(banCameraGetImage);
    }
    protected void getImagine() {
        Image image = imgWebCamCapturedImage.getImage();
        ImageView imageView = new ImageView(image);
        Label label = new Label("surname      Name:");
        TextField textField = new TextField();
        textField.setPromptText("Example: Zhang San");
        HBox hBox = new HBox(5);
        hBox.setAlignment(Pos.CENTER);
        hBox.getChildren().addAll(label, textField);
        Label label2 = new Label("Major grade:");
        TextField textField2 = new TextField();
        textField2.setPromptText("Example: software engineering 18-04");
        HBox hBox2 = new HBox(5);
        hBox2.setAlignment(Pos.CENTER);
        hBox2.getChildren().addAll(label2, textField2);
        Label label3 = new Label("learn      number:");
        TextField textField3 = new TextField();
        textField3.setPromptText("Example: 541813460400");
        HBox hBox3 = new HBox(5);
        hBox3.setAlignment(Pos.CENTER);
        hBox3.getChildren().addAll(label3, textField3);
        Button button = new Button("preservation");
        Stage stage = new Stage();
        stage.setTitle("Information entry");
        button.setOnAction(event -> {
            String name = textField.getText();
            String student = textField2.getText();
            String grade = textField3.getText();
            Alert alert = new Alert(Alert.AlertType.WARNING);
            if (StringUtils.isEmpty(name) || StringUtils.isEmpty(student) || StringUtils.isEmpty(grade)){
                alert.setContentText("Required item cannot be blank!");
                alert.showAndWait();
            }else {
                try {
                    File file = new File(filePath + student + ".png");
                    ImageIO.write(SwingFXUtils.fromFXImage(image, null), "png", file);
                    FaceUtils faceUtils = new FaceUtils();
                    faceUtils.setImageInfo(filePath + student + ".png");
                    byte[] faceFeature = faceUtils.getFaceFeature();
                    if (faceFeature == null){
                        alert.setContentText("Failed to collect face information, please make sure the lens contains faces!");
                        alert.showAndWait();
                    }else {
                        alert.setAlertType(Alert.AlertType.INFORMATION);
                        alert.setHeaderText("Collecting");
                        alert.show();
                        Student studentInfo = new Student();
                        studentInfo.setFeature(faceFeature);
                        studentInfo.setGrade(grade);
                        studentInfo.setName(name);
                        studentInfo.setStudent(student);
                        studentInfo.setImage(filePath + student + ".png");
                        InfoMapper infoMapper = new InfoMapper();
                        List<Student> allInfo = infoMapper.findAllInfo();
                        boolean flag = false;
                        for (Student student1 : allInfo) {
                            byte[] feature = student1.getFeature();
                            float compare = faceUtils.compareTo(faceFeature, feature);
                            if (compare >= 0.99) {
                                flag = true;
                                break;
                            }
                        }
                        if (flag){
                            alert.setHeaderText("The face has been entered!");
                            alert.show();
                        }else {
                            int i = infoMapper.insertInfo(studentInfo);
                            alert.hide();
                            if (i <= 0) {
                                alert.setHeaderText("Collection failed");
                                alert.showAndWait();
                            } else {
                                alert.setHeaderText("Collection successful");
                                alert.showAndWait();
                                stage.close();
                            }
                        }
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        });
        VBox vBox = new VBox(10);
        vBox.setAlignment(Pos.CENTER);
        vBox.setPadding(new Insets(10,10,10,10));
        vBox.getChildren().addAll(imageView, hBox,hBox2,hBox3,button);
        stage.setScene(new Scene(vBox));
        stage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
}

Face information recognition:

package zzuli.zw.camera;

import com.github.sarxos.webcam.Webcam;
import com.github.sarxos.webcam.WebcamEvent;
import com.github.sarxos.webcam.WebcamListener;
import com.github.sarxos.webcam.WebcamResolution;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.concurrent.Task;
import javafx.embed.swing.SwingFXUtils;
import javafx.geometry.Insets;
import javafx.geometry.Orientation;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.FlowPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import org.apache.commons.lang3.StringUtils;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;

public class MyCameraConfig extends Application {
    /**
     * File path of photo storage
     */
    String filePath = "C:/image/";

    private static class WebCamInfo {
        private String webCamName;
        private int webCamIndex;

        public String getWebCamName() {
            return webCamName;
        }

        public void setWebCamName(String webCamName) {
            this.webCamName = webCamName;
        }

        public int getWebCamIndex() {
            return webCamIndex;
        }

        public void setWebCamIndex(int webCamIndex) {
            this.webCamIndex = webCamIndex;
        }
    }

    private FlowPane bottomCameraControlPane;
    private FlowPane topPane;
    private ImageView imgWebCamCapturedImage;
    private Webcam webCam = null;
    private boolean stopCamera = false;
    private BufferedImage grabbedImage;
    private ObjectProperty<Image> imageProperty = new SimpleObjectProperty<>();
    private BorderPane webCamPane;

    @Override
    public void start(Stage primaryStage) {
        primaryStage.setTitle("Camera");
        BorderPane root = new BorderPane();
        topPane = new FlowPane();
        topPane.setAlignment(Pos.CENTER);
        topPane.setHgap(20);
        topPane.setOrientation(Orientation.HORIZONTAL);
        topPane.setPrefHeight(40);
        root.setTop(topPane);
        webCamPane = new BorderPane();
        webCamPane.setStyle("-fx-background-color: #ccc;");
        imgWebCamCapturedImage = new ImageView();
        webCamPane.setCenter(imgWebCamCapturedImage);
        root.setCenter(webCamPane);
        createTopPanel();
        bottomCameraControlPane = new FlowPane();
        bottomCameraControlPane.setOrientation(Orientation.HORIZONTAL);
        bottomCameraControlPane.setAlignment(Pos.CENTER);
        bottomCameraControlPane.setHgap(20);
        bottomCameraControlPane.setVgap(10);
        bottomCameraControlPane.setPrefHeight(40);
        bottomCameraControlPane.setDisable(true);
        createCameraControls();
        root.setBottom(bottomCameraControlPane);
        primaryStage.setScene(new Scene(root));
        primaryStage.setHeight(700);
        primaryStage.setWidth(600);
        primaryStage.centerOnScreen();
        primaryStage.show();
        Platform.runLater(this::setImageViewSize);
    }

    protected void setImageViewSize() {
        double height = webCamPane.getHeight();
        double width = webCamPane.getWidth();
        imgWebCamCapturedImage.setFitHeight(height);
        imgWebCamCapturedImage.setFitWidth(width);
        imgWebCamCapturedImage.prefHeight(height);
        imgWebCamCapturedImage.prefWidth(width);
        imgWebCamCapturedImage.setPreserveRatio(true);
    }

    private void createTopPanel() {
        int webCamCounter = 0;
        Label lbInfoLabel = new Label("Select camera:");
        ObservableList<WebCamInfo> options = FXCollections.observableArrayList();
        topPane.getChildren().add(lbInfoLabel);
        for (Webcam webcam : Webcam.getWebcams()) {
            WebCamInfo webCamInfo = new WebCamInfo();
            webCamInfo.setWebCamIndex(webCamCounter);
            webCamInfo.setWebCamName(webcam.getName());
            options.add(webCamInfo);
            webCamCounter++;
        }

        ComboBox<WebCamInfo> cameraOptions = new ComboBox<>();
        cameraOptions.setItems(options);
        String cameraListPromptText = "Select camera:";
        cameraOptions.setPromptText(cameraListPromptText);
        cameraOptions.getSelectionModel().selectedItemProperty().addListener((ObservableValue<? extends WebCamInfo> arg0, WebCamInfo arg1, WebCamInfo arg2) -> {
            if (arg2 != null) {
                initializeWebCam(arg2.getWebCamIndex());
            }
        });
        topPane.getChildren().add(cameraOptions);
    }

    protected void initializeWebCam(final int webCamIndex) {
        Task<Void> webCamTask = new Task<Void>() {
            @Override
            protected Void call() {
                webCam = Webcam.getWebcams().get(webCamIndex);
                webCam.setViewSize(WebcamResolution.VGA.getSize());
                webCam.open();
                startWebCamStream();
                return null;
            }
        };
        Thread webCamThread = new Thread(webCamTask);
        webCamThread.setDaemon(true);
        webCamThread.start();
        bottomCameraControlPane.setDisable(false);
    }

    protected void startWebCamStream() {
        stopCamera = false;
        Task<Void> task = new Task<Void>() {
            @Override
            protected Void call() {
                while (!stopCamera) {
                    try {
                        if ((grabbedImage = webCam.getImage()) != null) {
                            Platform.runLater(() -> {
                                Image mainImage = SwingFXUtils.toFXImage(grabbedImage, null);

                                imageProperty.set(mainImage);
                            });
                            grabbedImage.flush();
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
                return null;
            }
        };
        Thread th = new Thread(task);
        th.setDaemon(true);
        th.start();
        imgWebCamCapturedImage.imageProperty().bind(imageProperty);
        Timer timer = new Timer();
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                System.out.println("hello");
                Platform.runLater(()->{
                    getImagine();
                    timer.cancel();
                });
            }
        }, 2000);

    }

    private void createCameraControls() {
    }

    protected void getImagine() {
        Image image = imgWebCamCapturedImage.getImage();
        ImageView imageView = new ImageView();
        Label label = new Label("surname      Name:");
        TextField textField = new TextField();
        HBox hBox = new HBox(5);
        hBox.setAlignment(Pos.CENTER);
        hBox.getChildren().addAll(label, textField);
        Label label2 = new Label("Major grade:");
        TextField textField2 = new TextField();
        HBox hBox2 = new HBox(5);
        hBox2.setAlignment(Pos.CENTER);
        hBox2.getChildren().addAll(label2, textField2);
        Label label3 = new Label("learn      number:");
        TextField textField3 = new TextField();
        Label label4 = new Label("Similarity:");
        TextField textField4 = new TextField();
        HBox hBox3 = new HBox(5);
        hBox3.setAlignment(Pos.CENTER);
        hBox3.getChildren().addAll(label3, textField3);
        HBox hBox4 = new HBox(5);
        hBox4.setAlignment(Pos.CENTER);
        hBox4.getChildren().addAll(label4, textField4);
        Stage stage = new Stage();
        stage.setOnHiding(event -> {
           Timer timer = new Timer();
           timer.schedule(new TimerTask() {
               @Override
               public void run() {
                   System.out.println("hello");
                   Platform.runLater(()->{
                       getImagine();
                       timer.cancel();
                   });
               }
           }, 2000);
        });
        Alert alert = new Alert(Alert.AlertType.WARNING);
        VBox vBox = new VBox(10);
        try {
            File file = new File(filePath + "temp" + ".png");
            ImageIO.write(SwingFXUtils.fromFXImage(image, null), "png", file);
            FaceUtils faceUtils = new FaceUtils();
            faceUtils.setImageInfo(filePath + "temp"+ ".png");
            byte[] faceFeature = faceUtils.getFaceFeature();
            if (faceFeature == null) {
                Timer timer = new Timer();
                timer.schedule(new TimerTask() {
                    @Override
                    public void run() {
                        System.out.println("hello");
                        Platform.runLater(()->{
                            getImagine();
                            timer.cancel();
                        });
                    }
                }, 2000);
            } else {
                Student studentInfo = new Student();
                studentInfo.setFeature(faceFeature);
                InfoMapper infoMapper = new InfoMapper();
                List<Student> allInfo = infoMapper.findAllInfo();
                Map<Float,Student> map = new TreeMap<>((o1, o2) -> (int)(o2-o1));
                for (Student student1 : allInfo) {
                    byte[] feature = student1.getFeature();
                    float compare = faceUtils.compareTo(faceFeature, feature);
                    map.put(compare, student1);
                }
                Set<Float> keySet = map.keySet();
                for (Float aFloat : keySet) {
                    Student student = map.get(aFloat);
                    textField.setText(student.getName());
                    textField2.setText(student.getGrade());
                    textField3.setText(student.getStudent());
                    textField4.setText(aFloat.toString());
                    InputStream inputStream = new FileInputStream(student.getImage());
                    imageView.setImage(new Image(inputStream));
                    inputStream.close();
                    break;
                }
                vBox.setAlignment(Pos.CENTER);
                vBox.setPadding(new Insets(10, 10, 10, 10));
                vBox.getChildren().addAll(imageView, hBox, hBox2, hBox3,hBox4);
                stage.setScene(new Scene(vBox));
                stage.show();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    public static void main(String[] args) {
        launch(args);
    }
}

6, Complete code

https://github.com/suobanjin/javacv

7, Design difficulties

Automatic face recognition

In the first version of the design, I used the method of user passive identification. When the user clicks the button, I capture the current interface and identify the information. However, considering the actual application scenario, I think it is inconvenient, so I use the timed task to capture pictures regularly for face recognition and comparison.

Timer timer = new Timer();
timer.schedule(new TimerTask() {
    @Override
    public void run() {
        System.out.println("hello");
        Platform.runLater(()->{
            getImagine();
            timer.cancel();
        });
    }
}, 2000);

Set the task during camera initialization and execute it after 2s delay. When the user is recognized successfully, it will jump to the user information interface. At this time, we set the window closing event:

stage.setOnHiding(event -> {
   Timer timer = new Timer();
   timer.schedule(new TimerTask() {
       @Override
       public void run() {
           System.out.println("hello");
           Platform.runLater(()->{
               getImagine();
               timer.cancel();
           });
       }
   }, 2000);
});

Meanwhile, when the user identification is unsuccessful:

if (faceFeature == null) {
    Timer timer = new Timer();
    timer.schedule(new TimerTask() {
        @Override
        public void run() {
            System.out.println("hello");
            Platform.runLater(()->{
                getImagine();
                timer.cancel();
            });
        }
    }, 2000);
}

8, Project summary

Overall, the project is relatively simple. There are many areas for improvement:

  • webcam is not familiar with the use and does not view documents too much. At present, it is viewing documents so as to realize face marking and avoid repeated face detection
  • The more efficient data storage also needs to be considered. It can be seen that the face feature value is about 1kb. If there is more information in the face information database, it will waste a lot of time and low efficiency if we find and compare all the information in the database. At present, it is considered whether it can be stored in a file for operation. Of course, this needs to be compared to see which is more efficient.

Topics: Java face recognition javafx