之前写过用openCV识别人脸和训练模型,这次说说用模型文件来对比人脸
首先要调起本地摄像头,然后识别一下人脸,这个人脸框出来,再调用模型文件进行人脸对比,识别成功显示用户名在人脸框框上面
这次我把这个东东结合了另一个项目,写成了一个客户端,然后可以输入实验室ID和用户ID去进行一系列操作,客户端接口请求到另一个项目的服务端,通过服务端去访问Mysql数据库读取一些用户信息和实验室信息,并且校验是否有开门权限,以此来达到打开实验室门的作用
另外,一开始写的过程中,遇到一个脑壳疼的问题
就是我一请求服务端接口,java客户端的画面就会卡住不动,后来查老半天,也没查出是啥问题,有人说是UI线程问题
然后联想想到以前写app的时候,安卓要通过子线程去访问网络再通知主线程更新UI界面
于是我在java客户端起了一个子线程去访问服务端,然后问题就解决了哈哈
以下是相关代码,用到相关工具类可以参考我之前写的博客上面有贴,服务端接口是我自己另一个项目里面写的,这里没有
其他问题可以评论或私信留言
Recognition.java
package face.recognize;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.IOException;
import java.text.DecimalFormat;
import java.util.HashMap;
import java.util.Map;
import javax.swing.*;
import face.detect.FaceDetection;
import face.util.MyConstant;
import face.util.OkHttpHelper;
import face.util.VideoPanel;
import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.core.MatOfRect;
import org.opencv.core.Point;
import org.opencv.core.Rect;
import org.opencv.core.Scalar;
import org.opencv.core.Size;
import org.opencv.face.FaceRecognizer;
import org.opencv.face.LBPHFaceRecognizer;
import org.opencv.imgproc.Imgproc;
import org.opencv.objdetect.CascadeClassifier;
import org.opencv.objdetect.Objdetect;
import org.opencv.videoio.VideoCapture;
public class Recognition {
private static String userId = "";
private static String labId = "";
public final static String BASE_FILE_PATH = "/face/model/";
public final static String BASE_FILE_NAME = "/face_model.yml";
public static String getUserId() {
return userId;
}
public static void setUserId(String userId) {
Recognition.userId = userId;
}
public static String getLabId() {
return labId;
}
public static void setLabId(String labId) {
Recognition.labId = labId;
}
static int tag = 0;
public static VideoPanel vp;
public static VideoPanel getVp() {
return vp;
}
public static void setVp(VideoPanel vp) {
Recognition.vp = vp;
}
public static void main(String[] args) throws Exception {
if (userId.equals("") || labId.equals("")){
JOptionPane.showMessageDialog(null,"账号或实验室编号不可为空!","提示", JOptionPane.ERROR_MESSAGE);
throw new Exception("null error");
}
//通过模型存放的文件名来获取用户对应的模型文件
String readPath = BASE_FILE_PATH + userId + BASE_FILE_NAME;
System.out.println("file path---------->" + readPath);
File testFile = new File(readPath);
if(!testFile .exists()) {
JOptionPane.showMessageDialog(null,"模型文件不存在!请确认操作是否正确!","提示", JOptionPane.ERROR_MESSAGE);
System.out.println("file path---------->模型文件不存在!请确认操作是否正确!");
throw new Exception("error");
}
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
CascadeClassifier faceCascade = new CascadeClassifier();
faceCascade.load(MyConstant.BASE_LOCATION+"/face/install/etc/haarcascades/haarcascade_frontalface_alt.xml");
FaceRecognizer faceRecognizer = LBPHFaceRecognizer.create();
faceRecognizer.read(readPath);
VideoCapture capture = new VideoCapture();
try {
capture.open(0);
VideoPanel videoPanel = VideoPanel.show("Recognition", 640, 480, 0);
//对比识别过程
if (capture.isOpened()) {
Mat image = new Mat();
while (true) {
capture.read(image);
if (!image.empty()) {
detectAndDisplay(image, faceCascade, faceRecognizer);
videoPanel.setImageWithMat(image);
// setVp(videoPanel);
if (tag == 1) {
tag = 3;
JOptionPane.showMessageDialog(null, "开门成功!", "提示",JOptionPane.INFORMATION_MESSAGE);
} else if(tag == 2) {
tag = 3;
JOptionPane.showMessageDialog(null, "开门失败!请确认用户信息和预约信息!", "提示",JOptionPane.ERROR_MESSAGE);
}
} else {
break;
}
}
}
} finally {
capture.release();
}
}
public static void detectAndDisplay(Mat frame, CascadeClassifier faceCascade,
FaceRecognizer faceRecognizer) {
MatOfRect faces = new MatOfRect();
Mat grayFrame = new Mat();
Imgproc.cvtColor(frame, grayFrame, Imgproc.COLOR_BGR2GRAY);
Imgproc.equalizeHist(grayFrame, grayFrame);
// detect faces
faceCascade.detectMultiScale(grayFrame, faces);
Imgproc.equalizeHist(grayFrame, grayFrame);
Rect[] facesArray = faces.toArray();
for (int i = 0; i < facesArray.length; i++) {
int[] label = new int[1];
double[] confidence = new double[1];
faceRecognizer.predict(grayFrame.submat(facesArray[i]), label, confidence);
String name = faceRecognizer.getLabelInfo(label[0]);
Scalar color;
if (confidence[0] < 50) {
if (label[0] == 0) {
color = new Scalar(255, 0, 0);
} else if (label[0] == 1) {
color = new Scalar(0, 255, 0);
} else {
color = new Scalar(0, 255, 255);
}
name = name + " " + new DecimalFormat("#.0").format(confidence[0]);
} else {
name = "face";
color = new Scalar(0, 0, 255);
}
Imgproc.rectangle(frame, facesArray[i].tl(), facesArray[i].br(), color, 2);
setLabel(frame, name, facesArray[i].tl(), color);
}
}
static void setLabel(Mat im, String label, Point or, Scalar color) {
int fontface = Core.FONT_HERSHEY_SIMPLEX;
double scale = 0.8;
int thickness = 2;
int[] baseline = new int[1];
Size text = Imgproc.getTextSize(label, fontface, scale, thickness, baseline);
Imgproc.rectangle(im, new Point(or.x, or.y),
new Point(or.x + text.width, or.y - text.height - baseline[0] - baseline[0]), color,
Core.FILLED);
// System.out.println("识别信息-------------->"+label);
if(!label.equals("face") && tag==0) {
String[] sp = label.split(" ");
Map<String, Object> map = new HashMap<String, Object>();
// 测试数据
// map.put("userId", "1508141221");
// map.put("labId", 1);
map.put("userId", userId);
map.put("labId", labId);
map.put("isTag", 1);
try {
String res = OkHttpHelper.sendGet(MyConstant.BASE_URL, map);
if(res.equals("success")) {
tag = 1;
} else if (res.equals("error")) {
tag = 2;
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Imgproc.putText(im, label, new Point(or.x, or.y - baseline[0]), fontface, scale,
new Scalar(255, 255, 255), thickness);
}
}
OkHttpHelper.java
import java.io.IOException;
import java.util.Map;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
/**
* okhttp请求工具类,用于向服务端发送请求
* @author swallow
*
*/
public class OkHttpHelper {
private static final int COM_SUCCESS = 1;
private static final int COM_ERROR = 0;
public static String sendGet(String url,Map<String, Object> map) throws IOException {
OkHttpClient mClient = new OkHttpClient();
String result = "";
StringBuilder reqUrl = new StringBuilder(url);
if (map != null && map.size() > 0) {
reqUrl.append("?");
for (Map.Entry<String, Object> param : map.entrySet()) {
reqUrl.append(param.getKey() + "=" + param.getValue() + "&");
}
url = reqUrl.subSequence(0, reqUrl.length() - 1).toString();
System.out.println("start sendGet----->"+ url);
}
Request request = new Request.Builder()
.url(url)
.get()
.build();
try (Response response = mClient.newCall(request).execute()) {
result = response.body().string();
System.out.println("result sendGet----->"+ result);
}
return result;
}
}
客户端启动,这里我用JFrame做了个客户端,emmm客户端没有怎么学过,这个写的界面比较简单
package face.util;
import face.detect.FaceDetection;
import face.recognize.CollectData;
import face.recognize.Recognition;
import face.recognize.Train;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
public class Main {
public static void main(String[] args) {
// VideoPanel videoPanel = VideoPanel.show("Recognition", 640, 480);
mainShow();
}
private static void mainShow() {
Map<String,Object> cacheMap = new HashMap<String,Object>();
System.out.println("-----------------start Face Main-----------------");
JFrame fram = new JFrame(); //新建生成一个窗口
fram.setSize(1000,450); //设置窗口大小
fram.setLocationRelativeTo(null); //相对于什么居中,不填默认桌面居中
fram.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//设置关闭按钮关闭窗口并退出,括号内的值是Jfram的属性值,可以查询需要什么
//JPanel panel=new JPanel(); //新建面板
// JPanel panel=(JPanel)fram.getContentPane(); //获取默认面板 Container是JPanel父类 所以需要强制转换
JPanel panel=new JPanel();
panel.setLayout(new FlowLayout(FlowLayout.CENTER ));//设置该面板的布局方式
panel.setSize(300, 450);
JButton buttonFaceDetection = new JButton("开启人脸检测"); //新建按钮
JButton buttonFaceCollectData = new JButton("开启人脸收集");
JButton buttonFaceTrain = new JButton("训练模型");
JButton buttonOpenLab = new JButton("刷脸进入实验室");
JTextField tfUserId = new JTextField(); //新建输入框
JTextField tfLabId = new JTextField();
String note = "<html>说明:第一次使用此程序必须使用人脸收集与训练模型,否则无法正常开门!" +
"训练一次过后下次可不再训练,账号与实验室编号为必填项!</html>";
JLabel jlNote = new JLabel();
JLabel jlUserId = new JLabel("请输入账号");
JLabel jlLabId = new JLabel("请输入实验室编号");
jlNote.setPreferredSize(new Dimension(960, 30));
jlUserId.setPreferredSize(new Dimension(160, 30));
jlLabId.setPreferredSize(new Dimension(160, 30));
jlNote.setText(note);
buttonFaceDetection.setPreferredSize(new Dimension(260, 30));//设置大小
buttonFaceCollectData.setPreferredSize(new Dimension(260, 30));
buttonFaceTrain.setPreferredSize(new Dimension(260, 30));
buttonOpenLab.setPreferredSize(new Dimension(260, 30));
tfUserId.setPreferredSize(new Dimension(260, 30));;
tfLabId.setPreferredSize(new Dimension(260, 30));;
panel.add(jlNote);
panel.add(jlUserId);
panel.add(tfUserId);
panel.add(buttonFaceDetection); //加到面板,不添加窗口中不显示
panel.add(buttonFaceCollectData);
panel.add(jlLabId);
panel.add(tfLabId);
panel.add(buttonFaceTrain);
panel.add(buttonOpenLab);
buttonFaceDetection.addActionListener(new ActionListener() { //为按钮添加事件:开启人脸检测
public void actionPerformed(ActionEvent e) {
//输入按钮单单击后发生的动作
startDetection();
}
});
buttonFaceCollectData.addActionListener(new ActionListener() { //为按钮添加事件:开启人脸收集
public void actionPerformed(ActionEvent e) {
//输入按钮单单击后发生的动作
startCollectData(tfUserId.getText());
}
});
buttonFaceTrain.addActionListener(new ActionListener() { //为按钮添加事件:开启模型训练
public void actionPerformed(ActionEvent e) {
//输入按钮单单击后发生的动作
startTrain(tfUserId.getText());
}
});
buttonOpenLab.addActionListener(new ActionListener() { //为按钮添加事件:开门方法
public void actionPerformed(ActionEvent e) {
//输入按钮单单击后发生的动作
startOpenLab(tfUserId.getText(), tfLabId.getText());
// fram.dispose();
}
});
fram.add(panel);
fram.setVisible(true);
}
private static <V, t> void startDetection() {
System.out.println("-----------------startDetection-----------------");
// FaceDetection faceDetection = new FaceDetection();
new Thread(() -> {
FaceDetection.main(null);
}).start();
}
private static void startCollectData(String s) {
System.out.println("-----------------startCollectData-----------------");
System.out.println(s);
CollectData.setId(s);
new Thread(() -> {
try {
CollectData.main(null);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}).start();
}
private static void startTrain(String s) {
System.out.println("-----------------startTrain-----------------");
Train.setId(s);
new Thread(() -> {
try {
Train.main(null);
} catch (IOException e) {
e.printStackTrace();
}
}).start();
}
private static void startOpenLab( String userId,String LabId) {
System.out.println("-----------------startOpenLab-----------------");
System.out.println("userId------->" + userId);
System.out.println("LabId-------->" + LabId);
Recognition.setUserId(userId);
Recognition.setLabId(LabId);
new Thread(() -> {
try {
Recognition.main(null);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}).start();
}
}
相关文章