目前市场上很火的人脸刷卡,人脸签到,人脸支付等等都得力于人工智能的产物,但是人脸识别到底会不会存在大家所说的用一张照片也能‘蒙混’过关呢,最近有打算对接一个人脸登录系统的打算,所以进行了研究百度AI的人脸识别,开发者直接调用接口就可以实现人脸上传,人脸检测,人脸识别等等,非常方便,下面分享给大家,当做个笔记。
1)首先你需要去百度智能云AI官方申请一个帐号
点此直达
2)登录帐号后左侧导航依次选择,激活人脸识别,并创建应用
3)记住应用的几个关键参数
4)编写代码,创建一个最简单maven工程即可,导入下面依赖
代码语言:javascript复制<dependency>
<groupId>com.baidu.aip</groupId>
<artifactId>java-sdk</artifactId>
<version>4.8.0</version>
</dependency>
5)编写测试类,测试人脸上传,人脸识别,人脸更新等等。详细可参考官方开发者文档
代码语言:javascript复制public class FaceTest {
private AipFace client;
@Before
public void init() {
//1.创建java代码和百度云交互的client对象
//参数1:appid,参数2:apiKey,参数3:secretKey ,自行在百度云AI申请后填写
client = new AipFace("", "", "");
}
/**
* 人脸注册:向百度的人脸库中添加用户人脸照片
*
* @throws Exception
*/
@Test
public void testFaceRegister() throws Exception {
//2.参数设置
HashMap<String, String> options = new HashMap<>();
options.put("quality_control", "NORMAL");//图片质量 NONE LOW NORMAL,HIGH ,更多参数可参考官方文档https://ai.baidu.com/docs#/Face-Java-SDK/top
options.put("liveness_control", "NONE");//活体检测 测试用图片NONE
options.put("action_type", "REPLACE");//操作方式 APPEND 追加 REPLACE 替换
//3.构造图片
String path = "G:\IdeaProjects\basic_code\face-test\facetestimg\test1.jpg";
//上传的图片 两种格式 : url地址,Base64字符串形式
byte[] bytes = Files.readAllBytes(Paths.get(path));
String encode = Base64Util.encode(bytes);
//4.调用api方法完成人脸注册
/**
* 参数一:(图片的url或者图片的Base64字符串),
* 参数二:图片形式(URL,BASE64)
* 参数三:组ID(固定字符串) 实际业务中可以用于区分不同的分类
* 参数四:用户ID 实际业务中一般存储用户的userid
* 参数五:hashMap中的基本参数配置
*/
JSONObject res = client.addUser(encode, "BASE64", "testgroup1", "100001", options);
System.out.println(res.toString());
}
/**
* 人脸更新:更新人脸库中的照片
*/
@Test
public void testFaceUpdate() throws Exception {
//2.参数设置
HashMap<String, String> options = new HashMap<>();
options.put("quality_control", "NORMAL");//图片质量 NONE LOW NORMAL,HIGH
options.put("liveness_control", "NONE");//活体检测
options.put("action_type", "REPLACE");
//3.构造图片
String path = "G:\IdeaProjects\basic_code\face-test\facetestimg\test2.jpg";
//上传的图片 两种格式 : url地址,Base64字符串形式
byte[] bytes = Files.readAllBytes(Paths.get(path));
String encode = Base64Util.encode(bytes);
//4.调用api方法完成人脸注册
/**
* 参数一:(图片的url或者图片的Base64字符串),
* 参数二:图片形式(URL,BASE64)
* 参数三:组ID(固定字符串)
* 参数四:用户ID
* 参数五:hashMap中的基本参数配置
*/
JSONObject res = client.updateUser(encode, "BASE64", "testgroup1", "100001", options);
System.out.println(res.toString());
}
/**
* 人脸检测:判断图片中是否具有面部信息
*/
@Test
public void testFaceCheck() throws Exception {
//构造图片
String path = "G:\IdeaProjects\basic_code\face-test\facetestimg\test3.jpg";
//上传的图片 两种格式 : url地址,Base64字符串形式
byte[] bytes = Files.readAllBytes(Paths.get(path));
String image = Base64Util.encode(bytes);
//调用api方法进行人脸检测
//参数一:(图片的url或者图片的Base64字符串),
//参数二:图片形式(URL,BASE64)
//参数三:hashMap中的基本参数配置(null:使用默认配置)
JSONObject res = client.detect(image, "BASE64", null);
System.out.println(res.toString(2));
}
/**
* 人脸搜索:根据用户上传的图片和指定人脸库中的所有人脸进行比较,
* 获取相似度最高的一个或者某几个的评分
*
* 说明:返回值(数据,只需要第一条,相似度最高的数据)
* score:相似度评分(80分以上可以认为是同一个人)
*/
@Test
public void testFaceSearch() throws Exception {
//构造图片
String path = "G:\IdeaProjects\basic_code\face-test\facetestimg\test1.jpg";
byte[] bytes = Files.readAllBytes(Paths.get(path));
String image = Base64Util.encode(bytes);
//人脸搜索
JSONObject res = client.search(image, "BASE64", "testgroup1", null);
System.out.println(res.toString(2));
}
}
6)最后整理成工具类,以及常用的人脸登录生成二维码工具类
百度人工智能AI人脸工具类BaiduAiUtil:
代码语言:javascript复制@Component
public class BaiduAiUtil {
@Value("${ai.appId}")
private String APP_ID;
@Value("${ai.apiKey}")
private String API_KEY;
@Value("${ai.secretKey}")
private String SECRET_KEY;
@Value("${ai.imageType}")
private String IMAGE_TYPE;
@Value("${ai.groupId}")
private String groupId;
private AipFace client;
private HashMap<String, String> options = new HashMap<String, String>();
public BaiduAiUtil() {
options.put("quality_control", "NORMAL"); //更多参数可自行添加
options.put("liveness_control", "LOW");
}
@PostConstruct
public void init() {
client = new AipFace(APP_ID, API_KEY, SECRET_KEY);
}
/**
* 人脸注册 :将用户照片存入人脸库中
*/
public Boolean faceRegister(String userId, String image) {
// 人脸注册
JSONObject res = client.addUser(image, IMAGE_TYPE, groupId, userId, options);
Integer errorCode = res.getInt("error_code");
return errorCode == 0 ? true : false;
}
/**
* 人脸更新 :更新人脸库中的用户照片
*/
public Boolean faceUpdate(String userId, String image) {
// 人脸更新
JSONObject res = client.updateUser(image, IMAGE_TYPE, groupId, userId, options);
Integer errorCode = res.getInt("error_code");
return errorCode == 0 ? true : false;
}
/**
* 人脸检测:判断上传图片中是否具有面部头像
*/
public Boolean faceCheck(String image) {
JSONObject res = client.detect(image, IMAGE_TYPE, options);
if (res.has("error_code") && res.getInt("error_code") == 0) {
JSONObject resultObject = res.getJSONObject("result");
Integer faceNum = resultObject.getInt("face_num");
return faceNum == 1?true:false;
}else{
return false;
}
}
/**
* 人脸查找:查找人脸库中最相似的人脸并返回数据
* 处理:用户的匹配得分(score)大于80分,即可认为是同一个用户
*/
public String faceSearch(String image) {
JSONObject res = client.search(image, IMAGE_TYPE, groupId, options);
if (res.has("error_code") && res.getInt("error_code") == 0) {
JSONObject result = res.getJSONObject("result");
JSONArray userList = result.getJSONArray("user_list");
if (userList.length() > 0) {
JSONObject user = userList.getJSONObject(0);
double score = user.getDouble("score");
if(score > 80) {
return user.getString("user_id");
}
}
}
return null;
}
}
二维码生成工具类QRCodeUtil:
代码语言:javascript复制@Component
public class QRCodeUtil {
/**
* 生成Base64 二维码
*/
public String crateQRCode(String content) throws IOException {
System.out.println(content);
ByteArrayOutputStream os = new ByteArrayOutputStream();
try {
QRCodeWriter writer = new QRCodeWriter();
BitMatrix bitMatrix = writer.encode(content, BarcodeFormat.QR_CODE, 200, 200);
BufferedImage bufferedImage = MatrixToImageWriter.toBufferedImage(bitMatrix);
ImageIO.write(bufferedImage, "png", os);
//添加图片标识
return new String("data:image/png;base64," Base64.encode(os.toByteArray()));
} catch (Exception e) {
e.printStackTrace();
} finally {
os.close();
}
return null;
}
}
7)使用方法 这里采用SpringBoot对接人脸识别一套:
- 引入坐标
<!-- 百度云AI-->
<dependency>
<groupId>com.baidu.aip</groupId>
<artifactId>java-sdk</artifactId>
<version>4.8.0</version>
</dependency>
<!-- 谷歌二维码生成-->
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>core</artifactId>
<version>3.2.1</version>
</dependency>
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>javase</artifactId>
<version>3.2.1</version>
</dependency>
- 配置文件添加
ai:
appId: ?
apiKey: ?
secretKey: ?
imageType: BASE64
groupId: lcryface
8)实现人脸登录,人脸签到实现流程 互联网web端项目:用户 --> 二维码展示 --> 扫描二维码 --> 跳转落地页(手机相机或者笔记本摄像头)--> 人脸识别 --> 调用百度AI验证 --> 登录成功
实体项目:用户 --> 是否需要提交额外信息(金额等) --> 硬件摄像头采集人脸信息 --> 人脸识别 --> 调用百度AI验证 --> 成功
总结:
最后总结一句,用照片来‘敷衍’系统人脸识别是不可行的,除非没有进行活体检测,所以我在测试中都是将活体检测不检测,才能通过上传多个照片进行对比,并且在对比评分中,必须满足人脸对比评分score分数足够高,基本上无法伪造,当然,我也问过做这方面的人士,目前对双胞胎还有待提高,其实还是比较安全的,人脸签到这些不涉及金钱方面的可以采取,支付方面的可以暂时不考虑开启,因人而异