java利用openCV进行人脸对比(三)

之前写过用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();
        
      
    }

}

 

 

相关文章

java利用openCV进行人脸识别,采集照片和训练模型(二)

java调起本地摄像头,利用openCV进行人脸识别(一)

### 回答1: Java基于人脸识别签到是一种利用Java编程语言结合人脸识别技术实现签到功能的方法。人脸识别是一种通过图像分析和模式识别来判断人脸特征并进行身份验证的技术。它可以通过采集用户的面部特征,将其与数据库中的人脸特征进行比对,从而实现签到过程的自动化和准确性。 在Java中,可以使用一些第方的人脸识别库或者API来实现人脸识别功能。其中,常用的人脸识别库包括OpenCV、Dlib等。这些库可以提供人脸检测和识别的功能,可以进行面部特征的提取和对比。 实现基于人脸识别的签到功能,首先需要进行数据库的搭建和人脸的注册。通过人脸采集设备(如摄像头),获取用户的面部图像,并将之与用户的其他信息(如姓名、学号等)一起存储到数据库中。同时,可以对人脸图像进行预处理,例如对齐、裁剪等操作,提取出关键的面部特征。 在签到过程中,首先进行人脸的检测,确定摄像头中是否存在人脸。接着,对检测到的人脸进行特征提取,并将之与数据库中的特征进行比对。如果相似度达到预先设定的阈值,则认为识别成功,可以进行签到。否则,继续检测直到达到阈值或者超过一定的尝试次数。 通过Java的编程实现,可以方便地调用人脸识别库提供的接口,实现人脸的检测、识别和比对等功能。同时,Java也具备良好的跨平台性,可以在不同的操作系统和设备上运行,满足不同环境下的签到需求。 综上所述,基于人脸识别的签到功能可以借助Java编程语言实现,通过调用人脸识别库提供的接口,实现人脸的检测、识别和比对,从而实现签到过程的自动化和准确性。 ### 回答2: Java基于人脸识别签到系统是一种利用Java语言开发的签到系统,该系统通过人脸识别技术来验证用户身份并记录签到信息。 该系统的核心是人脸识别算法,它能够通过摄像头捕获用户的人脸图像,并将其与事先存储的已知人脸特征进行比对。通过比对算法,系统可以快速准确地识别用户,并记录签到时间。 Java作为一种面向对象的编程语言,在该系统中起到了关键作用。Java语言具有跨平台的特性,使得开发人员可以在不同操作系统上运行签到系统。同时,Java语言也提供了强大的图像处理和人脸识别库,如OpenCVJavaCV,可以方便地实现人脸识别功能。 基于人脸识别的签到系统有许多优点。首先,它可以大大提高签到的效率和准确性。相比传统的手动签到方式,人脸识别签到系统无需用户动手,只需站在摄像头前即可完成签到,节省了人力和时间成本。其次,人脸识别技术具有较高的识别准确率,能够有效防止冒名顶替和作弊行为。再者,该系统具有较强的可扩展性,可以根据需要进行定制和拓展,如与学生信息管理系统或员工考勤系统进行数据对接。 当然,人脸识别签到系统也有一些局限性,比如光线、角度和遮挡等因素可能会影响识别结果。因此,在开发过程中需注意这些问题,并结合合适的算法和参数进行优化。 总之,基于Java人脸识别签到系统是一种高效、准确的签到方式,能够满足各种签到需求,提高签到效率、防止作弊,是现代化签到管理的理想选择。
评论 15
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值