主类
package work;
import org.opencv.core.Core;
import org.opencv.videoio.VideoCapture;
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 java.io.IOException;
@WebServlet("/demo")
public class Main extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
VideoCapture vc = new VideoCapture(0);
System.out.println(vc);
if(CaptureBasic.showVido(vc)){
resp.sendRedirect("/liu_war_exploded/home.html");
}else {
resp.sendRedirect("/liu_war_exploded/login.html");
}
}
}
人脸识别
package work;
import org.opencv.core.Point;
import org.opencv.core.*;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
import org.opencv.objdetect.CascadeClassifier;
import org.opencv.videoio.VideoCapture;
import org.opencv.videoio.Videoio;
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
public class CaptureBasic extends JPanel {
private BufferedImage mImg;
/**
* 转换图像
*
* @param mat
* @return
*/
private BufferedImage mat2BI(Mat mat) {
int dataSize = mat.cols() * mat.rows() * (int) mat.elemSize();
byte[] data = new byte[dataSize];
mat.get(0, 0, data);
int type = mat.channels() == 1 ?
BufferedImage.TYPE_BYTE_GRAY : BufferedImage.TYPE_3BYTE_BGR;
if (type == BufferedImage.TYPE_3BYTE_BGR) {
for (int i = 0; i < dataSize; i += 3) {
byte blue = data[i + 0];
data[i + 0] = data[i + 2];
data[i + 2] = blue;
}
}
BufferedImage image = new BufferedImage(mat.cols(), mat.rows(), type);
image.getRaster().setDataElements(0, 0, mat.cols(), mat.rows(), data);
return image;
}
public void paintComponent(Graphics g) {
if (mImg != null) {
g.drawImage(mImg, 0, 0, mImg.getWidth(), mImg.getHeight(), this);
}
}
/**
* 显示视频
*/
public static boolean showVido(VideoCapture capture) {
try {
// 创建矩阵
Mat capImg = new Mat();
// 设置摄像头高度
int height = (int) capture.get(Videoio.CAP_PROP_FRAME_HEIGHT);
// 设置摄像头宽度
int width = (int) capture.get(Videoio.CAP_PROP_FRAME_WIDTH);
if (height == 0 || width == 0) {
throw new Exception("camera not found!");
}
//使用Swing生成GUI
JFrame frame = new JFrame("人脸识别");
frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
CaptureBasic panel = new CaptureBasic();
//设置中心显示
frame.setContentPane(panel);
frame.setVisible(true);
frame.setSize(width + frame.getInsets().left + frame.getInsets().right,
height + frame.getInsets().top + frame.getInsets().bottom);
frame.setLocationRelativeTo(null);
int n = 0;
// 创建一个临时矩阵
Mat temp = new Mat();
while (frame.isShowing() && n < 100000) {
//从摄像头读取一帧数据,保存到capImg矩阵中。
capture.read(capImg);
//转换为彩色图
Imgproc.cvtColor(capImg, temp, Imgproc.COLOR_RGBA2BGRA);
//调用人脸识别
capImg = detectFace(capImg);
//转为图像显示
panel.mImg = panel.mat2BI(capImg);
Imgcodecs.imwrite("D:\\renlian\\1.jpg",capImg);
panel.repaint();
String result = FaceMatch.match();
if(result.equals("1")){
capture.release();
frame.dispose();
return true;
}
}
capture.release();
frame.dispose();
} catch (Exception e) {
System.out.println("例外:" + e);
} finally {
System.out.println("--done--");
}
return false;
}
/**
* opencv实现人脸识别
*
* @param img
*/
public static Mat detectFace(Mat img) throws Exception {
System.out.println("Running DetectFace ... ");
// 从配置文件lbpcascade_frontalface.xml中创建一个人脸识别器,该文件位于opencv安装目录中
CascadeClassifier faceDetector = new CascadeClassifier("D:\\opencv\\opencv\\sources\\data\\haarcascades\\haarcascade_frontalface_alt.xml");
// 在图片中检测人脸
MatOfRect faceDetections = new MatOfRect();
faceDetector.detectMultiScale(img, faceDetections);
Rect[] rects = faceDetections.toArray();
if (rects != null && rects.length >= 1) {
for (Rect rect : rects) {
//画矩形
Imgproc.rectangle(img, new Point(rect.x, rect.y), new Point(rect.x + rect.width, rect.y + rect.height),
new Scalar(0, 255, 0), 2);
}
}
return img;
}
}
获取百度token
package work;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.List;
import java.util.Map;
public class AuthServiceAuthService {
/**
* 获取权限token
* @return 返回示例:
* {
* "access_token": "24.460da4889caad24cccdb1fea17221975.2592000.1491995545.282335-1234567",
* "expires_in": 2592000
* }
*/
public static String getAuth() {
// 官网获取的 API Key 更新为你注册的
String clientId = "百度云官网获取的 API Key";
// 官网获取的 Secret Key 更新为你注册的
String clientSecret = "百度云官网获取的 Securet Key";
return getAuth(clientId, clientSecret);
}
/**
* 获取API访问token
* 该token有一定的有效期,需要自行管理,当失效时需重新获取.
* @param ak - 百度云官网获取的 API Key
* @param sk - 百度云官网获取的 Securet Key
* @return assess_token 示例:
* "24.460da4889caad24cccdb1fea17221975.2592000.1491995545.282335-1234567"
*/
public static String getAuth(String ak, String sk) {
// 获取token地址
String authHost = "https://aip.baidubce.com/oauth/2.0/token?";
String getAccessTokenUrl = authHost
// 1. grant_type为固定参数
+ "grant_type=client_credentials"
// 2. 官网获取的 API Key
+ "&client_id=" + ak
// 3. 官网获取的 Secret Key
+ "&client_secret=" + sk;
try {
URL realUrl = new URL(getAccessTokenUrl);
// 打开和URL之间的连接
HttpURLConnection connection = (HttpURLConnection) realUrl.openConnection();
connection.setRequestMethod("GET");
connection.connect();
// 获取所有响应头字段
Map<String, List<String>> map = connection.getHeaderFields();
// 遍历所有的响应头字段
for (String key : map.keySet()) {
System.err.println(key + "--->" + map.get(key));
}
// 定义 BufferedReader输入流来读取URL的响应
BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String result = "";
String line;
while ((line = in.readLine()) != null) {
result += line;
}
/**
* 返回结果示例
*/
System.err.println("result:" + result);
JSONObject jsonObject = new JSONObject(result);
String access_token = jsonObject.getString("access_token");
return access_token;
} catch (Exception e) {
System.err.printf("获取token失败!");
e.printStackTrace(System.err);
}
return null;
}
}
面部比对
package work;
import com.alibaba.fastjson.JSON;
import utils.Base64Util;
import utils.FileUtil;
import utils.GsonUtils;
import utils.HttpUtil;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class FaceMatch {
/**
* 重要提示代码中所需工具类
* FileUtil,Base64Util,HttpUtil,GsonUtils请从
* https://ai.baidu.com/file/658A35ABAB2D404FBF903F64D47C1F72
* https://ai.baidu.com/file/C8D81F3301E24D2892968F09AE1AD6E2
* https://ai.baidu.com/file/544D677F5D4E4F17B4122FBD60DB82B3
* https://ai.baidu.com/file/470B3ACCA3FE43788B5A963BF0B625F3
* 下载
*/
public static String match() {
// 请求url
String url = "https://aip.baidubce.com/rest/2.0/face/v3/match";
try {
byte[] bytes1 = FileUtil.readFileByBytes("D:\\renlian\\1.jpg");
byte[] bytes2 = FileUtil.readFileByBytes("D:\\renlian\\ceshi.jpg");
String image1 = Base64Util.encode(bytes1);
String image2 = Base64Util.encode(bytes2);
List<Map<String, Object>> images = new ArrayList<>();
Map<String, Object> map1 = new HashMap<>();
map1.put("image", image1);
map1.put("image_type", "BASE64");
map1.put("face_type", "LIVE");
map1.put("quality_control", "LOW");
map1.put("liveness_control", "NONE");
Map<String, Object> map2 = new HashMap<>();
map2.put("image", image2);
map2.put("image_type", "BASE64");
map2.put("face_type", "LIVE");
map2.put("quality_control", "LOW");
map2.put("liveness_control", "NONE");
images.add(map1);
images.add(map2);
String param = GsonUtils.toJson(images);
// 注意这里仅为了简化编码每一次请求都去获取access_token,线上环境access_token有过期时间, 客户端可自行缓存,过期后重新获取。
// String accessToken = "【调用鉴权接口获取的token】";
String accessToken = AuthServiceAuthService.getAuth();
String result = HttpUtil.post(url, accessToken, "application/json", param);
System.out.println(result);
return checkIsOnePerson(result);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static String checkIsOnePerson(String result) {
try {
// 1. 将百度接口返回的result 转化成HashMap
HashMap baiduMap = JSON.parseObject(result, HashMap.class);
// 2. 如果从baiduMap中获取不到result则代表失败不是同一人,返回 0
if (baiduMap.get("result") == null) {
return "0";
} else {
// 3. 获取到result
HashMap resultMap = JSON.parseObject(String.valueOf(baiduMap.get("result")), HashMap.class);
// 4. 从result中获取score BigDecimal 类,用于高精度计算
BigDecimal score = (BigDecimal) resultMap.get("score");
// 5. 定义对比分值界限为85,如果score大于界限值lineScore则认为是同一人,否则不是同一人
BigDecimal lineScore = new BigDecimal(85);
// 6. BigDecimal提供的比较方法 ,原理就是 score - lineScore
int flag = score.compareTo(lineScore);
if (flag > 0) {
return "1";//1代表是同一个人
} else {
return "0";//0代表不是同一人
}
}
}catch (Exception e){
}
return "0";//0代表不是同一人
}
}
注意:
- 部署Tomcat
- 导入opencv
- 下载百度提示的工具
- 确认摄像头可用