Java+opencv+mysql实现人脸识别源码(人脸采集入库+人脸识别相似度)

Java+opencv实现人脸识别

写这篇博客,是因为以前经常使用python+opencv实现人脸处理,后来发现java也可以实现,于是便学习了下,以下将代码和实现过程贴出。

目录

1、环境准备

使用到的技术:java+opencv+mysql
我这里用的是opencv4.1,这里可以自行下载(其实只需要一个opencv的dll文件放在java安装目录的bin下面既可)

2、代码实现

核心opencv人脸识别类(识别算法):

package com.dialect.utils;

import org.opencv.core.*;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
import org.opencv.objdetect.CascadeClassifier;

import java.util.Arrays;

/**
 * 1.  灰度化(减小图片大小)
 * 2. 人脸识别
 * 3. 人脸切割
 * 4. 规一化(人脸直方图)
 * 5. 直方图相似度匹配
 *
 *
 * @Description: 比较两张图片人脸的匹配度
 * @date 2019/2/1813:47
 */
public class FaceCompare {

    // 初始化人脸探测器
    static CascadeClassifier faceDetector;

    static {
        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
        faceDetector = new CascadeClassifier("E:\\eclipseworkspace\\FaceDectcoSys\\src\\haarcascade_frontalface_default.xml");
    }


    // 灰度化人脸
    public static Mat conv_Mat(String img) {
        Mat image0 = Imgcodecs.imread(img);

        Mat image1 = new Mat();
        // 灰度化
        Imgproc.cvtColor(image0, image1, Imgproc.COLOR_BGR2GRAY);
        // 探测人脸
        MatOfRect faceDetections = new MatOfRect();
        faceDetector.detectMultiScale(image1, faceDetections);
        // rect中人脸图片的范围
        for (Rect rect : faceDetections.toArray()) {
            Mat face = new Mat(image1, rect);
            return face;
        }
        return null;
    }

    public static double compare_image(String img_1, String img_2) {
        Mat mat_1 = conv_Mat(img_1);
        Mat mat_2 = conv_Mat(img_2);
        Mat hist_1 = new Mat();
        Mat hist_2 = new Mat();

        //颜色范围
        MatOfFloat ranges = new MatOfFloat(0f, 256f);
        //直方图大小, 越大匹配越精确 (越慢)
        MatOfInt histSize = new MatOfInt(1000);

        Imgproc.calcHist(Arrays.asList(mat_1), new MatOfInt(0), new Mat(), hist_1, histSize, ranges);
        Imgproc.calcHist(Arrays.asList(mat_2), new MatOfInt(0), new Mat(), hist_2, histSize, ranges);

        // CORREL 相关系数
        double res = Imgproc.compareHist(hist_1, hist_2, Imgproc.CV_COMP_CORREL);
        return res;
    }

    public static void main(String[] args) {
        String basePicPath = "E:\\eclipseworkspace\\FaceDectcoSys\\WebContent\\static\\images\\";
        double compareHist = compare_image(basePicPath + "fbb1.jpg", basePicPath + "fbb2.jpg");
        System.out.println(compareHist);
        if (compareHist > 0.72) {
            System.out.println("人脸匹配");
        } else {
            System.out.println("人脸不匹配");
        }
    }
}

测试两张图片相似度(美女照片自己网上找):
Java+opencv+mysql实现人脸识别源码(人脸采集入库+人脸识别相似度)_第1张图片
Java+opencv+mysql实现人脸识别源码(人脸采集入库+人脸识别相似度)_第2张图片
测试结果:相似度0.82左右,还好了
在这里插入图片描述
接着实现网页

数据库dao:

package com.dialect.info.dao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

import com.dialect.info.bean.Dect;

/**
 * 人脸信息DAO接口
 * @author admin
 * @version 2020-05-10
 */
public class DectDao {

	
	/**
	 * 添加
	 * @param con
	 * @param Dialect
	 * @return
	 * @throws Exception
	 */
	public int add(Connection con,Dect dect)throws Exception{
		dect.setId(UUID.randomUUID().toString().replace("-", ""));
		String sql="insert into dect values(?,?)";
		PreparedStatement pstmt=con.prepareStatement(sql);
		pstmt.setString(1,dect.getId());
		pstmt.setString(2,dect.getBase64());
		return pstmt.executeUpdate();
	}
	
	
	/**
	 * 查询所有
	 * @param con
	 * @param dialect
	 * @return
	 * @throws Exception
	 */
	public List<Dect> list(Connection con)throws Exception{
		List<Dect> list = new ArrayList<>();
		Dect entity=null;
		String sql = "select a.* from dect a";
		PreparedStatement pstmt=con.prepareStatement(sql);
		ResultSet rs=pstmt.executeQuery();
		while(rs.next()){
			entity = new Dect();
			entity.setId(rs.getString("id"));
			entity.setBase64(rs.getString("base64"));
			list.add(entity);
		}
		return list;
	}
	
	
}

service层:

package com.dialect.info.service.impl;


import java.sql.Connection;
import java.util.List;

import com.dialect.info.bean.Dect;
import com.dialect.info.dao.DectDao;
import com.dialect.info.service.DectService;
import com.dialect.utils.DbUtil;
import com.dialect.utils.Page;


/**
 * 人脸信息DAO接口
 * @author admin
 * @version 2020-05-10
 */
public class DectServiceImpl  implements DectService  {
	
	DectDao dectDao = new DectDao();
	
	@Override
	public int add(Dect dect) {
		try {
			Connection con = DbUtil.getCon();
			Integer result =dectDao.add(con, dect);
			DbUtil.closeCon(con);
			return result;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return 0;
	}

	@Override
	public List<Dect> select() {
		try {
			Connection con = DbUtil.getCon();
			List<Dect> list = dectDao.list(con);
			DbUtil.closeCon(con);
			return list;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

		
}

control控制层:

package com.dialect.info.controller;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

import com.dialect.info.bean.Dect;
import com.dialect.info.dao.DectDao;
import com.dialect.info.service.DectService;
import com.dialect.info.service.impl.DectServiceImpl;
import com.dialect.utils.Page;
import com.dialect.utils.picToBase64;
import com.dialect.utils.FaceCompare; 

@WebServlet("/dect")
public class DectController extends HttpServlet {
	private static final long serialVersionUID = 1L;
	
	DectDao dectDao=new DectDao();
	DectService dectService = new DectServiceImpl();
	
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doPost(request, response);
	}
	
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		String method = request.getParameter("method");
		if ("upload".equals(method)) {
			upload(request,response);
		}else if ("select".equals(method)) {
			select(request, response);
		}else if ("list".equals(method)) {
			list(request, response);
		}else if ("form".equals(method)) {
			form(request, response);
		}
		
	}
	
	
		//添加
		private void upload(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
			System.err.println("---开始上传---");
			String para = request.getParameter("base64");
			String s = para.replace("data:image/jpeg;base64,","");
			System.err.println(para);
			System.err.println(s);
			
			Dect dect = new Dect();
			dect.setBase64(s);
			int res = dectService.add(dect);
			
//			System.err.println(res);
			
//			String res = "1";
//			String res2 = "3";
			// 解决json中文乱码
	        response.setContentType("text/json;charset=UTF-8");
	        response.setCharacterEncoding("UTF-8");
	        PrintWriter out = response.getWriter();
//	        String str ="{\"success\":"+res+",\"age\":"+res2 +"}";
	        String str ="{\"success\":"+res+"}";
	        out.println(str);
	        out.flush();
	        out.close();
		}
	//添加
	private void select(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		System.err.println("---进来了select方法---");
		FaceCompare faceCompare = new FaceCompare();
		String para = request.getParameter("base64");
		String s = para.replace("data:image/jpeg;base64,","");
		System.err.println(para);
		System.err.println(s);
		picToBase64 pic = new picToBase64();
		String imgPath1 = "E:\\eclipseworkspace\\FaceDectcoSys\\WebContent\\static\\images\\img1.jpg";
		String imgPath2 = "E:\\eclipseworkspace\\FaceDectcoSys\\WebContent\\static\\images\\img2.jpg";
//		String imgPath1 = "E:\\img1.jpg";
//		String imgPath2 = "E:\\img2.jpg";
		//String imgPath2 = "E:\\eclipseworkspace\\FaceDectcogSys\\WebContent\\static\\images\\img2";
		pic.Base64ToImage(s, imgPath1);
		List<Dect> list = dectService.select();
		
		int shibie_flag = 0;
		
		double res = 0;
		
		System.err.println(list.size());
		if (list.size()>0){
			for(Dect dect:list){
				System.err.println(dect.getBase64());
				String s1 = dect.getBase64().replace("data:image/jpeg;base64,","");
				System.err.println("s1:"+s1);
				picToBase64 pic2 = new picToBase64();
				pic2.Base64ToImage(s1, imgPath2);
				
				res = faceCompare.compare_image(imgPath1, imgPath2);
				
				if (res > 0.72){
					System.out.println("人脸匹配");
					shibie_flag = 1;
					break;
				}
			}
		}
		
		response.setContentType("text/json;charset=UTF-8");
        response.setCharacterEncoding("UTF-8");
        PrintWriter out = response.getWriter();
        String str ="{\"success\":"+shibie_flag+",\"res\":"+res +"}";
//        String str ="{\"success\":"+res+"}";
        out.println(str);
        out.flush();
        out.close();
//		response.sendRedirect(contextPath+"/dialect?method=list");
	}
	
	
	//列表查询
		private void list(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
			request.getRequestDispatcher("/dectList2.jsp").forward(request, response);
		}
		
		//form跳转页面
		private void form(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
			request.getRequestDispatcher("/dectList3.jsp").forward(request, response);
		}
	
}

3、运行效果

网站操作流程如下:
第一步:人脸采集(支持上传图片预览)
Java+opencv+mysql实现人脸识别源码(人脸采集入库+人脸识别相似度)_第3张图片
入库成功:
Java+opencv+mysql实现人脸识别源码(人脸采集入库+人脸识别相似度)_第4张图片
开始人脸识别(人脸匹配成功):
Java+opencv+mysql实现人脸识别源码(人脸采集入库+人脸识别相似度)_第5张图片

写在最后:因篇幅有限,不能讲所有代码贴出,如果需要可以加我:3459067873

你可能感兴趣的:(java,opencv,人脸识别,mysql)