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("人臉不匹配");
        }
    }
}

測試兩張圖片相似度(美女照片自己網上找):
在這裏插入圖片描述
在這裏插入圖片描述
測試結果:相似度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、運行效果

網站操作流程如下:
第一步:人臉採集(支持上傳圖片預覽)
在這裏插入圖片描述
入庫成功:
在這裏插入圖片描述
開始人臉識別(人臉匹配成功):
在這裏插入圖片描述

寫在最後:因篇幅有限,不能講所有代碼貼出,如果需要可以加我:3459067873

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章