系列文章:
一、JavaFX摄像:https://blog.csdn.net/haoranhaoshi/article/details/85880893
二、JavaFX拍照:https://blog.csdn.net/haoranhaoshi/article/details/85930981
三、百度人脸识别--人脸对比:https://blog.csdn.net/haoranhaoshi/article/details/85954440
四、人脸库对比:https://blog.csdn.net/haoranhaoshi/article/details/86302313
补充:
解决WebCam框架中摄像模糊:https://blog.csdn.net/haoranhaoshi/article/details/87713878
Java 摄像(依靠开源框架WebCam)(Swing方式):https://blog.csdn.net/haoranhaoshi/article/details/87714541
下载资源:
Java摄像开源框架(文档、案例、Jar包)、个人项目工程(JavaFX)、原始实例(JavaFX):https://download.csdn.net/download/haoranhaoshi/10898408
摄像、拍照、人脸识别、人脸库对比: https://download.csdn.net/download/haoranhaoshi/10911079
本篇在系列文章三的基础上进行扩展,拍照存储后产生人脸库,人脸图片保存时命名为个人姓名,点击人脸识别在人脸库中进行对比,展示对比结果。如果人脸库中有重复的人脸,也可在对比结果中检测到。
人脸库对比效果:
项目为IDEA搭建,终极工程可在如下地址下载(包括Java摄像、拍照、人脸识别、人脸库对比):
https://download.csdn.net/download/haoranhaoshi/10911079
(为了赚两积分,就不上GitHub了?,当然,Github上也有不少博主优秀工程https://github.com/haoranhaoshi)
import com.github.sarxos.webcam.Webcam;
import facematch.FaceMatch;
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.json.JSONException;
import org.json.JSONObject;import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;/*** 推荐JDK8及以上(适应lambda表达式),需导入lib下三个Jar包,支持摄像头选择、开始摄像、停止摄像、拍照存储、人脸识别*/
public class MyFaceMatch extends Application {/*** 拍照存储的文件路径*/String cameraImgFolderPath = new File("").getAbsolutePath() + "/src/userimage/";/*** 人脸识别临时存储的文件路径*/String faceImgFolderPath = new File("").getAbsolutePath() + "/src/tempimage/";private 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;}@Overridepublic String toString() {return "摄像头" + (Integer.parseInt(webCamName.split("Integrated Webcam ")[1]) + 1);}}private FlowPane bottomCameraControlPane;private FlowPane topPane;private BorderPane root;private String cameraListPromptText = "选择摄像头:";private ImageView imgWebCamCapturedImage;private Webcam webCam = null;private boolean stopCamera = false;private BufferedImage grabbedImage;private ObjectProperty<Image> imageProperty = new SimpleObjectProperty<Image>();private BorderPane webCamPane;private Button btnCamreaStop;private Button btnCamreaStart;private Button btnCamreaGetImage;private Button btnFaceMatch;@Overridepublic void start(Stage primaryStage) {primaryStage.setTitle("摄像");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(() ->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("选择摄像头:");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);cameraOptions.setPromptText(cameraListPromptText);cameraOptions.getSelectionModel().selectedItemProperty().addListener((ObservableValue<? extends WebCamInfo> arg0, WebCamInfo arg1, WebCamInfo arg2) -> {if (arg2 != null) {System.out.println("WebCam Index: " + arg2.getWebCamIndex() + ": WebCam Name:" + arg2.getWebCamName());initializeWebCam(arg2.getWebCamIndex());}});topPane.getChildren().add(cameraOptions);}protected void initializeWebCam(final int webCamIndex) {Task<Void> webCamTask = new Task<Void>() {@Overrideprotected Void call() {if (webCam != null) {disposeWebCamCamera();}webCam = Webcam.getWebcams().get(webCamIndex);webCam.open();startWebCamStream();return null;}};Thread webCamThread = new Thread(webCamTask);webCamThread.setDaemon(true);webCamThread.start();bottomCameraControlPane.setDisable(false);btnCamreaStart.setDisable(true);}protected void startWebCamStream() {stopCamera = false;Task<Void> task = new Task<Void>() {@Overrideprotected Void call() {while (!stopCamera) {try {if ((grabbedImage = webCam.getImage()) != null) {Platform.runLater(() -> {Image mainiamge = SwingFXUtils.toFXImage(grabbedImage, null);imageProperty.set(mainiamge);});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() {btnCamreaStop = new Button();btnCamreaStop.setOnAction(event -> stopWebCamCamera());btnCamreaStop.setText("停止摄像");btnCamreaStart = new Button();btnCamreaStart.setOnAction(event -> startWebCamCamera());btnCamreaStart.setText("开始摄像");btnCamreaGetImage = new Button();btnCamreaGetImage.setOnAction(event -> getImagine());btnCamreaGetImage.setText("拍照存储");btnFaceMatch = new Button();btnFaceMatch.setOnAction(event -> faceMatch());btnFaceMatch.setText("人脸识别");bottomCameraControlPane.getChildren().add(btnCamreaStart);bottomCameraControlPane.getChildren().add(btnCamreaStop);bottomCameraControlPane.getChildren().add(btnCamreaGetImage);bottomCameraControlPane.getChildren().add(btnFaceMatch);}protected void faceMatch(){Image image = imgWebCamCapturedImage.getImage();String faceImgPath = faceImgFolderPath + "tempImg" + ".png";try {File file = new File(faceImgPath);ImageIO.write(SwingFXUtils.fromFXImage(image, null), "png", file);} catch (IOException e) {e.printStackTrace();}File[] fileArray = new File(cameraImgFolderPath).listFiles();String ak = "PSce6S7M7WVRVyIux15iDToC";String sk = "fvzwcYociG2GYnsZppKqEbSlUDQaQ9Sd";List<String> faceMathPersonNameList = new ArrayList<>();for(int i = 0;i < fileArray.length;i++){String personImg = fileArray[i].getName();String storeImgPath = cameraImgFolderPath + personImg;String result = FaceMatch.match(ak, sk, faceImgPath, storeImgPath);try {String score = new JSONObject(result).getJSONObject("result").getString("score");// 阈值为80,高于80分判断为同一人if(Double.parseDouble(score) >= 80){faceMathPersonNameList.add(personImg.split("\\.")[0]);}} catch (JSONException e) {e.printStackTrace();}}String alertContent = "在拍照存储中没有匹配者!";for(int i = 0;i < faceMathPersonNameList.size();i++){String nameAbout = i < faceMathPersonNameList.size() - 1 ? (faceMathPersonNameList.get(i) + "、") : (faceMathPersonNameList.get(i) + "。");alertContent = i == 0 ? ("在拍照存储中找到匹配者,姓名为:" + nameAbout) : (alertContent + nameAbout);}Alert alert = new Alert(Alert.AlertType.INFORMATION, "", ButtonType.CLOSE);alert.setHeaderText(alertContent);alert.show();}protected void getImagine() {Image image = imgWebCamCapturedImage.getImage();ImageView imageView = new ImageView(image);Label label = new Label("图片名称:");TextField textField = new TextField();HBox hBox = new HBox(5);hBox.setAlignment(Pos.CENTER);hBox.getChildren().addAll(label, textField);Button button = new Button("保存");Stage stage = new Stage();button.setOnAction(event -> {try {File file = new File(cameraImgFolderPath + textField.getText() + ".png");ImageIO.write(SwingFXUtils.fromFXImage(image, null), "png", file);} catch (IOException e) {e.printStackTrace();}stage.close();});VBox vBox = new VBox(10);vBox.setAlignment(Pos.CENTER);vBox.setPadding(new Insets(10,10,10,10));vBox.getChildren().addAll(imageView, hBox, button);stage.setScene(new Scene(vBox));stage.show();}protected void disposeWebCamCamera() {stopCamera = true;webCam.close();Webcam.shutdown();btnCamreaStart.setDisable(true);btnCamreaStop.setDisable(true);}protected void startWebCamCamera() {stopCamera = false;startWebCamStream();btnCamreaStop.setDisable(false);btnCamreaStart.setDisable(true);}protected void stopWebCamCamera() {stopCamera = true;btnCamreaStart.setDisable(false);btnCamreaStop.setDisable(true);}public static void main(String[] args) {launch(args);}
}