从零玩转人脸识别验证2

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: 从零玩转人脸识别验证

构建项目工程

image-1652620445459.png

导入项目依赖

<properties>
        <java.version>1.8</java.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <spring-boot.version>2.3.7.RELEASE</spring-boot.version>
        <druid-spring-boot-starter.version>1.2.6</druid-spring-boot-starter.version>
        <mybatis-spring-boot.version>2.1.4</mybatis-spring-boot.version>
        <pagehelper.boot.version>1.3.0</pagehelper.boot.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--  人脸识别  -->
        <dependency>
            <groupId>com.arcsoft.face</groupId>
            <artifactId>arcsoft-sdk-face</artifactId>
            <scope>system</scope>
            <systemPath>${project.basedir}/lib/arcsoft-sdk-face-3.0.0.0.jar</systemPath>
            <version>3.0.0.0</version>
        </dependency>
        <!-- pool 对象池 -->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-pool2</artifactId>
        </dependency>
        <!-- guava -->
        <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>27.0.1-jre</version>
        </dependency>
        <!-- Mysql驱动包 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <!-- mybatis-plus 增强CRUD -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.4.2</version>
        </dependency>
        <!-- pagehelper 分页插件 内置mybatis 依赖-->
        <dependency>
            <groupId>com.github.pagehelper</groupId>
            <artifactId>pagehelper-spring-boot-starter</artifactId>
            <version>${pagehelper.boot.version}</version>
        </dependency>
        <!-- 阿里数据源 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>${druid-spring-boot-starter.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
        <!-- Spring框架基本的核心工具 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
        </dependency>
        <!-- JSON工具类 -->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
        </dependency>
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.8.0</version>
        </dependency>
        <!-- SpringWeb模块 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
        </dependency>
        <!-- servlet包 -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
        </dependency>
        <!-- aop -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
    </dependencies>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${spring-boot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>2.3.7.RELEASE</version>
                <configuration>
                    <mainClass>top.yangbuyi.YangbuyiFaceDemoApplication</mainClass>
                    <!-- 文件要配置includeSystemScope属性,否则可能会导致arcsoft-sdk-face-3.0.0.0.jar获取不到 -->
                    <includeSystemScope>true</includeSystemScope>
                    <fork>true</fork>
                </configuration>
                <executions>
                    <execution>
                        <id>repackage</id>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

使用代码生成器生成CRUD

版本请对应图片当中的jebat全家桶群里获取3秒破解使用

image-1652622813045.pngimage-1652621615948.png

生成完毕后在根目录创建lib目录将下载下来的人脸识别依赖导入->右击添加到库

image-1652621634861.png

application.yml 修改配置文件

# 开发环境配置
server:
  # 服务器的HTTP端口,默认为8080
  port: 8080
  servlet:
    # 应用的访问路径
    context-path: /
  tomcat:
    # tomcat的URI编码
    uri-encoding: UTF-8
    # tomcat最大线程数,默认为200
    max-threads: 800
    # Tomcat启动初始化的线程数,默认值25
    min-spare-threads: 30
# Spring配置
spring:
  # 同时执行其它配置文件
  profiles:
    active: druid
  mvc: # 把前端的接收到的时间格式 格式化为 yyyy-MM-dd HH:mm:ss
    date-format: yyyy-MM-dd HH:mm:ss
  jackson: # 把后台的时间格式 格式化为 yyyy-MM-dd HH:mm:ss
    date-format: yyyy-MM-dd HH:mm:ss
    time-zone: GMT+8
  # 服务模块
  devtools:
    restart:
      # 热部署开关
      enabled: true
# MyBatis配置
mybatis-plus:
  # 搜索指定包别名
  typeAliasesPackage: top.yangbuyi.domain
  # 配置mapper的扫描,找到所有的mapper.xml映射文件
  mapperLocations: classpath*:mapper/*Mapper.xml
  # 加载全局的配置文件
  configLocation: classpath:mybatis/mybatis-config.xml
# PageHelper分页插件
pagehelper:
  helperDialect: mysql
  reasonable: true
  supportMethodsArguments: true
  params: count=countSql
# 人脸识别配置
# WIND64
config:
  sdk-lib-path: M:\yangbuyiya-RBAC\libs\WIN64
  app-id: 4QKtmacvsKqaCsoXyyujcs21JTAr79pTczPdZpuaEjhH
  sdk-key: EgBjrmidnqstaL46msfHukeKanYXCujzeHokf2qcC3br
  thread-pool-size: 5

application-druid.yml 数据源配置

# 数据源配置
spring:
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driverClassName: com.mysql.cj.jdbc.Driver
    druid:
      url: jdbc:mysql://127.0.0.1:3308/face?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
      username: root
      password: 123456
      # 初始连接数
      initialSize: 5
      # 最小连接池数量
      minIdle: 10
      # 最大连接池数量
      maxActive: 20
      # 配置获取连接等待超时的时间
      maxWait: 60000
      # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
      timeBetweenEvictionRunsMillis: 60000
      # 配置一个连接在池中最小生存的时间,单位是毫秒
      minEvictableIdleTimeMillis: 300000
      # 配置一个连接在池中最大生存的时间,单位是毫秒
      maxEvictableIdleTimeMillis: 900000
      # 配置检测连接是否有效
      validationQuery: SELECT 1 FROM DUAL
      testWhileIdle: true
      testOnBorrow: false
      testOnReturn: false
      webStatFilter:
        enabled: true
      statViewServlet:
        enabled: true
        # 设置白名单,不填则允许所有访问
        allow:
        url-pattern: /yangbuyi/druid/*
      filter:
        stat:
          enabled: true
          # 慢SQL记录
          log-slow-sql: true
          slow-sql-millis: 1000
          merge-sql: true
        wall:
          config:
            multi-statement-allow: true

resources 下创建mybatis文件夹创建mybatis-config.xml文件

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <settings>
        <setting name="cacheEnabled" value="true"/>  <!-- 全局映射器启用缓存 -->
        <setting name="useGeneratedKeys" value="true"/>  <!-- 允许 JDBC 支持自动生成主键 -->
        <setting name="defaultExecutorType" value="REUSE"/> <!-- 配置默认的执行器 -->
        <setting name="logImpl" value="SLF4J"/> <!-- 指定 MyBatis 所用日志的具体实现 -->
        <!-- <setting name="mapUnderscoreToCamelCase" value="true"/>  驼峰式命名 -->
    </settings>
</configuration>

项目基础文件配置

创建config文件

创建ApplicationConfig全局配置类

/**
 * 程序注解配置
 *
 * @author yangbuyi
 */
@Configuration
// 表示通过aop框架暴露该代理对象,AopContext能够访问
@EnableAspectJAutoProxy(exposeProxy = true)
// 指定要扫描的Mapper类的包的路径
@MapperScan("top.yangbuyi.mapper")
public class ApplicationConfig {
    /**
     * 时区配置
     */
    @Bean
    public Jackson2ObjectMapperBuilderCustomizer jacksonObjectMapperCustomization () {
        return jacksonObjectMapperBuilder -> jacksonObjectMapperBuilder.timeZone(TimeZone.getDefault());
    }
    /**
     * 处理Long类型精度丢失
     *
     * @return
     */
    @Bean("jackson2ObjectMapperBuilderCustomizer")
    public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer () {
        return jacksonObjectMapperBuilder -> jacksonObjectMapperBuilder.serializerByType(Long.class, ToStringSerializer.instance)
                .serializerByType(Long.TYPE, ToStringSerializer.instance);
    }
}

创建全局MybatisPlusConfig配置

/**
 * @program: yangbuyi-rbac
 * @ClassName: MybatisPlusConfig
 * @create: 2022-04-25 15:48
 * @author: yby6.com
 * @since: JDK1.8
 * @MybatisPlusConfig: $
 **/
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.BlockAttackInnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.annotation.EnableTransactionManagement;
@EnableTransactionManagement(proxyTargetClass = true)
@Configuration
public class MybatisPlusConfig {
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor () {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        // 分页插件
        interceptor.addInnerInterceptor(paginationInnerInterceptor());
        // 乐观锁插件
        interceptor.addInnerInterceptor(optimisticLockerInnerInterceptor());
        // 阻断插件
        interceptor.addInnerInterceptor(blockAttackInnerInterceptor());
        return interceptor;
    }
    /**
     * 分页插件,自动识别数据库类型 https://baomidou.com/guide/interceptor-pagination.html
     */
    public PaginationInnerInterceptor paginationInnerInterceptor () {
        PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor();
        // 设置数据库类型为mysql
        paginationInnerInterceptor.setDbType(DbType.MYSQL);
        // 设置最大单页限制数量,默认 500 条,-1 不受限制
        paginationInnerInterceptor.setMaxLimit(-1L);
        return paginationInnerInterceptor;
    }
    /**
     * 乐观锁插件 https://baomidou.com/guide/interceptor-optimistic-locker.html
     */
    public OptimisticLockerInnerInterceptor optimisticLockerInnerInterceptor () {
        return new OptimisticLockerInnerInterceptor();
    }
    /**
     * 如果是对全表的删除或更新操作,就会终止该操作 https://baomidou.com/guide/interceptor-block-attack.html
     */
    public BlockAttackInnerInterceptor blockAttackInnerInterceptor () {
        return new BlockAttackInnerInterceptor();
    }
}

创建dto文件夹

创建人脸返回实体 FaceSearchResDto

/**
 * @author yby6.com
 */
@Data
public class FaceSearchResDto {
    /**
     * 唯一人脸Id
     */
    private String faceId;
    /**
     * 人脸名称
     */
    private String name;
    private Integer similarValue;
    /**
     * 年龄
     */
    private Integer age;
    /**
     * 性别
     */
    private String gender;
    /**
     * 图片
     */
    private String image;
}

创建人脸映射 FaceUserInfo

/**
 * @author yby6.com
 */
@Data
public class FaceUserInfo {
    private int id;
    private int groupId;
    private String faceId;
    private String name;
    private Integer similarValue;
    private byte[] faceFeature;
}

创建年龄映射

/**
 * @author yby6.com
 */
public class ProcessInfo {
    private Integer age;
    private Integer gender;
    public Integer getAge () {
        return age;
    }
    public void setAge (Integer age) {
        this.age = age;
    }
    public Integer getGender () {
        return gender;
    }
    public void setGender (Integer gender) {
        this.gender = gender;
    }
}

创建enums文件夹

创建ErrorCodeEnum枚举类

/**
 * @author yby6.com
 */
public enum ErrorCodeEnum {
    MOK(0, "成功"),
    UNKNOWN(1, "未知错误"),
    INVALID_PARAM(2, "无效参数"),
    UNSUPPORTED(3, "引擎不支持"),
    NO_MEMORY(4, "内存不足"),
    BAD_STATE(5, "状态错误"),
    USER_CANCEL(6, "用户取消相关操作"),
    EXPIRED(7, "操作时间过期"),
    USER_PAUSE(8, "用户暂停操作"),
    BUFFER_OVERFLOW(9, "缓冲上溢"),
    BUFFER_UNDERFLOW(10, "缓冲下溢"),
    NO_DISKSPACE(11, "存贮空间不足"),
    COMPONENT_NOT_EXIST(12, "组件不存在"),
    GLOBAL_DATA_NOT_EXIST(13, "全局数据不存在"),
    NO_FACE_DETECTED(14, "未检出到人脸"),
    FACE_DOES_NOT_MATCH(15, "人脸不匹配"),
    INVALID_APP_ID(28673, "无效的AppId"),
    INVALID_SDK_ID(28674, "无效的SdkKey"),
    INVALID_ID_PAIR(28675, "AppId和SdkKey不匹配"),
    MISMATCH_ID_AND_SDK(28676, "SdkKey 和使用的SDK 不匹配"),
    SYSTEM_VERSION_UNSUPPORTED(28677, "系统版本不被当前SDK所支持"),
    LICENCE_EXPIRED(28678, "SDK有效期过期,需要重新下载更新"),
    APS_ENGINE_HANDLE(69633, "引擎句柄非法"),
    APS_MEMMGR_HANDLE(69634, "内存句柄非法"),
    APS_DEVICEID_INVALID(69635, " Device ID 非法"),
    APS_DEVICEID_UNSUPPORTED(69636, "Device ID 不支持"),
    APS_MODEL_HANDLE(69637, "模板数据指针非法"),
    APS_MODEL_SIZE(69638, "模板数据长度非法"),
    APS_IMAGE_HANDLE(69639, "图像结构体指针非法"),
    APS_IMAGE_FORMAT_UNSUPPORTED(69640, "图像格式不支持"),
    APS_IMAGE_PARAM(69641, "图像参数非法"),
    APS_IMAGE_SIZE(69642, "图像尺寸大小超过支持范围"),
    APS_DEVICE_AVX2_UNSUPPORTED(69643, "处理器不支持AVX2指令"),
    FR_INVALID_MEMORY_INFO(73729, "无效的输入内存"),
    FR_INVALID_IMAGE_INFO(73730, "无效的输入图像参数"),
    FR_INVALID_FACE_INFO(73731, "无效的脸部信息"),
    FR_NO_GPU_AVAILABLE(73732, "当前设备无GPU可用"),
    FR_MISMATCHED_FEATURE_LEVEL(73733, "待比较的两个人脸特征的版本不一致"),
    FACEFEATURE_UNKNOWN(81921, "人脸特征检测错误未知"),
    FACEFEATURE_MEMORY(81922, "人脸特征检测内存错误"),
    FACEFEATURE_INVALID_FORMAT(81923, "人脸特征检测格式错误"),
    FACEFEATURE_INVALID_PARAM(81924, "人脸特征检测参数错误"),
    FACEFEATURE_LOW_CONFIDENCE_LEVEL(81925, "人脸特征检测结果置信度低"),
    ASF_EX_BASE_FEATURE_UNSUPPORTED_ON_INIT(86017, "Engine不支持的检测属性"),
    ASF_EX_BASE_FEATURE_UNINITED(86018, "需要检测的属性未初始化"),
    ASF_EX_BASE_FEATURE_UNPROCESSED(86019, "待获取的属性未在process中处理过"),
    ASF_EX_BASE_FEATURE_UNSUPPORTED_ON_PROCESS(86020, "PROCESS不支持的检测属性,例如FR,有自己独立的处理函数"),
    ASF_EX_BASE_INVALID_IMAGE_INFO(86021, "无效的输入图像"),
    ASF_EX_BASE_INVALID_FACE_INFO(86022, "无效的脸部信息"),
    ASF_BASE_ACTIVATION_FAIL(90113, "人脸比对SDK激活失败,请打开读写权限"),
    ASF_BASE_ALREADY_ACTIVATED(90114, "人脸比对SDK已激活"),
    ASF_BASE_NOT_ACTIVATED(90115, "人脸比对SDK未激活"),
    ASF_BASE_SCALE_NOT_SUPPORT(90116, "detectFaceScaleVal 不支持"),
    ASF_BASE_VERION_MISMATCH(90117, "SDK版本不匹配"),
    ASF_BASE_DEVICE_MISMATCH(90118, "设备不匹配"),
    ASF_BASE_UNIQUE_IDENTIFIER_MISMATCH(90119, "唯一标识不匹配"),
    ASF_BASE_PARAM_NULL(90120, "参数为空"),
    ASF_BASE_SDK_EXPIRED(90121, "SDK已过期"),
    ASF_BASE_VERSION_NOT_SUPPORT(90122, "版本不支持"),
    ASF_BASE_SIGN_ERROR(90123, "签名错误"),
    ASF_BASE_DATABASE_ERROR(90124, "数据库插入错误"),
    ASF_BASE_UNIQUE_CHECKOUT_FAIL(90125, "唯一标识符校验失败"),
    ASF_BASE_COLOR_SPACE_NOT_SUPPORT(90126, "输入的颜色空间不支持"),
    ASF_BASE_IMAGE_WIDTH_NOT_SUPPORT(90127, "输入图像的byte数据长度不正确"),
    ASF_NETWORK_BASE_COULDNT_RESOLVE_HOST(94209, "无法解析主机地址"),
    ASF_NETWORK_BASE_COULDNT_CONNECT_SERVER(94210, "无法连接服务器"),
    ASF_NETWORK_BASE_CONNECT_TIMEOUT(94211, "网络连接超时"),
    ASF_NETWORK_BASE_UNKNOWN_ERROR(94212, "未知错误");
    private Integer code;
    private String description;
    ErrorCodeEnum (Integer code, String description) {
        this.code = code;
        this.description = description;
    }
    public Integer getCode () {
        return code;
    }
    public void setCode (Integer code) {
        this.code = code;
    }
    public String getDescription () {
        return description;
    }
    public void setDescription (String description) {
        this.description = description;
    }
    public static ErrorCodeEnum getDescriptionByCode (Integer code) {
        for (ErrorCodeEnum errorCodeEnum : ErrorCodeEnum.values()) {
            if (code.equals(errorCodeEnum.getCode())) {
                return errorCodeEnum;
            }
        }
        return ErrorCodeEnum.UNKNOWN;
    }
}

创建utils文件夹

创建Base64DecodeMultipartFile

package top.yangbuyi.utils;
import org.springframework.web.multipart.MultipartFile;
import java.io.*;
/**
 * @author yby6.com
 * @program: yangbuyi-rbac
 * @ClassName: Base64DecodeMultipartFile
 * @create: 2022-04-25 16:25
 * @since: JDK1.8
 * @Base64DecodeMultipartFile: $
 **/
public class Base64DecodeMultipartFile implements MultipartFile {
    private final byte[] imgContent;
    private final String header;
    public Base64DecodeMultipartFile (byte[] imgContent, String header) {
        this.imgContent = imgContent;
        this.header = header.split(";")[0];
    }
    @Override
    public String getName () {
        return System.currentTimeMillis() + Math.random() + "." + header.split("/")[1];
    }
    @Override
    public String getOriginalFilename () {
        return System.currentTimeMillis() + (int) Math.random() * 10000 + "." + header.split("/")[1];
    }
    @Override
    public String getContentType () {
        return header.split(":")[1];
    }
    @Override
    public boolean isEmpty () {
        return imgContent == null || imgContent.length == 0;
    }
    @Override
    public long getSize () {
        return imgContent.length;
    }
    @Override
    public byte[] getBytes () throws IOException {
        return imgContent;
    }
    @Override
    public InputStream getInputStream () throws IOException {
        return new ByteArrayInputStream(imgContent);
    }
    @Override
    public void transferTo (File dest) throws IOException, IllegalStateException {
        new FileOutputStream(dest).write(imgContent);
    }
}

创建ImageUtils

package top.yangbuyi.utils;
import org.apache.tomcat.util.codec.binary.Base64;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.multipart.MultipartFile;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import java.util.Arrays;
/**
 * 图片处理工具类
 *
 * @author yby6.com
 */
public class ImageUtils {
    private static final Logger log = LoggerFactory.getLogger(ImageUtils.class);
    public static MultipartFile base64ToMultipartFile (String base64) {
        //base64编码后的图片有头信息所以要分离出来 [0]data:image/png;base64, 图片内容为索引[1]
        String[] baseStrs = base64.split(",");
        //取索引为1的元素进行处理
        byte[] b = Base64.decodeBase64(baseStrs[1]);
        for (int i = 0; i < b.length; ++i) {
            if (b[i] < 0) {
                b[i] += 256;
            }
        }
        //处理过后的数据通过Base64DecodeMultipartFile转换为MultipartFile对象
        return new Base64DecodeMultipartFile(b, baseStrs[0]);
    }
}

项目基本需要的配置与工具已经创建完毕接下来我们开始人脸识别业务编写

实现BasePooledObjectFactory自定义引擎工厂

创建factory文件夹->创建FaceEngineFactory类

import com.arcsoft.face.EngineConfiguration;
import com.arcsoft.face.FaceEngine;
import com.arcsoft.face.enums.DetectMode;
import com.arcsoft.face.enums.DetectOrient;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.pool2.BasePooledObjectFactory;
import org.apache.commons.pool2.PooledObject;
import org.apache.commons.pool2.impl.DefaultPooledObject;
/**
 * 引擎工厂
 * @author yby6.com
 */
@Slf4j
public class FaceEngineFactory extends BasePooledObjectFactory<FaceEngine> {
    private final String appId;
    private final String sdkKey;
    private final String sdkLibPath;
    private final EngineConfiguration engineConfiguration;
    private final Integer detectFaceMaxNum = 10;
    private final Integer detectFaceScaleVal = 16;
    private final DetectMode detectMode = DetectMode.ASF_DETECT_MODE_IMAGE;
    private final DetectMode detectVideo = DetectMode.ASF_DETECT_MODE_VIDEO;
    private final DetectOrient detectFaceOrientPriority = DetectOrient.ASF_OP_0_ONLY;
    public FaceEngineFactory (String sdkLibPath, String appId, String sdkKey, EngineConfiguration engineConfiguration) {
        this.sdkLibPath = sdkLibPath;
        this.appId = appId;
        this.sdkKey = sdkKey;
        this.engineConfiguration = engineConfiguration;
    }
    @Override
    public FaceEngine create () throws Exception {
        FaceEngine faceEngine = new FaceEngine(sdkLibPath);
        // 用于在线激活SDK---
        int activeCode = faceEngine.activeOnline(appId, sdkKey);
        log.info("在线激活SDK完毕!,{}", activeCode);
        int initCode = faceEngine.init(engineConfiguration);
        log.info("初始化功能引擎完毕!,{}", initCode);
        return faceEngine;
    }
    @Override
    public PooledObject<FaceEngine> wrap (FaceEngine faceEngine) {
        return new DefaultPooledObject<>(faceEngine);
    }
    @Override
    public void destroyObject (PooledObject<FaceEngine> p) throws Exception {
        FaceEngine faceEngine = p.getObject();
        int unInitCode = faceEngine.unInit();
        super.destroyObject(p);
        log.info("销毁对象完毕! faceEngineUnInitCode: {}", unInitCode);
    }
}


相关实践学习
如何快速连接云数据库RDS MySQL
本场景介绍如何通过阿里云数据管理服务DMS快速连接云数据库RDS MySQL,然后进行数据表的CRUD操作。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
7月前
|
Shell Linux 计算机视觉
【Dlib】动作检测:以常见的人脸识别验证为例讲解张嘴与闭眼
【Dlib】动作检测:以常见的人脸识别验证为例讲解张嘴与闭眼
284 0
|
7月前
|
算法 计算机视觉 异构计算
基于肤色模型的人脸识别FPGA实现,包含tb测试文件和MATLAB辅助验证
这是一个关于肤色检测算法的摘要:使用MATLAB 2022a和Vivado 2019.2进行测试和仿真,涉及图像预处理、RGB到YCbCr转换、肤色模型(基于阈值或概率)以及人脸检测。核心程序展示了如何读取图像数据并输入到FPGA处理,通过`tops`模块进行中值滤波、颜色空间转换及人脸检测,最终结果输出到&quot;face.txt&quot;。
|
存储 SQL 前端开发
从零玩转人脸识别验证3
从零玩转人脸识别验证
69 0
从零玩转人脸识别验证3
|
安全 Java 开发工具
从零玩转人脸识别验证1
从零玩转人脸识别验证
115 0
从零玩转人脸识别验证1
|
API 数据库
身份证实名认证接口验证不一致的原因
身份证是每个公民最常用的身份证明,随着当今互联网的快速发展,日常生活中越来越多的场景需要进行身份核验,以身份证实名认证为基础的网络实名制也引起了各行业的关注,随着实名制认证应用情景的多元化,众多网络平台对实名制验证机制的要求也越发严格。
611 0
身份证实名认证接口验证不一致的原因
|
安全
实人认证和活体人脸验证可以用于哪些场景?有什么场景特点?
实人认证和活体人脸验证可以用于哪些场景?有什么场景特点?
380 0
|
新零售 人工智能 大数据
农业全产业链人工智能工程“农业大脑”亮相北京;青岛工商登记实现全程电子化,用人脸识别验证申请人身份
据悉,“农业大脑”以传感器、物联网、云计算、大数据、超级人工智能为技术支撑,通过传感器嵌入到农业生产销售各个环节中,基于RS(遥感)、GIS(地理信息系统)和GPS(全球定位系统)分析土壤和气候等数据,再通过云计算和大数据处理和运算,最终帮助农户作出经济、高效的生产决策。
1926 0
|
7月前
|
机器学习/深度学习 监控 算法
m基于深度学习网络的活体人脸和视频人脸识别系统matlab仿真,带GUI界面
m基于深度学习网络的活体人脸和视频人脸识别系统matlab仿真,带GUI界面
100 0
|
7月前
|
算法 安全 搜索推荐
深入浅出:使用Python实现人脸识别系统
在当今数字化时代,人脸识别技术已成为安全验证、个性化服务等领域的关键技术。本文将引导读者从零开始,逐步探索如何利用Python和开源库OpenCV来构建一个基础的人脸识别系统。本文不仅会详细介绍环境搭建、关键算法理解,还会提供完整的代码示例,帮助读者理解人脸识别的工作原理,并在实际项目中快速应用。通过本文,您将能够掌握人脸识别的基本概念、关键技术和实现方法,为进一步深入学习和研究打下坚实的基础。

热门文章

最新文章