Java 使用百度 AI 人工智能人脸识别,一探究竟人脸识别真的容易被破解吗?

2022-11-29 19:12:32 浏览数 (2)

目前市场上很火的人脸刷卡,人脸签到,人脸支付等等都得力于人工智能的产物,但是人脸识别到底会不会存在大家所说的用一张照片也能‘蒙混’过关呢,最近有打算对接一个人脸登录系统的打算,所以进行了研究百度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对接人脸识别一套:

  • 引入坐标
代码语言:javascript复制
<!--        百度云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>
  • 配置文件添加
代码语言:javascript复制
ai:
  appId: ?
  apiKey: ?
  secretKey: ?
  imageType: BASE64
  groupId: lcryface

8)实现人脸登录,人脸签到实现流程 互联网web端项目:用户 --> 二维码展示 --> 扫描二维码 --> 跳转落地页(手机相机或者笔记本摄像头)--> 人脸识别 --> 调用百度AI验证 --> 登录成功

实体项目:用户 --> 是否需要提交额外信息(金额等) --> 硬件摄像头采集人脸信息 --> 人脸识别 --> 调用百度AI验证 --> 成功

总结:

最后总结一句,用照片来‘敷衍’系统人脸识别是不可行的,除非没有进行活体检测,所以我在测试中都是将活体检测不检测,才能通过上传多个照片进行对比,并且在对比评分中,必须满足人脸对比评分score分数足够高,基本上无法伪造,当然,我也问过做这方面的人士,目前对双胞胎还有待提高,其实还是比较安全的,人脸签到这些不涉及金钱方面的可以采取,支付方面的可以暂时不考虑开启,因人而异

0 人点赞